diff options
author | Bart Van Assche <bvanassche@acm.org> | 2013-10-10 07:53:25 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-11-08 17:43:18 -0500 |
commit | cd4e38542a5c2cab94e5410fb17c1cc004a60792 (patch) | |
tree | 8b106206f51e379c120ca2e5e32f58706a713dd9 /drivers/infiniband | |
parent | 99b6697a50c2acbe3ca2772d359fc9a28835dc84 (diff) |
IB/srp: Report receive errors correctly
The IB spec does not guarantee that the opcode is available in error
completions. Hence do not rely on it. See also commit 948d1e889e5b
("IB/srp: Introduce srp_handle_qp_err()").
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: <stable@vger.kernel.org> # v3.8
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 4bf2f9feb59a..a88631918e85 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -1449,14 +1449,13 @@ static void srp_tl_err_work(struct work_struct *work) | |||
1449 | srp_start_tl_fail_timers(target->rport); | 1449 | srp_start_tl_fail_timers(target->rport); |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | static void srp_handle_qp_err(enum ib_wc_status wc_status, | 1452 | static void srp_handle_qp_err(enum ib_wc_status wc_status, bool send_err, |
1453 | enum ib_wc_opcode wc_opcode, | ||
1454 | struct srp_target_port *target) | 1453 | struct srp_target_port *target) |
1455 | { | 1454 | { |
1456 | if (target->connected && !target->qp_in_error) { | 1455 | if (target->connected && !target->qp_in_error) { |
1457 | shost_printk(KERN_ERR, target->scsi_host, | 1456 | shost_printk(KERN_ERR, target->scsi_host, |
1458 | PFX "failed %s status %d\n", | 1457 | PFX "failed %s status %d\n", |
1459 | wc_opcode & IB_WC_RECV ? "receive" : "send", | 1458 | send_err ? "send" : "receive", |
1460 | wc_status); | 1459 | wc_status); |
1461 | queue_work(system_long_wq, &target->tl_err_work); | 1460 | queue_work(system_long_wq, &target->tl_err_work); |
1462 | } | 1461 | } |
@@ -1473,7 +1472,7 @@ static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) | |||
1473 | if (likely(wc.status == IB_WC_SUCCESS)) { | 1472 | if (likely(wc.status == IB_WC_SUCCESS)) { |
1474 | srp_handle_recv(target, &wc); | 1473 | srp_handle_recv(target, &wc); |
1475 | } else { | 1474 | } else { |
1476 | srp_handle_qp_err(wc.status, wc.opcode, target); | 1475 | srp_handle_qp_err(wc.status, false, target); |
1477 | } | 1476 | } |
1478 | } | 1477 | } |
1479 | } | 1478 | } |
@@ -1489,7 +1488,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) | |||
1489 | iu = (struct srp_iu *) (uintptr_t) wc.wr_id; | 1488 | iu = (struct srp_iu *) (uintptr_t) wc.wr_id; |
1490 | list_add(&iu->list, &target->free_tx); | 1489 | list_add(&iu->list, &target->free_tx); |
1491 | } else { | 1490 | } else { |
1492 | srp_handle_qp_err(wc.status, wc.opcode, target); | 1491 | srp_handle_qp_err(wc.status, true, target); |
1493 | } | 1492 | } |
1494 | } | 1493 | } |
1495 | } | 1494 | } |