aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2018-06-18 11:05:26 -0400
committerJason Gunthorpe <jgg@mellanox.com>2018-06-18 15:17:28 -0400
commit33023fb85a42b53bf778bc025f9667b582282be4 (patch)
tree66d55701f7cc41636dcfc4353e38b4262791b47f
parentb90575ce7b84483d46ebedd5c164e5f274f7ce5a (diff)
IB/core: add max_send_sge and max_recv_sge attributes
This patch replaces the ib_device_attr.max_sge with max_send_sge and max_recv_sge. It allows ulps to take advantage of devices that have very different send and recv sge depths. For example cxgb4 has a max_recv_sge of 4, yet a max_send_sge of 16. Splitting out these attributes allows much more efficient use of the SQ for cxgb4 with ulps that use the RDMA_RW API. Consider a large RDMA WRITE that has 16 scattergather entries. With max_sge of 4, the ulp would send 4 WRITE WRs, but with max_sge of 16, it can be done with 1 WRITE WR. Acked-by: Sagi Grimberg <sagi@grimberg.me> Acked-by: Christoph Hellwig <hch@lst.de> Acked-by: Selvin Xavier <selvin.xavier@broadcom.com> Acked-by: Shiraz Saleem <shiraz.saleem@intel.com> Acked-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c2
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c3
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c3
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_main.c3
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.c3
-rw-r--r--drivers/infiniband/hw/mlx4/main.c4
-rw-r--r--drivers/infiniband/hw/mlx5/main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c5
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c3
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c3
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c3
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c3
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c5
-rw-r--r--drivers/infiniband/sw/rxe/rxe.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_qp.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c2
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c5
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c6
-rw-r--r--drivers/nvme/target/rdma.c2
-rw-r--r--fs/cifs/smbdirect.c13
-rw-r--r--include/rdma/ib_verbs.h3
-rw-r--r--net/rds/ib.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c2
-rw-r--r--net/sunrpc/xprtrdma/verbs.c2
28 files changed, 65 insertions, 39 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 5733d0fb0673..908ee8ab3297 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -189,7 +189,7 @@ static void copy_query_dev_fields(struct ib_uverbs_file *file,
189 resp->max_qp = attr->max_qp; 189 resp->max_qp = attr->max_qp;
190 resp->max_qp_wr = attr->max_qp_wr; 190 resp->max_qp_wr = attr->max_qp_wr;
191 resp->device_cap_flags = lower_32_bits(attr->device_cap_flags); 191 resp->device_cap_flags = lower_32_bits(attr->device_cap_flags);
192 resp->max_sge = attr->max_sge; 192 resp->max_sge = min(attr->max_send_sge, attr->max_recv_sge);
193 resp->max_sge_rd = attr->max_sge_rd; 193 resp->max_sge_rd = attr->max_sge_rd;
194 resp->max_cq = attr->max_cq; 194 resp->max_cq = attr->max_cq;
195 resp->max_cqe = attr->max_cqe; 195 resp->max_cqe = attr->max_cqe;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 136eaa78ad4a..6c0c6d3426e0 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -166,7 +166,8 @@ int bnxt_re_query_device(struct ib_device *ibdev,
166 | IB_DEVICE_MEM_WINDOW 166 | IB_DEVICE_MEM_WINDOW
167 | IB_DEVICE_MEM_WINDOW_TYPE_2B 167 | IB_DEVICE_MEM_WINDOW_TYPE_2B
168 | IB_DEVICE_MEM_MGT_EXTENSIONS; 168 | IB_DEVICE_MEM_MGT_EXTENSIONS;
169 ib_attr->max_sge = dev_attr->max_qp_sges; 169 ib_attr->max_send_sge = dev_attr->max_qp_sges;
170 ib_attr->max_recv_sge = dev_attr->max_qp_sges;
170 ib_attr->max_sge_rd = dev_attr->max_qp_sges; 171 ib_attr->max_sge_rd = dev_attr->max_qp_sges;
171 ib_attr->max_cq = dev_attr->max_cq; 172 ib_attr->max_cq = dev_attr->max_cq;
172 ib_attr->max_cqe = dev_attr->max_cq_wqes; 173 ib_attr->max_cqe = dev_attr->max_cq_wqes;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index be097c6723c0..68bc2f9a532f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1103,7 +1103,8 @@ static int iwch_query_device(struct ib_device *ibdev, struct ib_device_attr *pro
1103 props->max_mr_size = dev->attr.max_mr_size; 1103 props->max_mr_size = dev->attr.max_mr_size;
1104 props->max_qp = dev->attr.max_qps; 1104 props->max_qp = dev->attr.max_qps;
1105 props->max_qp_wr = dev->attr.max_wrs; 1105 props->max_qp_wr = dev->attr.max_wrs;
1106 props->max_sge = dev->attr.max_sge_per_wr; 1106 props->max_send_sge = dev->attr.max_sge_per_wr;
1107 props->max_recv_sge = dev->attr.max_sge_per_wr;
1107 props->max_sge_rd = 1; 1108 props->max_sge_rd = 1;
1108 props->max_qp_rd_atom = dev->attr.max_rdma_reads_per_qp; 1109 props->max_qp_rd_atom = dev->attr.max_rdma_reads_per_qp;
1109 props->max_qp_init_rd_atom = dev->attr.max_rdma_reads_per_qp; 1110 props->max_qp_init_rd_atom = dev->attr.max_rdma_reads_per_qp;
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index 1feade8bb4b3..61b8bdb9423d 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -343,7 +343,8 @@ static int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *pro
343 props->max_mr_size = T4_MAX_MR_SIZE; 343 props->max_mr_size = T4_MAX_MR_SIZE;
344 props->max_qp = dev->rdev.lldi.vr->qp.size / 2; 344 props->max_qp = dev->rdev.lldi.vr->qp.size / 2;
345 props->max_qp_wr = dev->rdev.hw_queue.t4_max_qp_depth; 345 props->max_qp_wr = dev->rdev.hw_queue.t4_max_qp_depth;
346 props->max_sge = T4_MAX_RECV_SGE; 346 props->max_send_sge = min(T4_MAX_SEND_SGE, T4_MAX_WRITE_SGE);
347 props->max_recv_sge = T4_MAX_RECV_SGE;
347 props->max_sge_rd = 1; 348 props->max_sge_rd = 1;
348 props->max_res_rd_atom = dev->rdev.lldi.max_ird_adapter; 349 props->max_res_rd_atom = dev->rdev.lldi.max_ird_adapter;
349 props->max_qp_rd_atom = min(dev->rdev.lldi.max_ordird_qp, 350 props->max_qp_rd_atom = min(dev->rdev.lldi.max_ordird_qp,
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index 08991874c0e2..b7c75b63f887 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -1410,7 +1410,8 @@ static void hfi1_fill_device_attr(struct hfi1_devdata *dd)
1410 rdi->dparms.props.max_fast_reg_page_list_len = UINT_MAX; 1410 rdi->dparms.props.max_fast_reg_page_list_len = UINT_MAX;
1411 rdi->dparms.props.max_qp = hfi1_max_qps; 1411 rdi->dparms.props.max_qp = hfi1_max_qps;
1412 rdi->dparms.props.max_qp_wr = hfi1_max_qp_wrs; 1412 rdi->dparms.props.max_qp_wr = hfi1_max_qp_wrs;
1413 rdi->dparms.props.max_sge = hfi1_max_sges; 1413 rdi->dparms.props.max_send_sge = hfi1_max_sges;
1414 rdi->dparms.props.max_recv_sge = hfi1_max_sges;
1414 rdi->dparms.props.max_sge_rd = hfi1_max_sges; 1415 rdi->dparms.props.max_sge_rd = hfi1_max_sges;
1415 rdi->dparms.props.max_cq = hfi1_max_cqs; 1416 rdi->dparms.props.max_cq = hfi1_max_cqs;
1416 rdi->dparms.props.max_ah = hfi1_max_ahs; 1417 rdi->dparms.props.max_ah = hfi1_max_ahs;
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index 24a2ea0018d9..850032de8676 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -206,7 +206,8 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
206 props->max_qp_wr = hr_dev->caps.max_wqes; 206 props->max_qp_wr = hr_dev->caps.max_wqes;
207 props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT | 207 props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT |
208 IB_DEVICE_RC_RNR_NAK_GEN; 208 IB_DEVICE_RC_RNR_NAK_GEN;
209 props->max_sge = max(hr_dev->caps.max_sq_sg, hr_dev->caps.max_rq_sg); 209 props->max_send_sge = hr_dev->caps.max_sq_sg;
210 props->max_recv_sge = hr_dev->caps.max_rq_sg;
210 props->max_sge_rd = 1; 211 props->max_sge_rd = 1;
211 props->max_cq = hr_dev->caps.num_cqs; 212 props->max_cq = hr_dev->caps.num_cqs;
212 props->max_cqe = hr_dev->caps.max_cqes; 213 props->max_cqe = hr_dev->caps.max_cqes;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
index 68679ad4c6da..8884ff71a634 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
@@ -71,7 +71,8 @@ static int i40iw_query_device(struct ib_device *ibdev,
71 props->max_mr_size = I40IW_MAX_OUTBOUND_MESSAGE_SIZE; 71 props->max_mr_size = I40IW_MAX_OUTBOUND_MESSAGE_SIZE;
72 props->max_qp = iwdev->max_qp - iwdev->used_qps; 72 props->max_qp = iwdev->max_qp - iwdev->used_qps;
73 props->max_qp_wr = I40IW_MAX_QP_WRS; 73 props->max_qp_wr = I40IW_MAX_QP_WRS;
74 props->max_sge = I40IW_MAX_WQ_FRAGMENT_COUNT; 74 props->max_send_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
75 props->max_recv_sge = I40IW_MAX_WQ_FRAGMENT_COUNT;
75 props->max_cq = iwdev->max_cq - iwdev->used_cqs; 76 props->max_cq = iwdev->max_cq - iwdev->used_cqs;
76 props->max_cqe = iwdev->max_cqe; 77 props->max_cqe = iwdev->max_cqe;
77 props->max_mr = iwdev->max_mr - iwdev->used_mrs; 78 props->max_mr = iwdev->max_mr - iwdev->used_mrs;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 908b8e5c5acb..87de1a467d60 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -517,8 +517,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
517 props->page_size_cap = dev->dev->caps.page_size_cap; 517 props->page_size_cap = dev->dev->caps.page_size_cap;
518 props->max_qp = dev->dev->quotas.qp; 518 props->max_qp = dev->dev->quotas.qp;
519 props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; 519 props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
520 props->max_sge = min(dev->dev->caps.max_sq_sg, 520 props->max_send_sge = dev->dev->caps.max_sq_sg;
521 dev->dev->caps.max_rq_sg); 521 props->max_recv_sge = dev->dev->caps.max_rq_sg;
522 props->max_sge_rd = MLX4_MAX_SGE_RD; 522 props->max_sge_rd = MLX4_MAX_SGE_RD;
523 props->max_cq = dev->dev->quotas.cq; 523 props->max_cq = dev->dev->quotas.cq;
524 props->max_cqe = dev->dev->caps.max_cqes; 524 props->max_cqe = dev->dev->caps.max_cqes;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index e6d88f32391b..e46cda740479 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -888,7 +888,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
888 max_sq_sg = (max_sq_desc - sizeof(struct mlx5_wqe_ctrl_seg) - 888 max_sq_sg = (max_sq_desc - sizeof(struct mlx5_wqe_ctrl_seg) -
889 sizeof(struct mlx5_wqe_raddr_seg)) / 889 sizeof(struct mlx5_wqe_raddr_seg)) /
890 sizeof(struct mlx5_wqe_data_seg); 890 sizeof(struct mlx5_wqe_data_seg);
891 props->max_sge = min(max_rq_sg, max_sq_sg); 891 props->max_send_sge = max_sq_sg;
892 props->max_recv_sge = max_rq_sg;
892 props->max_sge_rd = MLX5_MAX_SGE_RD; 893 props->max_sge_rd = MLX5_MAX_SGE_RD;
893 props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); 894 props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq);
894 props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1; 895 props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 541f237965c7..20febafc1fdd 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -96,8 +96,9 @@ static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *pr
96 props->page_size_cap = mdev->limits.page_size_cap; 96 props->page_size_cap = mdev->limits.page_size_cap;
97 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; 97 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
98 props->max_qp_wr = mdev->limits.max_wqes; 98 props->max_qp_wr = mdev->limits.max_wqes;
99 props->max_sge = mdev->limits.max_sg; 99 props->max_send_sge = mdev->limits.max_sg;
100 props->max_sge_rd = props->max_sge; 100 props->max_recv_sge = mdev->limits.max_sg;
101 props->max_sge_rd = mdev->limits.max_sg;
101 props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs; 102 props->max_cq = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
102 props->max_cqe = mdev->limits.max_cqes; 103 props->max_cqe = mdev->limits.max_cqes;
103 props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws; 104 props->max_mr = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 32f26556c808..82b8f9630ee8 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -436,7 +436,8 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop
436 props->max_mr_size = 0x80000000; 436 props->max_mr_size = 0x80000000;
437 props->max_qp = nesibdev->max_qp; 437 props->max_qp = nesibdev->max_qp;
438 props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2; 438 props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2;
439 props->max_sge = nesdev->nesadapter->max_sge; 439 props->max_send_sge = nesdev->nesadapter->max_sge;
440 props->max_recv_sge = nesdev->nesadapter->max_sge;
440 props->max_cq = nesibdev->max_cq; 441 props->max_cq = nesibdev->max_cq;
441 props->max_cqe = nesdev->nesadapter->max_cqe; 442 props->max_cqe = nesdev->nesadapter->max_cqe;
442 props->max_mr = nesibdev->max_mr; 443 props->max_mr = nesibdev->max_mr;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index 82e20fc32890..1f057fdb3a8c 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -89,7 +89,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr,
89 IB_DEVICE_SYS_IMAGE_GUID | 89 IB_DEVICE_SYS_IMAGE_GUID |
90 IB_DEVICE_LOCAL_DMA_LKEY | 90 IB_DEVICE_LOCAL_DMA_LKEY |
91 IB_DEVICE_MEM_MGT_EXTENSIONS; 91 IB_DEVICE_MEM_MGT_EXTENSIONS;
92 attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_recv_sge); 92 attr->max_send_sge = dev->attr.max_send_sge;
93 attr->max_recv_sge = dev->attr.max_recv_sge;
93 attr->max_sge_rd = dev->attr.max_rdma_sge; 94 attr->max_sge_rd = dev->attr.max_rdma_sge;
94 attr->max_cq = dev->attr.max_cq; 95 attr->max_cq = dev->attr.max_cq;
95 attr->max_cqe = dev->attr.max_cqe; 96 attr->max_cqe = dev->attr.max_cqe;
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 10d8f4134ec0..0c41d54f586b 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -112,7 +112,8 @@ int qedr_query_device(struct ib_device *ibdev,
112 IB_DEVICE_RC_RNR_NAK_GEN | 112 IB_DEVICE_RC_RNR_NAK_GEN |
113 IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_MGT_EXTENSIONS; 113 IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_MGT_EXTENSIONS;
114 114
115 attr->max_sge = qattr->max_sge; 115 attr->max_send_sge = qattr->max_sge;
116 attr->max_recv_sge = qattr->max_sge;
116 attr->max_sge_rd = qattr->max_sge; 117 attr->max_sge_rd = qattr->max_sge;
117 attr->max_cq = qattr->max_cq; 118 attr->max_cq = qattr->max_cq;
118 attr->max_cqe = qattr->max_cqe; 119 attr->max_cqe = qattr->max_cqe;
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index 14b4057a2b8f..41babbc0db58 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -1489,7 +1489,8 @@ static void qib_fill_device_attr(struct qib_devdata *dd)
1489 rdi->dparms.props.max_mr_size = ~0ULL; 1489 rdi->dparms.props.max_mr_size = ~0ULL;
1490 rdi->dparms.props.max_qp = ib_qib_max_qps; 1490 rdi->dparms.props.max_qp = ib_qib_max_qps;
1491 rdi->dparms.props.max_qp_wr = ib_qib_max_qp_wrs; 1491 rdi->dparms.props.max_qp_wr = ib_qib_max_qp_wrs;
1492 rdi->dparms.props.max_sge = ib_qib_max_sges; 1492 rdi->dparms.props.max_send_sge = ib_qib_max_sges;
1493 rdi->dparms.props.max_recv_sge = ib_qib_max_sges;
1493 rdi->dparms.props.max_sge_rd = ib_qib_max_sges; 1494 rdi->dparms.props.max_sge_rd = ib_qib_max_sges;
1494 rdi->dparms.props.max_cq = ib_qib_max_cqs; 1495 rdi->dparms.props.max_cq = ib_qib_max_cqs;
1495 rdi->dparms.props.max_cqe = ib_qib_max_cqes; 1496 rdi->dparms.props.max_cqe = ib_qib_max_cqes;
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
index a51463cd2f37..816cc285daf6 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
@@ -82,7 +82,8 @@ int pvrdma_query_device(struct ib_device *ibdev,
82 props->max_qp = dev->dsr->caps.max_qp; 82 props->max_qp = dev->dsr->caps.max_qp;
83 props->max_qp_wr = dev->dsr->caps.max_qp_wr; 83 props->max_qp_wr = dev->dsr->caps.max_qp_wr;
84 props->device_cap_flags = dev->dsr->caps.device_cap_flags; 84 props->device_cap_flags = dev->dsr->caps.device_cap_flags;
85 props->max_sge = dev->dsr->caps.max_sge; 85 props->max_send_sge = dev->dsr->caps.max_sge;
86 props->max_recv_sge = dev->dsr->caps.max_sge;
86 props->max_sge_rd = PVRDMA_GET_CAP(dev, dev->dsr->caps.max_sge, 87 props->max_sge_rd = PVRDMA_GET_CAP(dev, dev->dsr->caps.max_sge,
87 dev->dsr->caps.max_sge_rd); 88 dev->dsr->caps.max_sge_rd);
88 props->max_srq = dev->dsr->caps.max_srq; 89 props->max_srq = dev->dsr->caps.max_srq;
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 815f94c17c48..d29e3c943399 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -780,14 +780,15 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
780 if (!rdi) 780 if (!rdi)
781 return ERR_PTR(-EINVAL); 781 return ERR_PTR(-EINVAL);
782 782
783 if (init_attr->cap.max_send_sge > rdi->dparms.props.max_sge || 783 if (init_attr->cap.max_send_sge > rdi->dparms.props.max_send_sge ||
784 init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr || 784 init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr ||
785 init_attr->create_flags) 785 init_attr->create_flags)
786 return ERR_PTR(-EINVAL); 786 return ERR_PTR(-EINVAL);
787 787
788 /* Check receive queue parameters if no SRQ is specified. */ 788 /* Check receive queue parameters if no SRQ is specified. */
789 if (!init_attr->srq) { 789 if (!init_attr->srq) {
790 if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_sge || 790 if (init_attr->cap.max_recv_sge >
791 rdi->dparms.props.max_recv_sge ||
791 init_attr->cap.max_recv_wr > rdi->dparms.props.max_qp_wr) 792 init_attr->cap.max_recv_wr > rdi->dparms.props.max_qp_wr)
792 return ERR_PTR(-EINVAL); 793 return ERR_PTR(-EINVAL);
793 794
diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
index 7121e1b1eb89..10999fa69281 100644
--- a/drivers/infiniband/sw/rxe/rxe.c
+++ b/drivers/infiniband/sw/rxe/rxe.c
@@ -91,7 +91,8 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
91 rxe->attr.max_qp = RXE_MAX_QP; 91 rxe->attr.max_qp = RXE_MAX_QP;
92 rxe->attr.max_qp_wr = RXE_MAX_QP_WR; 92 rxe->attr.max_qp_wr = RXE_MAX_QP_WR;
93 rxe->attr.device_cap_flags = RXE_DEVICE_CAP_FLAGS; 93 rxe->attr.device_cap_flags = RXE_DEVICE_CAP_FLAGS;
94 rxe->attr.max_sge = RXE_MAX_SGE; 94 rxe->attr.max_send_sge = RXE_MAX_SGE;
95 rxe->attr.max_recv_sge = RXE_MAX_SGE;
95 rxe->attr.max_sge_rd = RXE_MAX_SGE_RD; 96 rxe->attr.max_sge_rd = RXE_MAX_SGE_RD;
96 rxe->attr.max_cq = RXE_MAX_CQ; 97 rxe->attr.max_cq = RXE_MAX_CQ;
97 rxe->attr.max_cqe = (1 << RXE_MAX_LOG_CQE) - 1; 98 rxe->attr.max_cqe = (1 << RXE_MAX_LOG_CQE) - 1;
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
index 9f83fc982f31..c58452daffc7 100644
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -49,9 +49,9 @@ static int rxe_qp_chk_cap(struct rxe_dev *rxe, struct ib_qp_cap *cap,
49 goto err1; 49 goto err1;
50 } 50 }
51 51
52 if (cap->max_send_sge > rxe->attr.max_sge) { 52 if (cap->max_send_sge > rxe->attr.max_send_sge) {
53 pr_warn("invalid send sge = %d > %d\n", 53 pr_warn("invalid send sge = %d > %d\n",
54 cap->max_send_sge, rxe->attr.max_sge); 54 cap->max_send_sge, rxe->attr.max_send_sge);
55 goto err1; 55 goto err1;
56 } 56 }
57 57
@@ -62,9 +62,9 @@ static int rxe_qp_chk_cap(struct rxe_dev *rxe, struct ib_qp_cap *cap,
62 goto err1; 62 goto err1;
63 } 63 }
64 64
65 if (cap->max_recv_sge > rxe->attr.max_sge) { 65 if (cap->max_recv_sge > rxe->attr.max_recv_sge) {
66 pr_warn("invalid recv sge = %d > %d\n", 66 pr_warn("invalid recv sge = %d > %d\n",
67 cap->max_recv_sge, rxe->attr.max_sge); 67 cap->max_recv_sge, rxe->attr.max_recv_sge);
68 goto err1; 68 goto err1;
69 } 69 }
70 } 70 }
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 6535d9beb24d..23cb1adc636f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1068,8 +1068,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
1068 struct ib_qp *tx_qp; 1068 struct ib_qp *tx_qp;
1069 1069
1070 if (dev->features & NETIF_F_SG) 1070 if (dev->features & NETIF_F_SG)
1071 attr.cap.max_send_sge = 1071 attr.cap.max_send_sge = min_t(u32, priv->ca->attrs.max_send_sge,
1072 min_t(u32, priv->ca->attrs.max_sge, MAX_SKB_FRAGS + 1); 1072 MAX_SKB_FRAGS + 1);
1073 1073
1074 tx_qp = ib_create_qp(priv->pd, &attr); 1074 tx_qp = ib_create_qp(priv->pd, &attr);
1075 tx->max_send_sge = attr.cap.max_send_sge; 1075 tx->max_send_sge = attr.cap.max_send_sge;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 984a88096f39..ba4669f24014 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -147,7 +147,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
147 .cap = { 147 .cap = {
148 .max_send_wr = ipoib_sendq_size, 148 .max_send_wr = ipoib_sendq_size,
149 .max_recv_wr = ipoib_recvq_size, 149 .max_recv_wr = ipoib_recvq_size,
150 .max_send_sge = min_t(u32, priv->ca->attrs.max_sge, 150 .max_send_sge = min_t(u32, priv->ca->attrs.max_send_sge,
151 MAX_SKB_FRAGS + 1), 151 MAX_SKB_FRAGS + 1),
152 .max_recv_sge = IPOIB_UD_RX_SG 152 .max_recv_sge = IPOIB_UD_RX_SG
153 }, 153 },
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index cccbcf0eb035..7e056f3c82a0 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -136,7 +136,7 @@ isert_create_qp(struct isert_conn *isert_conn,
136 attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS + 1; 136 attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS + 1;
137 attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1; 137 attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
138 attr.cap.max_rdma_ctxs = ISCSI_DEF_XMIT_CMDS_MAX; 138 attr.cap.max_rdma_ctxs = ISCSI_DEF_XMIT_CMDS_MAX;
139 attr.cap.max_send_sge = device->ib_device->attrs.max_sge; 139 attr.cap.max_send_sge = device->ib_device->attrs.max_send_sge;
140 attr.cap.max_recv_sge = 1; 140 attr.cap.max_recv_sge = 1;
141 attr.sq_sig_type = IB_SIGNAL_REQ_WR; 141 attr.sq_sig_type = IB_SIGNAL_REQ_WR;
142 attr.qp_type = IB_QPT_RC; 142 attr.qp_type = IB_QPT_RC;
@@ -299,7 +299,8 @@ isert_create_device_ib_res(struct isert_device *device)
299 struct ib_device *ib_dev = device->ib_device; 299 struct ib_device *ib_dev = device->ib_device;
300 int ret; 300 int ret;
301 301
302 isert_dbg("devattr->max_sge: %d\n", ib_dev->attrs.max_sge); 302 isert_dbg("devattr->max_send_sge: %d devattr->max_recv_sge %d\n",
303 ib_dev->attrs.max_send_sge, ib_dev->attrs.max_recv_sge);
303 isert_dbg("devattr->max_sge_rd: %d\n", ib_dev->attrs.max_sge_rd); 304 isert_dbg("devattr->max_sge_rd: %d\n", ib_dev->attrs.max_sge_rd);
304 305
305 ret = isert_alloc_comps(device); 306 ret = isert_alloc_comps(device);
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 698f7779e231..1b0b285a0ae0 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1753,13 +1753,15 @@ retry:
1753 */ 1753 */
1754 qp_init->cap.max_send_wr = min(sq_size / 2, attrs->max_qp_wr); 1754 qp_init->cap.max_send_wr = min(sq_size / 2, attrs->max_qp_wr);
1755 qp_init->cap.max_rdma_ctxs = sq_size / 2; 1755 qp_init->cap.max_rdma_ctxs = sq_size / 2;
1756 qp_init->cap.max_send_sge = min(attrs->max_sge, SRPT_MAX_SG_PER_WQE); 1756 qp_init->cap.max_send_sge = min(attrs->max_send_sge,
1757 SRPT_MAX_SG_PER_WQE);
1757 qp_init->port_num = ch->sport->port; 1758 qp_init->port_num = ch->sport->port;
1758 if (sdev->use_srq) { 1759 if (sdev->use_srq) {
1759 qp_init->srq = sdev->srq; 1760 qp_init->srq = sdev->srq;
1760 } else { 1761 } else {
1761 qp_init->cap.max_recv_wr = ch->rq_size; 1762 qp_init->cap.max_recv_wr = ch->rq_size;
1762 qp_init->cap.max_recv_sge = qp_init->cap.max_send_sge; 1763 qp_init->cap.max_recv_sge = min(attrs->max_recv_sge,
1764 SRPT_MAX_SG_PER_WQE);
1763 } 1765 }
1764 1766
1765 if (ch->using_rdma_cm) { 1767 if (ch->using_rdma_cm) {
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 52e0c5d579a7..0d7f3d603f1d 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -874,7 +874,7 @@ static int nvmet_rdma_create_queue_ib(struct nvmet_rdma_queue *queue)
874 qp_attr.cap.max_send_wr = queue->send_queue_size + 1; 874 qp_attr.cap.max_send_wr = queue->send_queue_size + 1;
875 qp_attr.cap.max_rdma_ctxs = queue->send_queue_size; 875 qp_attr.cap.max_rdma_ctxs = queue->send_queue_size;
876 qp_attr.cap.max_send_sge = max(ndev->device->attrs.max_sge_rd, 876 qp_attr.cap.max_send_sge = max(ndev->device->attrs.max_sge_rd,
877 ndev->device->attrs.max_sge); 877 ndev->device->attrs.max_send_sge);
878 878
879 if (ndev->srq) { 879 if (ndev->srq) {
880 qp_attr.srq = ndev->srq; 880 qp_attr.srq = ndev->srq;
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index e459c97151b3..c5a1cddd8856 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -1661,9 +1661,16 @@ static struct smbd_connection *_smbd_get_connection(
1661 info->max_receive_size = smbd_max_receive_size; 1661 info->max_receive_size = smbd_max_receive_size;
1662 info->keep_alive_interval = smbd_keep_alive_interval; 1662 info->keep_alive_interval = smbd_keep_alive_interval;
1663 1663
1664 if (info->id->device->attrs.max_sge < SMBDIRECT_MAX_SGE) { 1664 if (info->id->device->attrs.max_send_sge < SMBDIRECT_MAX_SGE) {
1665 log_rdma_event(ERR, "warning: device max_sge = %d too small\n", 1665 log_rdma_event(ERR,
1666 info->id->device->attrs.max_sge); 1666 "warning: device max_send_sge = %d too small\n",
1667 info->id->device->attrs.max_send_sge);
1668 log_rdma_event(ERR, "Queue Pair creation may fail\n");
1669 }
1670 if (info->id->device->attrs.max_recv_sge < SMBDIRECT_MAX_SGE) {
1671 log_rdma_event(ERR,
1672 "warning: device max_recv_sge = %d too small\n",
1673 info->id->device->attrs.max_recv_sge);
1667 log_rdma_event(ERR, "Queue Pair creation may fail\n"); 1674 log_rdma_event(ERR, "Queue Pair creation may fail\n");
1668 } 1675 }
1669 1676
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 0232c0f9f717..dc5d262739e5 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -345,7 +345,8 @@ struct ib_device_attr {
345 int max_qp; 345 int max_qp;
346 int max_qp_wr; 346 int max_qp_wr;
347 u64 device_cap_flags; 347 u64 device_cap_flags;
348 int max_sge; 348 int max_send_sge;
349 int max_recv_sge;
349 int max_sge_rd; 350 int max_sge_rd;
350 int max_cq; 351 int max_cq;
351 int max_cqe; 352 int max_cqe;
diff --git a/net/rds/ib.c b/net/rds/ib.c
index b6ad38e48f62..683b55d4e2b0 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -143,7 +143,7 @@ static void rds_ib_add_one(struct ib_device *device)
143 INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free); 143 INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free);
144 144
145 rds_ibdev->max_wrs = device->attrs.max_qp_wr; 145 rds_ibdev->max_wrs = device->attrs.max_qp_wr;
146 rds_ibdev->max_sge = min(device->attrs.max_sge, RDS_IB_MAX_SGE); 146 rds_ibdev->max_sge = min(device->attrs.max_send_sge, RDS_IB_MAX_SGE);
147 147
148 has_fr = (device->attrs.device_cap_flags & 148 has_fr = (device->attrs.device_cap_flags &
149 IB_DEVICE_MEM_MGT_EXTENSIONS); 149 IB_DEVICE_MEM_MGT_EXTENSIONS);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index e9535a66bab0..547b2cdf1427 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -476,7 +476,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
476 476
477 /* Qualify the transport resource defaults with the 477 /* Qualify the transport resource defaults with the
478 * capabilities of this particular device */ 478 * capabilities of this particular device */
479 newxprt->sc_max_send_sges = dev->attrs.max_sge; 479 newxprt->sc_max_send_sges = dev->attrs.max_send_sge;
480 /* transport hdr, head iovec, one page list entry, tail iovec */ 480 /* transport hdr, head iovec, one page list entry, tail iovec */
481 if (newxprt->sc_max_send_sges < 4) { 481 if (newxprt->sc_max_send_sges < 4) {
482 pr_err("svcrdma: too few Send SGEs available (%d)\n", 482 pr_err("svcrdma: too few Send SGEs available (%d)\n",
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 16161a36dc73..112a15abc4a4 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -508,7 +508,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
508 unsigned int max_sge; 508 unsigned int max_sge;
509 int rc; 509 int rc;
510 510
511 max_sge = min_t(unsigned int, ia->ri_device->attrs.max_sge, 511 max_sge = min_t(unsigned int, ia->ri_device->attrs.max_send_sge,
512 RPCRDMA_MAX_SEND_SGES); 512 RPCRDMA_MAX_SEND_SGES);
513 if (max_sge < RPCRDMA_MIN_SEND_SGES) { 513 if (max_sge < RPCRDMA_MIN_SEND_SGES) {
514 pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); 514 pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge);