[ofa-general] [PATCH 2/2] IB/iser: iser_conn should not be released while its workqueue is active

Erez Zilber erezz at voltaire.com
Sun Mar 25 03:10:00 PDT 2007


When shutting down a connection, after there are no more posted
buffers, iSER schedules a workqueue that is used to notify the
iSCSI layer that the connection is down. Meanwhile, the connection
object (that holds the workqueue) is released. If the workqueue
function wasn't called yet, a NULL pointer will be referenced.

This fix waits until the workqueue function is called and only
then it releases the connection object.

Signed-off-by: Erez Zilber <erezz at voltaire.com>
---
 drivers/infiniband/ulp/iser/iscsi_iser.h |    1 +
 drivers/infiniband/ulp/iser/iser_verbs.c |    9 +++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index cae8c96..0e11f79 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -242,6 +242,7 @@ struct iser_conn {
 	struct ib_qp	             *qp;           /* QP 		       */
 	struct ib_fmr_pool           *fmr_pool;     /* pool of IB FMRs         */
 	int                          disc_evt_flag; /* disconn event delivered */
+	int                          wait_comp_error_work;
 	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
 	atomic_t                     post_recv_buf_count; /* posted rx count   */
 	atomic_t                     post_send_buf_count; /* posted tx count   */
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 693b770..dc2df33 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -331,7 +331,8 @@ void iser_conn_terminate(struct iser_con
 			 ib_conn,err);
 
 	wait_event_interruptible(ib_conn->wait,
-				 ib_conn->state == ISER_CONN_DOWN);
+				 ib_conn->state == ISER_CONN_DOWN &&
+				 ib_conn->wait_comp_error_work == 0);
 
 	iser_conn_release(ib_conn);
 }
@@ -771,6 +772,8 @@ static void iser_comp_error_worker(struc
 		ib_conn->state = ISER_CONN_DOWN;
 		wake_up_interruptible(&ib_conn->wait);
 	}
+
+	ib_conn->wait_comp_error_work = 0;
 }
 
 static void iser_handle_comp_error(struct iser_desc *desc)
@@ -791,8 +794,10 @@ static void iser_handle_comp_error(struc
 	}
 
 	if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
-	    atomic_read(&ib_conn->post_send_buf_count) == 0)
+	    atomic_read(&ib_conn->post_send_buf_count) == 0) {
+		ib_conn->wait_comp_error_work = 1;
 		schedule_work(&ib_conn->comperror_work);
+	}
 }
 
 static void iser_cq_tasklet_fn(unsigned long data)
-- 
1.4.2





More information about the general mailing list