Erez Zilber wrote:
> Roland,
> 
> Or & I found a bug in this patch. I hope to send a fix for it in the
> next few days. Meanwhile, please don't merge it.
> 

Roland, Mike,

The following patch replaces the bad patch (iser_conn should not be released 
while its workqueue is active) that I sent a few days ago. Again, if it's 
possible, I'd like to have it merged into 2.6.21 (it is a bug fix).


When a connection is terminated asynchronously from the iSCSI layer's 
perspective,
iSER needs to notify the iSCSI layer that the connection has failed. This was
done using a workqueue (switched to from a tasklet context). The context switch 
is
not required, and everything can be done from the iSER tasklet.

Signed-off-by: Erez Zilber <[EMAIL PROTECTED]>
---
 drivers/infiniband/ulp/iser/iscsi_iser.h |    1 -
 drivers/infiniband/ulp/iser/iser_verbs.c |   40 ++++++++++++------------------
 2 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h 
b/drivers/infiniband/ulp/iser/iscsi_iser.h
index cae8c96..8960196 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -245,7 +245,6 @@ struct iser_conn {
        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   
*/
-       struct work_struct           comperror_work; /* conn term sleepable 
ctx*/
        char                         name[ISER_OBJECT_NAME_SIZE];
        struct iser_page_vec         *page_vec;     /* represents SG to fmr 
maps*
                                                     * maps serialized as tx 
is*/
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c 
b/drivers/infiniband/ulp/iser/iser_verbs.c
index 693b770..1fc9674 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -48,7 +48,6 @@ #define ISER_MAX_CQ_LEN               ((ISER_QP_MAX_R
 
 static void iser_cq_tasklet_fn(unsigned long data);
 static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
-static void iser_comp_error_worker(struct work_struct *work);
 
 static void iser_cq_event_callback(struct ib_event *cause, void *context)
 {
@@ -480,7 +479,6 @@ int iser_conn_init(struct iser_conn **ib
        init_waitqueue_head(&ib_conn->wait);
        atomic_set(&ib_conn->post_recv_buf_count, 0);
        atomic_set(&ib_conn->post_send_buf_count, 0);
-       INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker);
        INIT_LIST_HEAD(&ib_conn->conn_list);
        spin_lock_init(&ib_conn->lock);
 
@@ -753,26 +751,6 @@ int iser_post_send(struct iser_desc *tx_
        return ret_val;
 }
 
-static void iser_comp_error_worker(struct work_struct *work)
-{
-       struct iser_conn *ib_conn =
-               container_of(work, struct iser_conn, comperror_work);
-
-       /* getting here when the state is UP means that the conn is being *
-        * terminated asynchronously from the iSCSI layer's perspective.  */
-       if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
-                                     ISER_CONN_TERMINATING))
-               iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
-                                       ISCSI_ERR_CONN_FAILED);
-
-       /* complete the termination process if disconnect event was delivered *
-        * note there are no more non completed posts to the QP               */
-       if (ib_conn->disc_evt_flag) {
-               ib_conn->state = ISER_CONN_DOWN;
-               wake_up_interruptible(&ib_conn->wait);
-       }
-}
-
 static void iser_handle_comp_error(struct iser_desc *desc)
 {
        struct iser_dto  *dto     = &desc->dto;
@@ -791,8 +769,22 @@ 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)
-               schedule_work(&ib_conn->comperror_work);
+           atomic_read(&ib_conn->post_send_buf_count) == 0) {
+               /* getting here when the state is UP means that the conn is *
+                * being terminated asynchronously from the iSCSI layer's   *
+                * perspective.                                             */
+               if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
+                   ISER_CONN_TERMINATING))
+                       iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
+                                          ISCSI_ERR_CONN_FAILED);
+
+               /* complete the termination process if disconnect event was 
delivered *
+                * note there are no more non completed posts to the QP         
      */
+               if (ib_conn->disc_evt_flag) {
+                       ib_conn->state = ISER_CONN_DOWN;
+                       wake_up_interruptible(&ib_conn->wait);
+               }
+       }
 }
 
 static void iser_cq_tasklet_fn(unsigned long data)
-- 
1.4.2



_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to