This is a note to let you know that I've just added the patch titled

    iser-target: Fix connected_handler + teardown flow race

to the 3.10-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     iser-target-fix-connected_handler-teardown-flow-race.patch
and it can be found in the queue-3.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


>From n...@linux-iscsi.org  Tue Feb  3 15:08:27 2015
From: "Nicholas A. Bellinger" <n...@linux-iscsi.org>
Date: Fri, 30 Jan 2015 22:17:28 +0000
Subject: iser-target: Fix connected_handler + teardown flow race
To: target-devel <target-de...@vger.kernel.org>
Cc: Greg-KH <gre...@linuxfoundation.org>, stable <stable@vger.kernel.org>, Sagi 
Grimberg <sa...@mellanox.com>
Message-ID: <1422656251-29468-10-git-send-email-...@linux-iscsi.org>


From: Sagi Grimberg <sa...@mellanox.com>

commit 19e2090fb246ca21b3e569ead51a6a7a1748eadd upstream.

Take isert_conn pointer from cm_id->qp->qp_context. This
will allow us to know that the cm_id context is always
the network portal. This will make the cm_id event check
(connection or network portal) more reliable.

In order to avoid a NULL dereference in cma_id->qp->qp_context
we destroy the qp after we destroy the cm_id (and make the
dereference safe). session stablishment/teardown sequences
can happen in parallel, we should take into account that
connected_handler might race with connection teardown flow.

Also, protect isert_conn->conn_device->active_qps decrement
within the error patch during QP creation failure and the
normal teardown path in isert_connect_release().

Squashed:

iser-target: Decrement completion context active_qps in error flow

Signed-off-by: Sagi Grimberg <sa...@mellanox.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/infiniband/ulp/isert/ib_isert.c |   31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -132,12 +132,18 @@ isert_conn_setup_qp(struct isert_conn *i
        ret = rdma_create_qp(cma_id, isert_conn->conn_pd, &attr);
        if (ret) {
                pr_err("rdma_create_qp failed for cma_id %d\n", ret);
-               return ret;
+               goto err;
        }
        isert_conn->conn_qp = cma_id->qp;
        pr_debug("rdma_create_qp() returned success 
>>>>>>>>>>>>>>>>>>>>>>>>>.\n");
 
        return 0;
+err:
+       mutex_lock(&device_list_mutex);
+       device->cq_active_qps[min_index]--;
+       mutex_unlock(&device_list_mutex);
+
+       return ret;
 }
 
 static void
@@ -425,7 +431,6 @@ isert_connect_request(struct rdma_cm_id
        kref_init(&isert_conn->conn_kref);
        mutex_init(&isert_conn->conn_mutex);
 
-       cma_id->context = isert_conn;
        isert_conn->conn_cm_id = cma_id;
        isert_conn->responder_resources = event->param.conn.responder_resources;
        isert_conn->initiator_depth = event->param.conn.initiator_depth;
@@ -526,18 +531,20 @@ isert_connect_release(struct isert_conn
 
        pr_debug("Entering isert_connect_release(): 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
 
+       isert_free_rx_descriptors(isert_conn);
+       rdma_destroy_id(isert_conn->conn_cm_id);
+
        if (isert_conn->conn_qp) {
                cq_index = ((struct isert_cq_desc *)
                        isert_conn->conn_qp->recv_cq->cq_context)->cq_index;
                pr_debug("isert_connect_release: cq_index: %d\n", cq_index);
+               mutex_lock(&device_list_mutex);
                isert_conn->conn_device->cq_active_qps[cq_index]--;
+               mutex_unlock(&device_list_mutex);
 
-               rdma_destroy_qp(isert_conn->conn_cm_id);
+               ib_destroy_qp(isert_conn->conn_qp);
        }
 
-       isert_free_rx_descriptors(isert_conn);
-       rdma_destroy_id(isert_conn->conn_cm_id);
-
        if (isert_conn->login_buf) {
                ib_dma_unmap_single(ib_dev, isert_conn->login_rsp_dma,
                                    ISER_RX_LOGIN_SIZE, DMA_TO_DEVICE);
@@ -557,7 +564,7 @@ isert_connect_release(struct isert_conn
 static void
 isert_connected_handler(struct rdma_cm_id *cma_id)
 {
-       struct isert_conn *isert_conn = cma_id->context;
+       struct isert_conn *isert_conn = cma_id->qp->qp_context;
 
        pr_info("conn %p\n", isert_conn);
 
@@ -635,16 +642,16 @@ isert_conn_terminate(struct isert_conn *
 static int
 isert_disconnected_handler(struct rdma_cm_id *cma_id)
 {
+       struct iscsi_np *np = cma_id->context;
+       struct isert_np *isert_np = np->np_context;
        struct isert_conn *isert_conn;
 
-       if (!cma_id->qp) {
-               struct isert_np *isert_np = cma_id->context;
-
+       if (isert_np->np_cm_id == cma_id) {
                isert_np->np_cm_id = NULL;
                return -1;
        }
 
-       isert_conn = (struct isert_conn *)cma_id->context;
+       isert_conn = cma_id->qp->qp_context;
 
        mutex_lock(&isert_conn->conn_mutex);
        isert_conn_terminate(isert_conn);
@@ -659,7 +666,7 @@ isert_disconnected_handler(struct rdma_c
 static void
 isert_connect_error(struct rdma_cm_id *cma_id)
 {
-       struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;
+       struct isert_conn *isert_conn = cma_id->qp->qp_context;
 
        isert_put_conn(isert_conn);
 }


Patches currently in stable-queue which might be from n...@linux-iscsi.org are

queue-3.10/iser-target-fix-connected_handler-teardown-flow-race.patch
queue-3.10/iscsi-iser-target-initiate-termination-only-once.patch
queue-3.10/ib_isert-add-max_send_sge-2-minimum-for-control-pdu-responses.patch
queue-3.10/iser-target-fix-implicit-termination-of-connections.patch
queue-3.10/iser-target-parallelize-cm-connection-establishment.patch
queue-3.10/vhost-scsi-take-configfs-group-dependency-during-vhost_scsi_set_endpoint.patch
queue-3.10/ib-isert-adjust-cq-size-to-hw-limits.patch
queue-3.10/iser-target-handle-addr_change-event-for-listener-cm_id.patch
queue-3.10/vhost-scsi-add-missing-virtio-scsi-tcm-attribute-conversion.patch
queue-3.10/target-drop-arbitrary-maximum-i-o-size-limit.patch
queue-3.10/tcm_loop-fix-wrong-i_t-nexus-association.patch
queue-3.10/iser-target-fix-flush-disconnect-completion-handling.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to