[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