aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-20 20:26:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-20 20:26:01 -0400
commitd2228e4310612a1289c343bcf819831a74ae0366 (patch)
treec6a5e4a3cfd51c7080f98140bc97ae5dccdca5ac /drivers/infiniband
parent8f4ce072bf4b65f47dada7e74e3d95cc900866b2 (diff)
parent524630d5824c7a75aab568c6bd1423fd748cd3bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull scsi target fixes from Nicholas Bellinger: "Apologies for the late pull request. Here are the outstanding target-pending fixes for v4.1 code. The series contains three patches from Sagi + Co that address a few iser-target issues that have been uncovered during recent testing at Mellanox. Patch #1 has a v3.16+ stable tag, and #2-3 have v3.10+ stable tags" * git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: iser-target: Fix possible use-after-free iser-target: release stale iser connections iser-target: Fix variable-length response error completion
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 3f40319a55da..575a072d765f 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -65,6 +65,8 @@ static int
65isert_rdma_accept(struct isert_conn *isert_conn); 65isert_rdma_accept(struct isert_conn *isert_conn);
66struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); 66struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
67 67
68static void isert_release_work(struct work_struct *work);
69
68static inline bool 70static inline bool
69isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) 71isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
70{ 72{
@@ -648,6 +650,7 @@ isert_init_conn(struct isert_conn *isert_conn)
648 mutex_init(&isert_conn->mutex); 650 mutex_init(&isert_conn->mutex);
649 spin_lock_init(&isert_conn->pool_lock); 651 spin_lock_init(&isert_conn->pool_lock);
650 INIT_LIST_HEAD(&isert_conn->fr_pool); 652 INIT_LIST_HEAD(&isert_conn->fr_pool);
653 INIT_WORK(&isert_conn->release_work, isert_release_work);
651} 654}
652 655
653static void 656static void
@@ -925,6 +928,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
925{ 928{
926 struct isert_np *isert_np = cma_id->context; 929 struct isert_np *isert_np = cma_id->context;
927 struct isert_conn *isert_conn; 930 struct isert_conn *isert_conn;
931 bool terminating = false;
928 932
929 if (isert_np->np_cm_id == cma_id) 933 if (isert_np->np_cm_id == cma_id)
930 return isert_np_cma_handler(cma_id->context, event); 934 return isert_np_cma_handler(cma_id->context, event);
@@ -932,12 +936,25 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
932 isert_conn = cma_id->qp->qp_context; 936 isert_conn = cma_id->qp->qp_context;
933 937
934 mutex_lock(&isert_conn->mutex); 938 mutex_lock(&isert_conn->mutex);
939 terminating = (isert_conn->state == ISER_CONN_TERMINATING);
935 isert_conn_terminate(isert_conn); 940 isert_conn_terminate(isert_conn);
936 mutex_unlock(&isert_conn->mutex); 941 mutex_unlock(&isert_conn->mutex);
937 942
938 isert_info("conn %p completing wait\n", isert_conn); 943 isert_info("conn %p completing wait\n", isert_conn);
939 complete(&isert_conn->wait); 944 complete(&isert_conn->wait);
940 945
946 if (terminating)
947 goto out;
948
949 mutex_lock(&isert_np->np_accept_mutex);
950 if (!list_empty(&isert_conn->accept_node)) {
951 list_del_init(&isert_conn->accept_node);
952 isert_put_conn(isert_conn);
953 queue_work(isert_release_wq, &isert_conn->release_work);
954 }
955 mutex_unlock(&isert_np->np_accept_mutex);
956
957out:
941 return 0; 958 return 0;
942} 959}
943 960
@@ -2380,7 +2397,6 @@ isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
2380 page_off = offset % PAGE_SIZE; 2397 page_off = offset % PAGE_SIZE;
2381 2398
2382 send_wr->sg_list = ib_sge; 2399 send_wr->sg_list = ib_sge;
2383 send_wr->num_sge = sg_nents;
2384 send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc; 2400 send_wr->wr_id = (uintptr_t)&isert_cmd->tx_desc;
2385 /* 2401 /*
2386 * Perform mapping of TCM scatterlist memory ib_sge dma_addr. 2402 * Perform mapping of TCM scatterlist memory ib_sge dma_addr.
@@ -2400,14 +2416,17 @@ isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
2400 ib_sge->addr, ib_sge->length, ib_sge->lkey); 2416 ib_sge->addr, ib_sge->length, ib_sge->lkey);
2401 page_off = 0; 2417 page_off = 0;
2402 data_left -= ib_sge->length; 2418 data_left -= ib_sge->length;
2419 if (!data_left)
2420 break;
2403 ib_sge++; 2421 ib_sge++;
2404 isert_dbg("Incrementing ib_sge pointer to %p\n", ib_sge); 2422 isert_dbg("Incrementing ib_sge pointer to %p\n", ib_sge);
2405 } 2423 }
2406 2424
2425 send_wr->num_sge = ++i;
2407 isert_dbg("Set outgoing sg_list: %p num_sg: %u from TCM SGLs\n", 2426 isert_dbg("Set outgoing sg_list: %p num_sg: %u from TCM SGLs\n",
2408 send_wr->sg_list, send_wr->num_sge); 2427 send_wr->sg_list, send_wr->num_sge);
2409 2428
2410 return sg_nents; 2429 return send_wr->num_sge;
2411} 2430}
2412 2431
2413static int 2432static int
@@ -3366,7 +3385,6 @@ static void isert_wait_conn(struct iscsi_conn *conn)
3366 isert_wait4flush(isert_conn); 3385 isert_wait4flush(isert_conn);
3367 isert_wait4logout(isert_conn); 3386 isert_wait4logout(isert_conn);
3368 3387
3369 INIT_WORK(&isert_conn->release_work, isert_release_work);
3370 queue_work(isert_release_wq, &isert_conn->release_work); 3388 queue_work(isert_release_wq, &isert_conn->release_work);
3371} 3389}
3372 3390
@@ -3374,6 +3392,7 @@ static void isert_free_conn(struct iscsi_conn *conn)
3374{ 3392{
3375 struct isert_conn *isert_conn = conn->context; 3393 struct isert_conn *isert_conn = conn->context;
3376 3394
3395 isert_wait4flush(isert_conn);
3377 isert_put_conn(isert_conn); 3396 isert_put_conn(isert_conn);
3378} 3397}
3379 3398