aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-10-01 07:02:05 -0400
committerRoland Dreier <roland@purestorage.com>2014-10-09 03:06:06 -0400
commit8c204e69ced1a8c0d74f8b6d7a1393d055c5c4fa (patch)
treed005e8d3452fab29ba1894d8d9c1df6d3aee0670 /drivers/infiniband
parent3a940daf6fa105d28b69cf3b7a3739a3777f4185 (diff)
IB/iser: Signal iSCSI layer that transport is broken in error completions
Previously we notified iscsi layer about the connection layer when we consumed all of our flush errors. This was racy as there was no guarentee that iscsi_conn wasn't terminated by then (which ends up in an invalid memory access). In case we got a non FLUSH error completion, we are guarenteed that iscsi_conn is still alive. We should notify iSCSI layer with iscsi_conn_failure to initiate error handling. While we are at it, add a nice kernel-doc style documentation. Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Ariel Nahum <arieln@mellanox.com> Signed-off-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 6ce20fd9abac..35f53a3fdf21 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -1159,9 +1159,30 @@ int iser_post_send(struct ib_conn *ib_conn, struct iser_tx_desc *tx_desc)
1159 return ib_ret; 1159 return ib_ret;
1160} 1160}
1161 1161
1162static void iser_handle_comp_error(struct iser_tx_desc *desc, 1162/**
1163 struct ib_conn *ib_conn) 1163 * iser_handle_comp_error() - Handle error completion
1164 * @desc: iser TX descriptor
1165 * @ib_conn: connection RDMA resources
1166 * @wc: work completion
1167 *
1168 * Notes: We may handle a FLUSH error completion and in this case
1169 * we only cleanup in case TX type was DATAOUT. For non-FLUSH
1170 * error completion we should also notify iscsi layer that
1171 * connection is failed (in case we passed bind stage).
1172 */
1173static void
1174iser_handle_comp_error(struct iser_tx_desc *desc,
1175 struct ib_conn *ib_conn,
1176 struct ib_wc *wc)
1164{ 1177{
1178 struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn,
1179 ib_conn);
1180
1181 if (wc->status != IB_WC_WR_FLUSH_ERR)
1182 if (iser_conn->iscsi_conn)
1183 iscsi_conn_failure(iser_conn->iscsi_conn,
1184 ISCSI_ERR_CONN_FAILED);
1185
1165 if (desc && desc->type == ISCSI_TX_DATAOUT) 1186 if (desc && desc->type == ISCSI_TX_DATAOUT)
1166 kmem_cache_free(ig.desc_cache, desc); 1187 kmem_cache_free(ig.desc_cache, desc);
1167} 1188}
@@ -1188,7 +1209,7 @@ static int iser_drain_tx_cq(struct iser_device *device, int cq_index)
1188 wc.wr_id, wc.status, wc.vendor_err); 1209 wc.wr_id, wc.status, wc.vendor_err);
1189 if (wc.wr_id != ISER_FASTREG_LI_WRID) { 1210 if (wc.wr_id != ISER_FASTREG_LI_WRID) {
1190 atomic_dec(&ib_conn->post_send_buf_count); 1211 atomic_dec(&ib_conn->post_send_buf_count);
1191 iser_handle_comp_error(tx_desc, ib_conn); 1212 iser_handle_comp_error(tx_desc, ib_conn, &wc);
1192 } 1213 }
1193 } 1214 }
1194 completed_tx++; 1215 completed_tx++;
@@ -1230,7 +1251,7 @@ static void iser_cq_tasklet_fn(unsigned long data)
1230 iser_err("rx id %llx status %d vend_err %x\n", 1251 iser_err("rx id %llx status %d vend_err %x\n",
1231 wc.wr_id, wc.status, wc.vendor_err); 1252 wc.wr_id, wc.status, wc.vendor_err);
1232 ib_conn->post_recv_buf_count--; 1253 ib_conn->post_recv_buf_count--;
1233 iser_handle_comp_error(NULL, ib_conn); 1254 iser_handle_comp_error(NULL, ib_conn, &wc);
1234 } 1255 }
1235 completed_rx++; 1256 completed_rx++;
1236 if (!(completed_rx & 63)) 1257 if (!(completed_rx & 63))