Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/efa: Expose RDMA read related attributes

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.

Link: https://lore.kernel.org/r/20191121141509.59297-4-galpress@amazon.com
Signed-off-by: Daniel Kranzdorf <dkkranzd@amazon.com>
Reviewed-by: Yossi Leybovich <sleybo@amazon.com>
Signed-off-by: Gal Pressman <galpress@amazon.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>

authored by

Daniel Kranzdorf and committed by
Jason Gunthorpe
666e8ff5 e6c4f3ff

+46 -5
+17
drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
··· 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 { ··· 618 608 619 609 /* The maximum size of LLQ in bytes */ 620 610 u32 max_llq_size; 611 + 612 + /* Maximum number of SGEs for a single RDMA read WQE */ 613 + u16 max_wr_rdma_sges; 621 614 }; 622 615 623 616 struct efa_admin_feature_aenq_desc { ··· 635 622 /* Raw address data in network byte order */ 636 623 u8 addr[16]; 637 624 625 + /* max packet payload size in bytes */ 638 626 u32 mtu; 639 627 }; 640 628 ··· 810 796 811 797 /* get_set_feature_common_desc */ 812 798 #define EFA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0) 799 + 800 + /* feature_device_attr_desc */ 801 + #define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RDMA_READ_MASK BIT(0) 813 802 814 803 #endif /* _EFA_ADMIN_CMDS_H_ */
+3
drivers/infiniband/hw/efa/efa_com_cmd.c
··· 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( ··· 479 477 result->max_ah = resp.u.queue_attr.max_ah; 480 478 result->max_llq_size = resp.u.queue_attr.max_llq_size; 481 479 result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq; 480 + result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges; 482 481 483 482 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR); 484 483 if (err) {
+3
drivers/infiniband/hw/efa/efa_com_cmd.h
··· 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
+17 -5
drivers/infiniband/hw/efa/efa_verbs.c
··· 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; ··· 139 142 return container_of(rdma_entry, struct efa_user_mmap_entry, rdma_entry); 140 143 } 141 144 145 + static inline bool is_rdma_read_cap(struct efa_dev *dev) 146 + { 147 + return dev->dev_attr.device_caps & EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_RDMA_READ_MASK; 148 + } 149 + 142 150 #define field_avail(x, fld, sz) (offsetof(typeof(x), fld) + \ 143 151 FIELD_SIZEOF(typeof(x), fld) <= (sz)) 144 152 ··· 203 201 dev_attr->max_rq_depth); 204 202 props->max_send_sge = dev_attr->max_sq_sge; 205 203 props->max_recv_sge = dev_attr->max_rq_sge; 204 + props->max_sge_rd = dev_attr->max_wr_rdma_sge; 206 205 207 206 if (udata && udata->outlen) { 208 207 resp.max_sq_sge = dev_attr->max_sq_sge; 209 208 resp.max_rq_sge = dev_attr->max_rq_sge; 210 209 resp.max_sq_wr = dev_attr->max_sq_depth; 211 210 resp.max_rq_wr = dev_attr->max_rq_depth; 211 + resp.max_rdma_size = dev_attr->max_rdma_size; 212 + 213 + if (is_rdma_read_cap(dev)) 214 + resp.device_caps |= EFA_QUERY_DEVICE_CAPS_RDMA_READ; 212 215 213 216 err = ib_copy_to_udata(udata, &resp, 214 217 min(sizeof(resp), udata->outlen)); ··· 1352 1345 struct efa_com_reg_mr_params params = {}; 1353 1346 struct efa_com_reg_mr_result result = {}; 1354 1347 struct pbl_context pbl; 1348 + int supp_access_flags; 1355 1349 unsigned int pg_sz; 1356 1350 struct efa_mr *mr; 1357 1351 int inline_size; ··· 1366 1358 goto err_out; 1367 1359 } 1368 1360 1369 - if (access_flags & ~EFA_SUPPORTED_ACCESS_FLAGS) { 1361 + supp_access_flags = 1362 + IB_ACCESS_LOCAL_WRITE | 1363 + (is_rdma_read_cap(dev) ? IB_ACCESS_REMOTE_READ : 0); 1364 + 1365 + if (access_flags & ~supp_access_flags) { 1370 1366 ibdev_dbg(&dev->ibdev, 1371 1367 "Unsupported access flags[%#x], supported[%#x]\n", 1372 - access_flags, EFA_SUPPORTED_ACCESS_FLAGS); 1368 + access_flags, supp_access_flags); 1373 1369 err = -EOPNOTSUPP; 1374 1370 goto err_out; 1375 1371 }
+6
include/uapi/rdma/efa-abi.h
··· 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 */