Query the device attributes for RDMA operations, including maximum transfer size and maximum number of SGEs per RDMA WR, and report them back to the userspace library.
Unified · Split
| @@ -562,6 +562,16 @@ struct efa_admin_feature_device_attr_desc { · 561 unmodified lines | ||
| 562 | 562 | |
| 563 | 563 | /* Indicates how many bits are used virtual address access */ |
| 564 | 564 | u8 virt_addr_width; |
| 565 | + | |
| 566 | + /* | |
| 567 | + * 0 : rdma_read - If set, RDMA Read is supported on | |
| 568 | + * TX queues | |
| 569 | + * 31:1 : reserved - MBZ | |
| 570 | + */ | |
| 571 | + u32 device_caps; | |
| 572 | + | |
| 573 | + /* Max RDMA transfer size in bytes */ | |
| 574 | + u32 max_rdma_size; | |
| 565 | 575 | }; |
| 566 | 576 | |
| 567 | 577 | struct efa_admin_feature_queue_attr_desc { |
| @@ -608,6 +618,9 @@ struct efa_admin_feature_queue_attr_desc { · 40 unmodified lines | ||
| 608 | 618 | |
| 609 | 619 | /* The maximum size of LLQ in bytes */ |
| 610 | 620 | u32 max_llq_size; |
| 621 | + | |
| 622 | + /* Maximum number of SGEs for a single RDMA read WQE */ | |
| 623 | + u16 max_wr_rdma_sges; | |
| 611 | 624 | }; |
| 612 | 625 | |
| 613 | 626 | struct efa_admin_feature_aenq_desc { |
| @@ -622,6 +635,7 @@ struct efa_admin_feature_network_attr_desc { · 8 unmodified lines | ||
| 622 | 635 | /* Raw address data in network byte order */ |
| 623 | 636 | u8 addr[16]; |
| 624 | 637 | |
| 638 | + /* max packet payload size in bytes */ | |
| 625 | 639 | u32 mtu; |
| 626 | 640 | }; |
| 627 | 641 | |
| @@ -797,4 +811,7 @@ struct efa_admin_mmio_req_read_less_resp { · 169 unmodified lines | ||
| 797 | 811 | /* get_set_feature_common_desc */ |
| 798 | 812 | #define EFA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0) |
| 799 | 813 | |
| 814 | +/* feature_device_attr_desc */ | |
| 815 | +#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RDMA_READ_MASK BIT(0) | |
| 816 | + | |
| 800 | 817 | #endif /* _EFA_ADMIN_CMDS_H_ */ |
| @@ -444,6 +444,8 @@ int efa_com_get_device_attr(struct efa_com_dev *edev, · 443 unmodified lines | ||
| 444 | 444 | result->phys_addr_width = resp.u.device_attr.phys_addr_width; |
| 445 | 445 | result->virt_addr_width = resp.u.device_attr.virt_addr_width; |
| 446 | 446 | result->db_bar = resp.u.device_attr.db_bar; |
| 447 | + result->max_rdma_size = resp.u.device_attr.max_rdma_size; | |
| 448 | + result->device_caps = resp.u.device_attr.device_caps; | |
| 447 | 449 | |
| 448 | 450 | if (result->admin_api_version < 1) { |
| 449 | 451 | ibdev_err_ratelimited( |
| @@ -477,6 +479,7 @@ int efa_com_get_device_attr(struct efa_com_dev *edev, · 27 unmodified lines | ||
| 477 | 479 | result->max_ah = resp.u.queue_attr.max_ah; |
| 478 | 480 | result->max_llq_size = resp.u.queue_attr.max_llq_size; |
| 479 | 481 | result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq; |
| 482 | + result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges; | |
| 480 | 483 | |
| 481 | 484 | err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR); |
| 482 | 485 | if (err) { |
| @@ -121,9 +121,12 @@ struct efa_com_get_device_attr_result { · 120 unmodified lines | ||
| 121 | 121 | u32 max_pd; |
| 122 | 122 | u32 max_ah; |
| 123 | 123 | u32 max_llq_size; |
| 124 | + u32 max_rdma_size; | |
| 125 | + u32 device_caps; | |
| 124 | 126 | u16 sub_cqs_per_cq; |
| 125 | 127 | u16 max_sq_sge; |
| 126 | 128 | u16 max_rq_sge; |
| 129 | + u16 max_wr_rdma_sge; | |
| 127 | 130 | u8 db_bar; |
| 128 | 131 | }; |
| 129 | 132 | |
| @@ -70,9 +70,6 @@ static const char *const efa_stats_names[] = { · 69 unmodified lines | ||
| 70 | 70 | #define EFA_CHUNK_USED_SIZE \ |
| 71 | 71 | ((EFA_PTRS_PER_CHUNK * EFA_CHUNK_PAYLOAD_PTR_SIZE) + EFA_CHUNK_PTR_SIZE) |
| 72 | 72 | |
| 73 | −#define EFA_SUPPORTED_ACCESS_FLAGS \ | |
| 74 | − (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ) | |
| 75 | − | |
| 76 | 73 | struct pbl_chunk { |
| 77 | 74 | dma_addr_t dma_addr; |
| 78 | 75 | u64 *buf; |
| @@ -142,6 +139,11 @@ to_emmap(struct rdma_user_mmap_entry *rdma_entry) · 63 unmodified lines | ||
| 142 | 139 | return container_of(rdma_entry, struct efa_user_mmap_entry, rdma_entry); |
| 143 | 140 | } |
| 144 | 141 | |
| 142 | +static inline bool is_rdma_read_cap(struct efa_dev *dev) | |
| 143 | +{ | |
| 144 | + return dev->dev_attr.device_caps & EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RDMA_READ_MASK; | |
| 145 | +} | |
| 146 | + | |
| 145 | 147 | #define field_avail(x, fld, sz) (offsetof(typeof(x), fld) + \ |
| 146 | 148 | FIELD_SIZEOF(typeof(x), fld) <= (sz)) |
| 147 | 149 | |
| @@ -201,12 +203,17 @@ int efa_query_device(struct ib_device *ibdev, · 53 unmodified lines | ||
| 201 | 203 | dev_attr->max_rq_depth); |
| 202 | 204 | props->max_send_sge = dev_attr->max_sq_sge; |
| 203 | 205 | props->max_recv_sge = dev_attr->max_rq_sge; |
| 206 | + props->max_sge_rd = dev_attr->max_wr_rdma_sge; | |
| 204 | 207 | |
| 205 | 208 | if (udata && udata->outlen) { |
| 206 | 209 | resp.max_sq_sge = dev_attr->max_sq_sge; |
| 207 | 210 | resp.max_rq_sge = dev_attr->max_rq_sge; |
| 208 | 211 | resp.max_sq_wr = dev_attr->max_sq_depth; |
| 209 | 212 | resp.max_rq_wr = dev_attr->max_rq_depth; |
| 213 | + resp.max_rdma_size = dev_attr->max_rdma_size; | |
| 214 | + | |
| 215 | + if (is_rdma_read_cap(dev)) | |
| 216 | + resp.device_caps |= EFA_QUERY_DEVICE_CAPS_RDMA_READ; | |
| 210 | 217 | |
| 211 | 218 | err = ib_copy_to_udata(udata, &resp, |
| 212 | 219 | min(sizeof(resp), udata->outlen)); |
| @@ -1345,6 +1352,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length, · 1132 unmodified lines | ||
| 1345 | 1352 | struct efa_com_reg_mr_params params = {}; |
| 1346 | 1353 | struct efa_com_reg_mr_result result = {}; |
| 1347 | 1354 | struct pbl_context pbl; |
| 1355 | + int supp_access_flags; | |
| 1348 | 1356 | unsigned int pg_sz; |
| 1349 | 1357 | struct efa_mr *mr; |
| 1350 | 1358 | int inline_size; |
| @@ -1358,10 +1366,14 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length, · 7 unmodified lines | ||
| 1358 | 1366 | goto err_out; |
| 1359 | 1367 | } |
| 1360 | 1368 | |
| 1361 | − if (access_flags & ~EFA_SUPPORTED_ACCESS_FLAGS) { | |
| 1369 | + supp_access_flags = | |
| 1370 | + IB_ACCESS_LOCAL_WRITE | | |
| 1371 | + (is_rdma_read_cap(dev) ? IB_ACCESS_REMOTE_READ : 0); | |
| 1372 | + | |
| 1373 | + if (access_flags & ~supp_access_flags) { | |
| 1362 | 1374 | ibdev_dbg(&dev->ibdev, |
| 1363 | 1375 | "Unsupported access flags[%#x], supported[%#x]\n", |
| 1364 | − access_flags, EFA_SUPPORTED_ACCESS_FLAGS); | |
| 1376 | + access_flags, supp_access_flags); | |
| 1365 | 1377 | err = -EOPNOTSUPP; |
| 1366 | 1378 | goto err_out; |
| 1367 | 1379 | } |
| @@ -90,12 +90,18 @@ struct efa_ibv_create_ah_resp { · 89 unmodified lines | ||
| 90 | 90 | __u8 reserved_30[2]; |
| 91 | 91 | }; |
| 92 | 92 | |
| 93 | +enum { | |
| 94 | + EFA_QUERY_DEVICE_CAPS_RDMA_READ = 1 << 0, | |
| 95 | +}; | |
| 96 | + | |
| 93 | 97 | struct efa_ibv_ex_query_device_resp { |
| 94 | 98 | __u32 comp_mask; |
| 95 | 99 | __u32 max_sq_wr; |
| 96 | 100 | __u32 max_rq_wr; |
| 97 | 101 | __u16 max_sq_sge; |
| 98 | 102 | __u16 max_rq_sge; |
| 103 | + __u32 max_rdma_size; | |
| 104 | + __u32 device_caps; | |
| 99 | 105 | }; |
| 100 | 106 | |
| 101 | 107 | #endif /* EFA_ABI_USER_H */ |