aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c4
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h5
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c101
-rw-r--r--drivers/infiniband/hw/mlx4/user.h9
-rw-r--r--drivers/net/mlx4/fw.c2
5 files changed, 83 insertions, 38 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 048c5274ab1c..e940521e9c8d 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -355,7 +355,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
355 wq = &(*cur_qp)->sq; 355 wq = &(*cur_qp)->sq;
356 wqe_ctr = be16_to_cpu(cqe->wqe_index); 356 wqe_ctr = be16_to_cpu(cqe->wqe_index);
357 wq->tail += (u16) (wqe_ctr - (u16) wq->tail); 357 wq->tail += (u16) (wqe_ctr - (u16) wq->tail);
358 wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; 358 wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
359 ++wq->tail; 359 ++wq->tail;
360 } else if ((*cur_qp)->ibqp.srq) { 360 } else if ((*cur_qp)->ibqp.srq) {
361 srq = to_msrq((*cur_qp)->ibqp.srq); 361 srq = to_msrq((*cur_qp)->ibqp.srq);
@@ -364,7 +364,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
364 mlx4_ib_free_srq_wqe(srq, wqe_ctr); 364 mlx4_ib_free_srq_wqe(srq, wqe_ctr);
365 } else { 365 } else {
366 wq = &(*cur_qp)->rq; 366 wq = &(*cur_qp)->rq;
367 wc->wr_id = wq->wrid[wq->tail & (wq->max - 1)]; 367 wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
368 ++wq->tail; 368 ++wq->tail;
369 } 369 }
370 370
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 93dac71f3230..24ccadd6e4f8 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -95,7 +95,8 @@ struct mlx4_ib_mr {
95struct mlx4_ib_wq { 95struct mlx4_ib_wq {
96 u64 *wrid; 96 u64 *wrid;
97 spinlock_t lock; 97 spinlock_t lock;
98 int max; 98 int wqe_cnt;
99 int max_post;
99 int max_gs; 100 int max_gs;
100 int offset; 101 int offset;
101 int wqe_shift; 102 int wqe_shift;
@@ -113,6 +114,7 @@ struct mlx4_ib_qp {
113 114
114 u32 doorbell_qpn; 115 u32 doorbell_qpn;
115 __be32 sq_signal_bits; 116 __be32 sq_signal_bits;
117 int sq_spare_wqes;
116 struct mlx4_ib_wq sq; 118 struct mlx4_ib_wq sq;
117 119
118 struct ib_umem *umem; 120 struct ib_umem *umem;
@@ -123,6 +125,7 @@ struct mlx4_ib_qp {
123 u8 alt_port; 125 u8 alt_port;
124 u8 atomic_rd_en; 126 u8 atomic_rd_en;
125 u8 resp_depth; 127 u8 resp_depth;
128 u8 sq_no_prefetch;
126 u8 state; 129 u8 state;
127}; 130};
128 131
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 4c15fa3426b8..8fabe0da3234 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -109,6 +109,20 @@ static void *get_send_wqe(struct mlx4_ib_qp *qp, int n)
109 return get_wqe(qp, qp->sq.offset + (n << qp->sq.wqe_shift)); 109 return get_wqe(qp, qp->sq.offset + (n << qp->sq.wqe_shift));
110} 110}
111 111
112/*
113 * Stamp a SQ WQE so that it is invalid if prefetched by marking the
114 * first four bytes of every 64 byte chunk with 0xffffffff, except for
115 * the very first chunk of the WQE.
116 */
117static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n)
118{
119 u32 *wqe = get_send_wqe(qp, n);
120 int i;
121
122 for (i = 16; i < 1 << (qp->sq.wqe_shift - 2); i += 16)
123 wqe[i] = 0xffffffff;
124}
125
112static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type) 126static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type)
113{ 127{
114 struct ib_event event; 128 struct ib_event event;
@@ -201,18 +215,18 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
201 if (cap->max_recv_wr) 215 if (cap->max_recv_wr)
202 return -EINVAL; 216 return -EINVAL;
203 217
204 qp->rq.max = qp->rq.max_gs = 0; 218 qp->rq.wqe_cnt = qp->rq.max_gs = 0;
205 } else { 219 } else {
206 /* HW requires >= 1 RQ entry with >= 1 gather entry */ 220 /* HW requires >= 1 RQ entry with >= 1 gather entry */
207 if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge)) 221 if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
208 return -EINVAL; 222 return -EINVAL;
209 223
210 qp->rq.max = roundup_pow_of_two(max(1U, cap->max_recv_wr)); 224 qp->rq.wqe_cnt = roundup_pow_of_two(max(1U, cap->max_recv_wr));
211 qp->rq.max_gs = roundup_pow_of_two(max(1U, cap->max_recv_sge)); 225 qp->rq.max_gs = roundup_pow_of_two(max(1U, cap->max_recv_sge));
212 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); 226 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
213 } 227 }
214 228
215 cap->max_recv_wr = qp->rq.max; 229 cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt;
216 cap->max_recv_sge = qp->rq.max_gs; 230 cap->max_recv_sge = qp->rq.max_gs;
217 231
218 return 0; 232 return 0;
@@ -236,8 +250,6 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
236 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg) 250 cap->max_send_sge + 2 > dev->dev->caps.max_sq_sg)
237 return -EINVAL; 251 return -EINVAL;
238 252
239 qp->sq.max = cap->max_send_wr ? roundup_pow_of_two(cap->max_send_wr) : 1;
240
241 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge * 253 qp->sq.wqe_shift = ilog2(roundup_pow_of_two(max(cap->max_send_sge *
242 sizeof (struct mlx4_wqe_data_seg), 254 sizeof (struct mlx4_wqe_data_seg),
243 cap->max_inline_data + 255 cap->max_inline_data +
@@ -246,18 +258,25 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
246 qp->sq.max_gs = ((1 << qp->sq.wqe_shift) - send_wqe_overhead(type)) / 258 qp->sq.max_gs = ((1 << qp->sq.wqe_shift) - send_wqe_overhead(type)) /
247 sizeof (struct mlx4_wqe_data_seg); 259 sizeof (struct mlx4_wqe_data_seg);
248 260
249 qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) + 261 /*
250 (qp->sq.max << qp->sq.wqe_shift); 262 * We need to leave 2 KB + 1 WQE of headroom in the SQ to
263 * allow HW to prefetch.
264 */
265 qp->sq_spare_wqes = (2048 >> qp->sq.wqe_shift) + 1;
266 qp->sq.wqe_cnt = roundup_pow_of_two(cap->max_send_wr + qp->sq_spare_wqes);
267
268 qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
269 (qp->sq.wqe_cnt << qp->sq.wqe_shift);
251 if (qp->rq.wqe_shift > qp->sq.wqe_shift) { 270 if (qp->rq.wqe_shift > qp->sq.wqe_shift) {
252 qp->rq.offset = 0; 271 qp->rq.offset = 0;
253 qp->sq.offset = qp->rq.max << qp->rq.wqe_shift; 272 qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
254 } else { 273 } else {
255 qp->rq.offset = qp->sq.max << qp->sq.wqe_shift; 274 qp->rq.offset = qp->sq.wqe_cnt << qp->sq.wqe_shift;
256 qp->sq.offset = 0; 275 qp->sq.offset = 0;
257 } 276 }
258 277
259 cap->max_send_wr = qp->sq.max; 278 cap->max_send_wr = qp->sq.max_post = qp->sq.wqe_cnt - qp->sq_spare_wqes;
260 cap->max_send_sge = qp->sq.max_gs; 279 cap->max_send_sge = qp->sq.max_gs;
261 cap->max_inline_data = (1 << qp->sq.wqe_shift) - send_wqe_overhead(type) - 280 cap->max_inline_data = (1 << qp->sq.wqe_shift) - send_wqe_overhead(type) -
262 sizeof (struct mlx4_wqe_inline_seg); 281 sizeof (struct mlx4_wqe_inline_seg);
263 282
@@ -267,11 +286,11 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
267static int set_user_sq_size(struct mlx4_ib_qp *qp, 286static int set_user_sq_size(struct mlx4_ib_qp *qp,
268 struct mlx4_ib_create_qp *ucmd) 287 struct mlx4_ib_create_qp *ucmd)
269{ 288{
270 qp->sq.max = 1 << ucmd->log_sq_bb_count; 289 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
271 qp->sq.wqe_shift = ucmd->log_sq_stride; 290 qp->sq.wqe_shift = ucmd->log_sq_stride;
272 291
273 qp->buf_size = (qp->rq.max << qp->rq.wqe_shift) + 292 qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
274 (qp->sq.max << qp->sq.wqe_shift); 293 (qp->sq.wqe_cnt << qp->sq.wqe_shift);
275 294
276 return 0; 295 return 0;
277} 296}
@@ -307,6 +326,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
307 goto err; 326 goto err;
308 } 327 }
309 328
329 qp->sq_no_prefetch = ucmd.sq_no_prefetch;
330
310 err = set_user_sq_size(qp, &ucmd); 331 err = set_user_sq_size(qp, &ucmd);
311 if (err) 332 if (err)
312 goto err; 333 goto err;
@@ -334,6 +355,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
334 goto err_mtt; 355 goto err_mtt;
335 } 356 }
336 } else { 357 } else {
358 qp->sq_no_prefetch = 0;
359
337 err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp); 360 err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
338 if (err) 361 if (err)
339 goto err; 362 goto err;
@@ -360,8 +383,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
360 if (err) 383 if (err)
361 goto err_mtt; 384 goto err_mtt;
362 385
363 qp->sq.wrid = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL); 386 qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof (u64), GFP_KERNEL);
364 qp->rq.wrid = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL); 387 qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof (u64), GFP_KERNEL);
365 388
366 if (!qp->sq.wrid || !qp->rq.wrid) { 389 if (!qp->sq.wrid || !qp->rq.wrid) {
367 err = -ENOMEM; 390 err = -ENOMEM;
@@ -743,14 +766,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
743 context->mtu_msgmax = (attr->path_mtu << 5) | 31; 766 context->mtu_msgmax = (attr->path_mtu << 5) | 31;
744 } 767 }
745 768
746 if (qp->rq.max) 769 if (qp->rq.wqe_cnt)
747 context->rq_size_stride = ilog2(qp->rq.max) << 3; 770 context->rq_size_stride = ilog2(qp->rq.wqe_cnt) << 3;
748 context->rq_size_stride |= qp->rq.wqe_shift - 4; 771 context->rq_size_stride |= qp->rq.wqe_shift - 4;
749 772
750 if (qp->sq.max) 773 if (qp->sq.wqe_cnt)
751 context->sq_size_stride = ilog2(qp->sq.max) << 3; 774 context->sq_size_stride = ilog2(qp->sq.wqe_cnt) << 3;
752 context->sq_size_stride |= qp->sq.wqe_shift - 4; 775 context->sq_size_stride |= qp->sq.wqe_shift - 4;
753 776
777 if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
778 context->sq_size_stride |= !!qp->sq_no_prefetch << 7;
779
754 if (qp->ibqp.uobject) 780 if (qp->ibqp.uobject)
755 context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index); 781 context->usr_page = cpu_to_be32(to_mucontext(ibqp->uobject->context)->uar.index);
756 else 782 else
@@ -884,16 +910,19 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
884 910
885 /* 911 /*
886 * Before passing a kernel QP to the HW, make sure that the 912 * Before passing a kernel QP to the HW, make sure that the
887 * ownership bits of the send queue are set so that the 913 * ownership bits of the send queue are set and the SQ
888 * hardware doesn't start processing stale work requests. 914 * headroom is stamped so that the hardware doesn't start
915 * processing stale work requests.
889 */ 916 */
890 if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) { 917 if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
891 struct mlx4_wqe_ctrl_seg *ctrl; 918 struct mlx4_wqe_ctrl_seg *ctrl;
892 int i; 919 int i;
893 920
894 for (i = 0; i < qp->sq.max; ++i) { 921 for (i = 0; i < qp->sq.wqe_cnt; ++i) {
895 ctrl = get_send_wqe(qp, i); 922 ctrl = get_send_wqe(qp, i);
896 ctrl->owner_opcode = cpu_to_be32(1 << 31); 923 ctrl->owner_opcode = cpu_to_be32(1 << 31);
924
925 stamp_send_wqe(qp, i);
897 } 926 }
898 } 927 }
899 928
@@ -1124,7 +1153,7 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1124 struct mlx4_ib_cq *cq; 1153 struct mlx4_ib_cq *cq;
1125 1154
1126 cur = wq->head - wq->tail; 1155 cur = wq->head - wq->tail;
1127 if (likely(cur + nreq < wq->max)) 1156 if (likely(cur + nreq < wq->max_post))
1128 return 0; 1157 return 0;
1129 1158
1130 cq = to_mcq(ib_cq); 1159 cq = to_mcq(ib_cq);
@@ -1132,7 +1161,7 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1132 cur = wq->head - wq->tail; 1161 cur = wq->head - wq->tail;
1133 spin_unlock(&cq->lock); 1162 spin_unlock(&cq->lock);
1134 1163
1135 return cur + nreq >= wq->max; 1164 return cur + nreq >= wq->max_post;
1136} 1165}
1137 1166
1138int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 1167int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
@@ -1165,8 +1194,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1165 goto out; 1194 goto out;
1166 } 1195 }
1167 1196
1168 ctrl = wqe = get_send_wqe(qp, ind & (qp->sq.max - 1)); 1197 ctrl = wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1));
1169 qp->sq.wrid[ind & (qp->sq.max - 1)] = wr->wr_id; 1198 qp->sq.wrid[ind & (qp->sq.wqe_cnt - 1)] = wr->wr_id;
1170 1199
1171 ctrl->srcrb_flags = 1200 ctrl->srcrb_flags =
1172 (wr->send_flags & IB_SEND_SIGNALED ? 1201 (wr->send_flags & IB_SEND_SIGNALED ?
@@ -1301,7 +1330,16 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1301 } 1330 }
1302 1331
1303 ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] | 1332 ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
1304 (ind & qp->sq.max ? cpu_to_be32(1 << 31) : 0); 1333 (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0);
1334
1335 /*
1336 * We can improve latency by not stamping the last
1337 * send queue WQE until after ringing the doorbell, so
1338 * only stamp here if there are still more WQEs to post.
1339 */
1340 if (wr->next)
1341 stamp_send_wqe(qp, (ind + qp->sq_spare_wqes) &
1342 (qp->sq.wqe_cnt - 1));
1305 1343
1306 ++ind; 1344 ++ind;
1307 } 1345 }
@@ -1324,6 +1362,9 @@ out:
1324 * and reach the HCA out of order. 1362 * and reach the HCA out of order.
1325 */ 1363 */
1326 mmiowb(); 1364 mmiowb();
1365
1366 stamp_send_wqe(qp, (ind + qp->sq_spare_wqes - 1) &
1367 (qp->sq.wqe_cnt - 1));
1327 } 1368 }
1328 1369
1329 spin_unlock_irqrestore(&qp->rq.lock, flags); 1370 spin_unlock_irqrestore(&qp->rq.lock, flags);
@@ -1344,7 +1385,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1344 1385
1345 spin_lock_irqsave(&qp->rq.lock, flags); 1386 spin_lock_irqsave(&qp->rq.lock, flags);
1346 1387
1347 ind = qp->rq.head & (qp->rq.max - 1); 1388 ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
1348 1389
1349 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1390 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1350 if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) { 1391 if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) {
@@ -1375,7 +1416,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1375 1416
1376 qp->rq.wrid[ind] = wr->wr_id; 1417 qp->rq.wrid[ind] = wr->wr_id;
1377 1418
1378 ind = (ind + 1) & (qp->rq.max - 1); 1419 ind = (ind + 1) & (qp->rq.wqe_cnt - 1);
1379 } 1420 }
1380 1421
1381out: 1422out:
diff --git a/drivers/infiniband/hw/mlx4/user.h b/drivers/infiniband/hw/mlx4/user.h
index 88c72d56368b..e2d11be4525c 100644
--- a/drivers/infiniband/hw/mlx4/user.h
+++ b/drivers/infiniband/hw/mlx4/user.h
@@ -39,7 +39,7 @@
39 * Increment this value if any changes that break userspace ABI 39 * Increment this value if any changes that break userspace ABI
40 * compatibility are made. 40 * compatibility are made.
41 */ 41 */
42#define MLX4_IB_UVERBS_ABI_VERSION 2 42#define MLX4_IB_UVERBS_ABI_VERSION 3
43 43
44/* 44/*
45 * Make sure that all structs defined in this file remain laid out so 45 * Make sure that all structs defined in this file remain laid out so
@@ -87,9 +87,10 @@ struct mlx4_ib_create_srq_resp {
87struct mlx4_ib_create_qp { 87struct mlx4_ib_create_qp {
88 __u64 buf_addr; 88 __u64 buf_addr;
89 __u64 db_addr; 89 __u64 db_addr;
90 __u8 log_sq_bb_count; 90 __u8 log_sq_bb_count;
91 __u8 log_sq_stride; 91 __u8 log_sq_stride;
92 __u8 reserved[6]; 92 __u8 sq_no_prefetch;
93 __u8 reserved[5];
93}; 94};
94 95
95#endif /* MLX4_IB_USER_H */ 96#endif /* MLX4_IB_USER_H */
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index e7ca118c8dfd..81fc546a1c44 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -38,7 +38,7 @@
38#include "icm.h" 38#include "icm.h"
39 39
40enum { 40enum {
41 MLX4_COMMAND_INTERFACE_REV = 1 41 MLX4_COMMAND_INTERFACE_REV = 2,
42}; 42};
43 43
44extern void __buggy_use_of_MLX4_GET(void); 44extern void __buggy_use_of_MLX4_GET(void);