[Open-FCoE] [PATCH] libfc: fc_exch_timeout runs in process context

Robert Love robert.w.love at intel.com
Wed Oct 15 16:25:07 UTC 2008


Since this thread will call into the lport which will lock
a mutex it can't be in irq context. This patch switches
it from a timer to work thread.

Signed-off-by: Robert Love <robert.w.love at intel.com>
---

 drivers/scsi/libfc/fc_exch.c |   25 ++++++++++++++-----------
 1 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 06e6236..0531c7c 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -86,7 +86,7 @@ struct fc_exch {
 	struct list_head	ex_list;	/* free or busy list linkage */
 	spinlock_t	ex_lock;	/* lock covering exchange state */
 	atomic_t	ex_refcnt;	/* reference counter */
-	struct timer_list ex_timer;	/* timer for upper level protocols */
+	struct delayed_work timeout_work; /* timer for upper level protocols */
 	struct fc_lport	*lp;		/* fc device instance */
 	u16		oxid;		/* originator's exchange ID */
 	u16		rxid;		/* responder's exchange ID */
@@ -310,7 +310,6 @@ static void fc_exch_release(struct fc_exch *ep)
 		if (ep->lp->tt.exch_put)
 			ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
 		WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE);
-		WARN_ON(timer_pending(&ep->ex_timer));
 		mempool_free(ep, mp->ep_pool);
 	}
 }
@@ -332,7 +331,7 @@ static int fc_exch_done_locked(struct fc_exch *ep)
 
 	if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
 		ep->state |= FC_EX_DONE;
-		if (del_timer(&ep->ex_timer))
+		if (cancel_delayed_work(&ep->timeout_work))
 			atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
 		rc = 0;
 	}
@@ -362,7 +361,8 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
 	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
 		return;
 
-	if (!mod_timer(&ep->ex_timer, jiffies + msecs_to_jiffies(timer_msec)))
+	if (schedule_delayed_work(&ep->timeout_work,
+				  jiffies + msecs_to_jiffies(timer_msec)))
 		fc_exch_hold(ep);		/* hold for timer */
 }
 
@@ -435,9 +435,10 @@ EXPORT_SYMBOL(fc_seq_exch_abort);
  * Exchange timeout - handle exchange timer expiration.
  * The timer will have been cancelled before this is called.
  */
-static void fc_exch_timeout(unsigned long ep_arg)
+static void fc_exch_timeout(struct work_struct *work)
 {
-	struct fc_exch *ep = (struct fc_exch *)ep_arg;
+	struct fc_exch *ep = container_of(work, struct fc_exch,
+					  timeout_work.work);
 	struct fc_seq *sp = &ep->seq;
 	void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
 	void *arg;
@@ -584,7 +585,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16 xid)
 	ep->f_ctl = FC_FC_FIRST_SEQ;	/* next seq is first seq */
 	ep->rxid = FC_XID_UNKNOWN;
 	ep->class = mp->class;
-	setup_timer(&ep->ex_timer, fc_exch_timeout, (unsigned long)ep);
+	INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
 out:
 	return ep;
 err:
@@ -1331,7 +1332,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
 		FC_DBG("exch: BLS rctl %x - %s\n",
 		       fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl));
 
-	if (del_timer_sync(&ep->ex_timer))
+	if (cancel_delayed_work_sync(&ep->timeout_work))
 		fc_exch_release(ep);	/* release from pending timer hold */
 
 	spin_lock_bh(&ep->ex_lock);
@@ -1509,7 +1510,7 @@ static void fc_exch_reset(struct fc_exch *ep)
 	 * functions can also grab the lport lock which could cause
 	 * a deadlock).
 	 */
-	if (del_timer(&ep->ex_timer))
+	if (cancel_delayed_work(&ep->timeout_work))
 		atomic_dec(&ep->ex_refcnt);     /* drop hold for timer */
 	resp = ep->resp;
 	ep->resp = NULL;
@@ -1785,8 +1786,10 @@ static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
 		ep->esb_stat &= ~ESB_ST_REC_QUAL;
 		atomic_dec(&ep->ex_refcnt);	/* drop hold for rec qual */
 	}
-	if ((ep->esb_stat & ESB_ST_COMPLETE) && (del_timer(&ep->ex_timer)))
-		atomic_dec(&ep->ex_refcnt);	/* drop hold for timer */
+	if (ep->esb_stat & ESB_ST_COMPLETE) {
+		if (cancel_delayed_work(&ep->timeout_work))
+			atomic_dec(&ep->ex_refcnt);	/* drop hold for timer */
+	}
 
 	spin_unlock_bh(&ep->ex_lock);
 




More information about the devel mailing list