diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-20 20:26:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-20 20:26:01 -0400 |
commit | d2228e4310612a1289c343bcf819831a74ae0366 (patch) | |
tree | c6a5e4a3cfd51c7080f98140bc97ae5dccdca5ac /drivers/infiniband | |
parent | 8f4ce072bf4b65f47dada7e74e3d95cc900866b2 (diff) | |
parent | 524630d5824c7a75aab568c6bd1423fd748cd3bb (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.c | 25 |
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 | |||
65 | isert_rdma_accept(struct isert_conn *isert_conn); | 65 | isert_rdma_accept(struct isert_conn *isert_conn); |
66 | struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); | 66 | struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); |
67 | 67 | ||
68 | static void isert_release_work(struct work_struct *work); | ||
69 | |||
68 | static inline bool | 70 | static inline bool |
69 | isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) | 71 | isert_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 | ||
653 | static void | 656 | static 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 | |||
957 | out: | ||
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 | ||
2413 | static int | 2432 | static 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 | ||