diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_ruc.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ruc.c | 329 |
1 files changed, 192 insertions, 137 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index 9e3fe61cbd0..a4b5521567f 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. | 2 | * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. |
3 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | 3 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
@@ -78,6 +78,7 @@ const u32 ib_ipath_rnr_table[32] = { | |||
78 | * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device | 78 | * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device |
79 | * @qp: the QP | 79 | * @qp: the QP |
80 | * | 80 | * |
81 | * Called with the QP s_lock held and interrupts disabled. | ||
81 | * XXX Use a simple list for now. We might need a priority | 82 | * XXX Use a simple list for now. We might need a priority |
82 | * queue if we have lots of QPs waiting for RNR timeouts | 83 | * queue if we have lots of QPs waiting for RNR timeouts |
83 | * but that should be rare. | 84 | * but that should be rare. |
@@ -85,9 +86,9 @@ const u32 ib_ipath_rnr_table[32] = { | |||
85 | void ipath_insert_rnr_queue(struct ipath_qp *qp) | 86 | void ipath_insert_rnr_queue(struct ipath_qp *qp) |
86 | { | 87 | { |
87 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 88 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
88 | unsigned long flags; | ||
89 | 89 | ||
90 | spin_lock_irqsave(&dev->pending_lock, flags); | 90 | /* We already did a spin_lock_irqsave(), so just use spin_lock */ |
91 | spin_lock(&dev->pending_lock); | ||
91 | if (list_empty(&dev->rnrwait)) | 92 | if (list_empty(&dev->rnrwait)) |
92 | list_add(&qp->timerwait, &dev->rnrwait); | 93 | list_add(&qp->timerwait, &dev->rnrwait); |
93 | else { | 94 | else { |
@@ -109,7 +110,7 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) | |||
109 | nqp->s_rnr_timeout -= qp->s_rnr_timeout; | 110 | nqp->s_rnr_timeout -= qp->s_rnr_timeout; |
110 | list_add(&qp->timerwait, l); | 111 | list_add(&qp->timerwait, l); |
111 | } | 112 | } |
112 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 113 | spin_unlock(&dev->pending_lock); |
113 | } | 114 | } |
114 | 115 | ||
115 | /** | 116 | /** |
@@ -140,20 +141,11 @@ int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | |||
140 | goto bail; | 141 | goto bail; |
141 | 142 | ||
142 | bad_lkey: | 143 | bad_lkey: |
144 | memset(&wc, 0, sizeof(wc)); | ||
143 | wc.wr_id = wqe->wr_id; | 145 | wc.wr_id = wqe->wr_id; |
144 | wc.status = IB_WC_LOC_PROT_ERR; | 146 | wc.status = IB_WC_LOC_PROT_ERR; |
145 | wc.opcode = IB_WC_RECV; | 147 | wc.opcode = IB_WC_RECV; |
146 | wc.vendor_err = 0; | ||
147 | wc.byte_len = 0; | ||
148 | wc.imm_data = 0; | ||
149 | wc.qp = &qp->ibqp; | 148 | wc.qp = &qp->ibqp; |
150 | wc.src_qp = 0; | ||
151 | wc.wc_flags = 0; | ||
152 | wc.pkey_index = 0; | ||
153 | wc.slid = 0; | ||
154 | wc.sl = 0; | ||
155 | wc.dlid_path_bits = 0; | ||
156 | wc.port_num = 0; | ||
157 | /* Signal solicited completion event. */ | 149 | /* Signal solicited completion event. */ |
158 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | 150 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); |
159 | ret = 0; | 151 | ret = 0; |
@@ -194,6 +186,11 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
194 | } | 186 | } |
195 | 187 | ||
196 | spin_lock_irqsave(&rq->lock, flags); | 188 | spin_lock_irqsave(&rq->lock, flags); |
189 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { | ||
190 | ret = 0; | ||
191 | goto unlock; | ||
192 | } | ||
193 | |||
197 | wq = rq->wq; | 194 | wq = rq->wq; |
198 | tail = wq->tail; | 195 | tail = wq->tail; |
199 | /* Validate tail before using it since it is user writable. */ | 196 | /* Validate tail before using it since it is user writable. */ |
@@ -201,9 +198,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
201 | tail = 0; | 198 | tail = 0; |
202 | do { | 199 | do { |
203 | if (unlikely(tail == wq->head)) { | 200 | if (unlikely(tail == wq->head)) { |
204 | spin_unlock_irqrestore(&rq->lock, flags); | ||
205 | ret = 0; | 201 | ret = 0; |
206 | goto bail; | 202 | goto unlock; |
207 | } | 203 | } |
208 | /* Make sure entry is read after head index is read. */ | 204 | /* Make sure entry is read after head index is read. */ |
209 | smp_rmb(); | 205 | smp_rmb(); |
@@ -216,7 +212,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
216 | wq->tail = tail; | 212 | wq->tail = tail; |
217 | 213 | ||
218 | ret = 1; | 214 | ret = 1; |
219 | qp->r_wrid_valid = 1; | 215 | set_bit(IPATH_R_WRID_VALID, &qp->r_aflags); |
220 | if (handler) { | 216 | if (handler) { |
221 | u32 n; | 217 | u32 n; |
222 | 218 | ||
@@ -243,8 +239,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
243 | goto bail; | 239 | goto bail; |
244 | } | 240 | } |
245 | } | 241 | } |
242 | unlock: | ||
246 | spin_unlock_irqrestore(&rq->lock, flags); | 243 | spin_unlock_irqrestore(&rq->lock, flags); |
247 | |||
248 | bail: | 244 | bail: |
249 | return ret; | 245 | return ret; |
250 | } | 246 | } |
@@ -270,38 +266,63 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp) | |||
270 | struct ib_wc wc; | 266 | struct ib_wc wc; |
271 | u64 sdata; | 267 | u64 sdata; |
272 | atomic64_t *maddr; | 268 | atomic64_t *maddr; |
269 | enum ib_wc_status send_status; | ||
273 | 270 | ||
271 | /* | ||
272 | * Note that we check the responder QP state after | ||
273 | * checking the requester's state. | ||
274 | */ | ||
274 | qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn); | 275 | qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn); |
275 | if (!qp) { | ||
276 | dev->n_pkt_drops++; | ||
277 | return; | ||
278 | } | ||
279 | 276 | ||
280 | again: | ||
281 | spin_lock_irqsave(&sqp->s_lock, flags); | 277 | spin_lock_irqsave(&sqp->s_lock, flags); |
282 | 278 | ||
283 | if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) || | 279 | /* Return if we are already busy processing a work request. */ |
284 | sqp->s_rnr_timeout) { | 280 | if ((sqp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) || |
285 | spin_unlock_irqrestore(&sqp->s_lock, flags); | 281 | !(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) |
286 | goto done; | 282 | goto unlock; |
287 | } | ||
288 | 283 | ||
289 | /* Get the next send request. */ | 284 | sqp->s_flags |= IPATH_S_BUSY; |
290 | if (sqp->s_last == sqp->s_head) { | 285 | |
291 | /* Send work queue is empty. */ | 286 | again: |
292 | spin_unlock_irqrestore(&sqp->s_lock, flags); | 287 | if (sqp->s_last == sqp->s_head) |
293 | goto done; | 288 | goto clr_busy; |
289 | wqe = get_swqe_ptr(sqp, sqp->s_last); | ||
290 | |||
291 | /* Return if it is not OK to start a new work reqeust. */ | ||
292 | if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_NEXT_SEND_OK)) { | ||
293 | if (!(ib_ipath_state_ops[sqp->state] & IPATH_FLUSH_SEND)) | ||
294 | goto clr_busy; | ||
295 | /* We are in the error state, flush the work request. */ | ||
296 | send_status = IB_WC_WR_FLUSH_ERR; | ||
297 | goto flush_send; | ||
294 | } | 298 | } |
295 | 299 | ||
296 | /* | 300 | /* |
297 | * We can rely on the entry not changing without the s_lock | 301 | * We can rely on the entry not changing without the s_lock |
298 | * being held until we update s_last. | 302 | * being held until we update s_last. |
303 | * We increment s_cur to indicate s_last is in progress. | ||
299 | */ | 304 | */ |
300 | wqe = get_swqe_ptr(sqp, sqp->s_last); | 305 | if (sqp->s_last == sqp->s_cur) { |
306 | if (++sqp->s_cur >= sqp->s_size) | ||
307 | sqp->s_cur = 0; | ||
308 | } | ||
301 | spin_unlock_irqrestore(&sqp->s_lock, flags); | 309 | spin_unlock_irqrestore(&sqp->s_lock, flags); |
302 | 310 | ||
303 | wc.wc_flags = 0; | 311 | if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { |
304 | wc.imm_data = 0; | 312 | dev->n_pkt_drops++; |
313 | /* | ||
314 | * For RC, the requester would timeout and retry so | ||
315 | * shortcut the timeouts and just signal too many retries. | ||
316 | */ | ||
317 | if (sqp->ibqp.qp_type == IB_QPT_RC) | ||
318 | send_status = IB_WC_RETRY_EXC_ERR; | ||
319 | else | ||
320 | send_status = IB_WC_SUCCESS; | ||
321 | goto serr; | ||
322 | } | ||
323 | |||
324 | memset(&wc, 0, sizeof wc); | ||
325 | send_status = IB_WC_SUCCESS; | ||
305 | 326 | ||
306 | sqp->s_sge.sge = wqe->sg_list[0]; | 327 | sqp->s_sge.sge = wqe->sg_list[0]; |
307 | sqp->s_sge.sg_list = wqe->sg_list + 1; | 328 | sqp->s_sge.sg_list = wqe->sg_list + 1; |
@@ -313,75 +334,33 @@ again: | |||
313 | wc.imm_data = wqe->wr.ex.imm_data; | 334 | wc.imm_data = wqe->wr.ex.imm_data; |
314 | /* FALLTHROUGH */ | 335 | /* FALLTHROUGH */ |
315 | case IB_WR_SEND: | 336 | case IB_WR_SEND: |
316 | if (!ipath_get_rwqe(qp, 0)) { | 337 | if (!ipath_get_rwqe(qp, 0)) |
317 | rnr_nak: | 338 | goto rnr_nak; |
318 | /* Handle RNR NAK */ | ||
319 | if (qp->ibqp.qp_type == IB_QPT_UC) | ||
320 | goto send_comp; | ||
321 | if (sqp->s_rnr_retry == 0) { | ||
322 | wc.status = IB_WC_RNR_RETRY_EXC_ERR; | ||
323 | goto err; | ||
324 | } | ||
325 | if (sqp->s_rnr_retry_cnt < 7) | ||
326 | sqp->s_rnr_retry--; | ||
327 | dev->n_rnr_naks++; | ||
328 | sqp->s_rnr_timeout = | ||
329 | ib_ipath_rnr_table[qp->r_min_rnr_timer]; | ||
330 | ipath_insert_rnr_queue(sqp); | ||
331 | goto done; | ||
332 | } | ||
333 | break; | 339 | break; |
334 | 340 | ||
335 | case IB_WR_RDMA_WRITE_WITH_IMM: | 341 | case IB_WR_RDMA_WRITE_WITH_IMM: |
336 | if (unlikely(!(qp->qp_access_flags & | 342 | if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) |
337 | IB_ACCESS_REMOTE_WRITE))) { | 343 | goto inv_err; |
338 | wc.status = IB_WC_REM_INV_REQ_ERR; | ||
339 | goto err; | ||
340 | } | ||
341 | wc.wc_flags = IB_WC_WITH_IMM; | 344 | wc.wc_flags = IB_WC_WITH_IMM; |
342 | wc.imm_data = wqe->wr.ex.imm_data; | 345 | wc.imm_data = wqe->wr.ex.imm_data; |
343 | if (!ipath_get_rwqe(qp, 1)) | 346 | if (!ipath_get_rwqe(qp, 1)) |
344 | goto rnr_nak; | 347 | goto rnr_nak; |
345 | /* FALLTHROUGH */ | 348 | /* FALLTHROUGH */ |
346 | case IB_WR_RDMA_WRITE: | 349 | case IB_WR_RDMA_WRITE: |
347 | if (unlikely(!(qp->qp_access_flags & | 350 | if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) |
348 | IB_ACCESS_REMOTE_WRITE))) { | 351 | goto inv_err; |
349 | wc.status = IB_WC_REM_INV_REQ_ERR; | ||
350 | goto err; | ||
351 | } | ||
352 | if (wqe->length == 0) | 352 | if (wqe->length == 0) |
353 | break; | 353 | break; |
354 | if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length, | 354 | if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length, |
355 | wqe->wr.wr.rdma.remote_addr, | 355 | wqe->wr.wr.rdma.remote_addr, |
356 | wqe->wr.wr.rdma.rkey, | 356 | wqe->wr.wr.rdma.rkey, |
357 | IB_ACCESS_REMOTE_WRITE))) { | 357 | IB_ACCESS_REMOTE_WRITE))) |
358 | acc_err: | 358 | goto acc_err; |
359 | wc.status = IB_WC_REM_ACCESS_ERR; | ||
360 | err: | ||
361 | wc.wr_id = wqe->wr.wr_id; | ||
362 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
363 | wc.vendor_err = 0; | ||
364 | wc.byte_len = 0; | ||
365 | wc.qp = &sqp->ibqp; | ||
366 | wc.src_qp = sqp->remote_qpn; | ||
367 | wc.pkey_index = 0; | ||
368 | wc.slid = sqp->remote_ah_attr.dlid; | ||
369 | wc.sl = sqp->remote_ah_attr.sl; | ||
370 | wc.dlid_path_bits = 0; | ||
371 | wc.port_num = 0; | ||
372 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
373 | ipath_sqerror_qp(sqp, &wc); | ||
374 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
375 | goto done; | ||
376 | } | ||
377 | break; | 359 | break; |
378 | 360 | ||
379 | case IB_WR_RDMA_READ: | 361 | case IB_WR_RDMA_READ: |
380 | if (unlikely(!(qp->qp_access_flags & | 362 | if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ))) |
381 | IB_ACCESS_REMOTE_READ))) { | 363 | goto inv_err; |
382 | wc.status = IB_WC_REM_INV_REQ_ERR; | ||
383 | goto err; | ||
384 | } | ||
385 | if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length, | 364 | if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length, |
386 | wqe->wr.wr.rdma.remote_addr, | 365 | wqe->wr.wr.rdma.remote_addr, |
387 | wqe->wr.wr.rdma.rkey, | 366 | wqe->wr.wr.rdma.rkey, |
@@ -394,11 +373,8 @@ again: | |||
394 | 373 | ||
395 | case IB_WR_ATOMIC_CMP_AND_SWP: | 374 | case IB_WR_ATOMIC_CMP_AND_SWP: |
396 | case IB_WR_ATOMIC_FETCH_AND_ADD: | 375 | case IB_WR_ATOMIC_FETCH_AND_ADD: |
397 | if (unlikely(!(qp->qp_access_flags & | 376 | if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) |
398 | IB_ACCESS_REMOTE_ATOMIC))) { | 377 | goto inv_err; |
399 | wc.status = IB_WC_REM_INV_REQ_ERR; | ||
400 | goto err; | ||
401 | } | ||
402 | if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64), | 378 | if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64), |
403 | wqe->wr.wr.atomic.remote_addr, | 379 | wqe->wr.wr.atomic.remote_addr, |
404 | wqe->wr.wr.atomic.rkey, | 380 | wqe->wr.wr.atomic.rkey, |
@@ -415,7 +391,8 @@ again: | |||
415 | goto send_comp; | 391 | goto send_comp; |
416 | 392 | ||
417 | default: | 393 | default: |
418 | goto done; | 394 | send_status = IB_WC_LOC_QP_OP_ERR; |
395 | goto serr; | ||
419 | } | 396 | } |
420 | 397 | ||
421 | sge = &sqp->s_sge.sge; | 398 | sge = &sqp->s_sge.sge; |
@@ -448,8 +425,7 @@ again: | |||
448 | sqp->s_len -= len; | 425 | sqp->s_len -= len; |
449 | } | 426 | } |
450 | 427 | ||
451 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE || | 428 | if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) |
452 | wqe->wr.opcode == IB_WR_RDMA_READ) | ||
453 | goto send_comp; | 429 | goto send_comp; |
454 | 430 | ||
455 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM) | 431 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM) |
@@ -458,33 +434,89 @@ again: | |||
458 | wc.opcode = IB_WC_RECV; | 434 | wc.opcode = IB_WC_RECV; |
459 | wc.wr_id = qp->r_wr_id; | 435 | wc.wr_id = qp->r_wr_id; |
460 | wc.status = IB_WC_SUCCESS; | 436 | wc.status = IB_WC_SUCCESS; |
461 | wc.vendor_err = 0; | ||
462 | wc.byte_len = wqe->length; | 437 | wc.byte_len = wqe->length; |
463 | wc.qp = &qp->ibqp; | 438 | wc.qp = &qp->ibqp; |
464 | wc.src_qp = qp->remote_qpn; | 439 | wc.src_qp = qp->remote_qpn; |
465 | wc.pkey_index = 0; | ||
466 | wc.slid = qp->remote_ah_attr.dlid; | 440 | wc.slid = qp->remote_ah_attr.dlid; |
467 | wc.sl = qp->remote_ah_attr.sl; | 441 | wc.sl = qp->remote_ah_attr.sl; |
468 | wc.dlid_path_bits = 0; | ||
469 | wc.port_num = 1; | 442 | wc.port_num = 1; |
470 | /* Signal completion event if the solicited bit is set. */ | 443 | /* Signal completion event if the solicited bit is set. */ |
471 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | 444 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
472 | wqe->wr.send_flags & IB_SEND_SOLICITED); | 445 | wqe->wr.send_flags & IB_SEND_SOLICITED); |
473 | 446 | ||
474 | send_comp: | 447 | send_comp: |
448 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
449 | flush_send: | ||
475 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; | 450 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; |
476 | ipath_send_complete(sqp, wqe, IB_WC_SUCCESS); | 451 | ipath_send_complete(sqp, wqe, send_status); |
477 | goto again; | 452 | goto again; |
478 | 453 | ||
454 | rnr_nak: | ||
455 | /* Handle RNR NAK */ | ||
456 | if (qp->ibqp.qp_type == IB_QPT_UC) | ||
457 | goto send_comp; | ||
458 | /* | ||
459 | * Note: we don't need the s_lock held since the BUSY flag | ||
460 | * makes this single threaded. | ||
461 | */ | ||
462 | if (sqp->s_rnr_retry == 0) { | ||
463 | send_status = IB_WC_RNR_RETRY_EXC_ERR; | ||
464 | goto serr; | ||
465 | } | ||
466 | if (sqp->s_rnr_retry_cnt < 7) | ||
467 | sqp->s_rnr_retry--; | ||
468 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
469 | if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_RECV_OK)) | ||
470 | goto clr_busy; | ||
471 | sqp->s_flags |= IPATH_S_WAITING; | ||
472 | dev->n_rnr_naks++; | ||
473 | sqp->s_rnr_timeout = ib_ipath_rnr_table[qp->r_min_rnr_timer]; | ||
474 | ipath_insert_rnr_queue(sqp); | ||
475 | goto clr_busy; | ||
476 | |||
477 | inv_err: | ||
478 | send_status = IB_WC_REM_INV_REQ_ERR; | ||
479 | wc.status = IB_WC_LOC_QP_OP_ERR; | ||
480 | goto err; | ||
481 | |||
482 | acc_err: | ||
483 | send_status = IB_WC_REM_ACCESS_ERR; | ||
484 | wc.status = IB_WC_LOC_PROT_ERR; | ||
485 | err: | ||
486 | /* responder goes to error state */ | ||
487 | ipath_rc_error(qp, wc.status); | ||
488 | |||
489 | serr: | ||
490 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
491 | ipath_send_complete(sqp, wqe, send_status); | ||
492 | if (sqp->ibqp.qp_type == IB_QPT_RC) { | ||
493 | int lastwqe = ipath_error_qp(sqp, IB_WC_WR_FLUSH_ERR); | ||
494 | |||
495 | sqp->s_flags &= ~IPATH_S_BUSY; | ||
496 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
497 | if (lastwqe) { | ||
498 | struct ib_event ev; | ||
499 | |||
500 | ev.device = sqp->ibqp.device; | ||
501 | ev.element.qp = &sqp->ibqp; | ||
502 | ev.event = IB_EVENT_QP_LAST_WQE_REACHED; | ||
503 | sqp->ibqp.event_handler(&ev, sqp->ibqp.qp_context); | ||
504 | } | ||
505 | goto done; | ||
506 | } | ||
507 | clr_busy: | ||
508 | sqp->s_flags &= ~IPATH_S_BUSY; | ||
509 | unlock: | ||
510 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
479 | done: | 511 | done: |
480 | if (atomic_dec_and_test(&qp->refcount)) | 512 | if (qp && atomic_dec_and_test(&qp->refcount)) |
481 | wake_up(&qp->wait); | 513 | wake_up(&qp->wait); |
482 | } | 514 | } |
483 | 515 | ||
484 | static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp) | 516 | static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp) |
485 | { | 517 | { |
486 | if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) || | 518 | if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) || |
487 | qp->ibqp.qp_type == IB_QPT_SMI) { | 519 | qp->ibqp.qp_type == IB_QPT_SMI) { |
488 | unsigned long flags; | 520 | unsigned long flags; |
489 | 521 | ||
490 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | 522 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
@@ -502,26 +534,36 @@ static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp) | |||
502 | * @dev: the device we ran out of buffers on | 534 | * @dev: the device we ran out of buffers on |
503 | * | 535 | * |
504 | * Called when we run out of PIO buffers. | 536 | * Called when we run out of PIO buffers. |
537 | * If we are now in the error state, return zero to flush the | ||
538 | * send work request. | ||
505 | */ | 539 | */ |
506 | static void ipath_no_bufs_available(struct ipath_qp *qp, | 540 | static int ipath_no_bufs_available(struct ipath_qp *qp, |
507 | struct ipath_ibdev *dev) | 541 | struct ipath_ibdev *dev) |
508 | { | 542 | { |
509 | unsigned long flags; | 543 | unsigned long flags; |
544 | int ret = 1; | ||
510 | 545 | ||
511 | /* | 546 | /* |
512 | * Note that as soon as want_buffer() is called and | 547 | * Note that as soon as want_buffer() is called and |
513 | * possibly before it returns, ipath_ib_piobufavail() | 548 | * possibly before it returns, ipath_ib_piobufavail() |
514 | * could be called. If we are still in the tasklet function, | 549 | * could be called. Therefore, put QP on the piowait list before |
515 | * tasklet_hi_schedule() will not call us until the next time | 550 | * enabling the PIO avail interrupt. |
516 | * tasklet_hi_schedule() is called. | ||
517 | * We leave the busy flag set so that another post send doesn't | ||
518 | * try to put the same QP on the piowait list again. | ||
519 | */ | 551 | */ |
520 | spin_lock_irqsave(&dev->pending_lock, flags); | 552 | spin_lock_irqsave(&qp->s_lock, flags); |
521 | list_add_tail(&qp->piowait, &dev->piowait); | 553 | if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) { |
522 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 554 | dev->n_piowait++; |
523 | want_buffer(dev->dd, qp); | 555 | qp->s_flags |= IPATH_S_WAITING; |
524 | dev->n_piowait++; | 556 | qp->s_flags &= ~IPATH_S_BUSY; |
557 | spin_lock(&dev->pending_lock); | ||
558 | if (list_empty(&qp->piowait)) | ||
559 | list_add_tail(&qp->piowait, &dev->piowait); | ||
560 | spin_unlock(&dev->pending_lock); | ||
561 | } else | ||
562 | ret = 0; | ||
563 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
564 | if (ret) | ||
565 | want_buffer(dev->dd, qp); | ||
566 | return ret; | ||
525 | } | 567 | } |
526 | 568 | ||
527 | /** | 569 | /** |
@@ -597,15 +639,13 @@ void ipath_do_send(unsigned long data) | |||
597 | struct ipath_qp *qp = (struct ipath_qp *)data; | 639 | struct ipath_qp *qp = (struct ipath_qp *)data; |
598 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 640 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
599 | int (*make_req)(struct ipath_qp *qp); | 641 | int (*make_req)(struct ipath_qp *qp); |
600 | 642 | unsigned long flags; | |
601 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) | ||
602 | goto bail; | ||
603 | 643 | ||
604 | if ((qp->ibqp.qp_type == IB_QPT_RC || | 644 | if ((qp->ibqp.qp_type == IB_QPT_RC || |
605 | qp->ibqp.qp_type == IB_QPT_UC) && | 645 | qp->ibqp.qp_type == IB_QPT_UC) && |
606 | qp->remote_ah_attr.dlid == dev->dd->ipath_lid) { | 646 | qp->remote_ah_attr.dlid == dev->dd->ipath_lid) { |
607 | ipath_ruc_loopback(qp); | 647 | ipath_ruc_loopback(qp); |
608 | goto clear; | 648 | goto bail; |
609 | } | 649 | } |
610 | 650 | ||
611 | if (qp->ibqp.qp_type == IB_QPT_RC) | 651 | if (qp->ibqp.qp_type == IB_QPT_RC) |
@@ -615,6 +655,19 @@ void ipath_do_send(unsigned long data) | |||
615 | else | 655 | else |
616 | make_req = ipath_make_ud_req; | 656 | make_req = ipath_make_ud_req; |
617 | 657 | ||
658 | spin_lock_irqsave(&qp->s_lock, flags); | ||
659 | |||
660 | /* Return if we are already busy processing a work request. */ | ||
661 | if ((qp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) || | ||
662 | !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) { | ||
663 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
664 | goto bail; | ||
665 | } | ||
666 | |||
667 | qp->s_flags |= IPATH_S_BUSY; | ||
668 | |||
669 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
670 | |||
618 | again: | 671 | again: |
619 | /* Check for a constructed packet to be sent. */ | 672 | /* Check for a constructed packet to be sent. */ |
620 | if (qp->s_hdrwords != 0) { | 673 | if (qp->s_hdrwords != 0) { |
@@ -624,8 +677,8 @@ again: | |||
624 | */ | 677 | */ |
625 | if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, | 678 | if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, |
626 | qp->s_cur_sge, qp->s_cur_size)) { | 679 | qp->s_cur_sge, qp->s_cur_size)) { |
627 | ipath_no_bufs_available(qp, dev); | 680 | if (ipath_no_bufs_available(qp, dev)) |
628 | goto bail; | 681 | goto bail; |
629 | } | 682 | } |
630 | dev->n_unicast_xmit++; | 683 | dev->n_unicast_xmit++; |
631 | /* Record that we sent the packet and s_hdr is empty. */ | 684 | /* Record that we sent the packet and s_hdr is empty. */ |
@@ -634,16 +687,20 @@ again: | |||
634 | 687 | ||
635 | if (make_req(qp)) | 688 | if (make_req(qp)) |
636 | goto again; | 689 | goto again; |
637 | clear: | 690 | |
638 | clear_bit(IPATH_S_BUSY, &qp->s_busy); | ||
639 | bail:; | 691 | bail:; |
640 | } | 692 | } |
641 | 693 | ||
694 | /* | ||
695 | * This should be called with s_lock held. | ||
696 | */ | ||
642 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, | 697 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, |
643 | enum ib_wc_status status) | 698 | enum ib_wc_status status) |
644 | { | 699 | { |
645 | unsigned long flags; | 700 | u32 old_last, last; |
646 | u32 last; | 701 | |
702 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) | ||
703 | return; | ||
647 | 704 | ||
648 | /* See ch. 11.2.4.1 and 10.7.3.1 */ | 705 | /* See ch. 11.2.4.1 and 10.7.3.1 */ |
649 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | 706 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || |
@@ -651,27 +708,25 @@ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, | |||
651 | status != IB_WC_SUCCESS) { | 708 | status != IB_WC_SUCCESS) { |
652 | struct ib_wc wc; | 709 | struct ib_wc wc; |
653 | 710 | ||
711 | memset(&wc, 0, sizeof wc); | ||
654 | wc.wr_id = wqe->wr.wr_id; | 712 | wc.wr_id = wqe->wr.wr_id; |
655 | wc.status = status; | 713 | wc.status = status; |
656 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | 714 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; |
657 | wc.vendor_err = 0; | ||
658 | wc.byte_len = wqe->length; | ||
659 | wc.imm_data = 0; | ||
660 | wc.qp = &qp->ibqp; | 715 | wc.qp = &qp->ibqp; |
661 | wc.src_qp = 0; | 716 | if (status == IB_WC_SUCCESS) |
662 | wc.wc_flags = 0; | 717 | wc.byte_len = wqe->length; |
663 | wc.pkey_index = 0; | 718 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, |
664 | wc.slid = 0; | 719 | status != IB_WC_SUCCESS); |
665 | wc.sl = 0; | ||
666 | wc.dlid_path_bits = 0; | ||
667 | wc.port_num = 0; | ||
668 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
669 | } | 720 | } |
670 | 721 | ||
671 | spin_lock_irqsave(&qp->s_lock, flags); | 722 | old_last = last = qp->s_last; |
672 | last = qp->s_last; | ||
673 | if (++last >= qp->s_size) | 723 | if (++last >= qp->s_size) |
674 | last = 0; | 724 | last = 0; |
675 | qp->s_last = last; | 725 | qp->s_last = last; |
676 | spin_unlock_irqrestore(&qp->s_lock, flags); | 726 | if (qp->s_cur == old_last) |
727 | qp->s_cur = last; | ||
728 | if (qp->s_tail == old_last) | ||
729 | qp->s_tail = last; | ||
730 | if (qp->state == IB_QPS_SQD && last == qp->s_cur) | ||
731 | qp->s_draining = 0; | ||
677 | } | 732 | } |