[Open-FCoE] [PATCH 16/28] libfc: fc_lport_timeout run from a work thread

Robert Love robert.w.love at intel.com
Tue Sep 30 18:26:13 UTC 2008


Start the lport timout handler from a work thread so that we're
in process context and can sleep when using mutexes.

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

 drivers/scsi/libfc/fc_lport.c |   19 +++++++++++--------
 drivers/scsi/libfc/fc_ns.c    |    9 +++++----
 include/scsi/libfc/libfc.h    |    3 +--
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index f1dde34..d810a7c 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -565,8 +565,9 @@ static void fc_lport_retry(struct fc_lport *lp)
 		       "- will retry\n", lp->fid, fc_lport_state(lp));
 	if (lp->retry_count < lp->max_retry_count) {
 		lp->retry_count++;
-		mod_timer(&lp->state_timer,
-			  jiffies + msecs_to_jiffies(lp->e_d_tov));
+		schedule_delayed_work(&lp->retry_work,
+				      jiffies +
+				      msecs_to_jiffies(lp->e_d_tov));
 	} else {
 		FC_DBG("local port %6x alloc failure in state %s "
 		       "- retries exhausted\n", lp->fid,
@@ -789,13 +790,15 @@ static void fc_lport_error(struct fc_lport *lp, struct fc_frame *fp)
 	fc_lport_unlock(lp);
 }
 
-static void fc_lport_timeout(unsigned long lp_arg)
+static void fc_lport_timeout(struct work_struct *work)
 {
-	struct fc_lport *lp = (struct fc_lport *)lp_arg;
+	struct fc_lport *lport =
+		container_of(work, struct fc_lport,
+			     retry_work.work);
 
-	fc_lport_lock(lp);
-	fc_lport_enter_retry(lp);
-	fc_lport_unlock(lp);
+	fc_lport_lock(lport);
+	fc_lport_enter_retry(lport);
+	fc_lport_unlock(lport);
 }
 
 static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
@@ -971,7 +974,7 @@ void fc_lport_enter_flogi(struct fc_lport *lp)
 /* Configure a fc_lport */
 int fc_lport_config(struct fc_lport *lp)
 {
-	setup_timer(&lp->state_timer, fc_lport_timeout, (unsigned long)lp);
+	INIT_DELAYED_WORK(&lp->retry_work, fc_lport_timeout);
 	spin_lock_init(&lp->state_lock);
 
 	fc_lport_lock(lp);
diff --git a/drivers/scsi/libfc/fc_ns.c b/drivers/scsi/libfc/fc_ns.c
index 1f03b01..aa846dc 100644
--- a/drivers/scsi/libfc/fc_ns.c
+++ b/drivers/scsi/libfc/fc_ns.c
@@ -400,8 +400,9 @@ static void fc_ns_retry(struct fc_lport *lp)
 		       "- will retry\n", lp->fid);
 	if (lp->retry_count < lp->max_retry_count) {
 		lp->retry_count++;
-		mod_timer(&lp->state_timer,
-			  jiffies + msecs_to_jiffies(lp->e_d_tov));
+		schedule_delayed_work(&lp->retry_work,
+				      jiffies +
+				      msecs_to_jiffies(lp->e_d_tov));
 	} else {
 		FC_DBG("local port %6x alloc failure "
 		       "- retries exhausted\n", lp->fid);
@@ -481,7 +482,7 @@ fc_ns_resp(struct fc_seq *sp, struct fc_frame *fp, void *lp_arg)
 
 	if (!IS_ERR(fp)) {
 		fc_lport_lock(lp);
-		del_timer(&lp->state_timer);
+		cancel_delayed_work_sync(&lp->retry_work);
 		if (fc_lport_dns_acc(fp)) {
 			if (lp->state == LPORT_ST_REG_PN)
 				fc_ns_enter_reg_ft(lp);
@@ -883,7 +884,7 @@ static void fc_ns_enter_dns(struct fc_lport *lp)
 		rp->event_callback = lp->tt.event_callback;
 		lp->tt.rport_login(rport);
 	} else {
-		del_timer(&lp->state_timer);
+		cancel_delayed_work_sync(&lp->retry_work);
 		fc_ns_enter_reg_pn(lp);
 	}
 	return;
diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
index b6fe5f1..8af4c2a 100644
--- a/include/scsi/libfc/libfc.h
+++ b/include/scsi/libfc/libfc.h
@@ -467,7 +467,7 @@ struct fc_lport {
 
 	/* Miscellaneous */
 	struct fc_gpn_ft_resp	ns_disc_buf;	/* partial name buffer */
-	struct timer_list	state_timer;	/* timer for state events */
+	struct delayed_work	retry_work;
 	struct delayed_work	ns_disc_work;
 
 	void			*drv_priv;
@@ -540,7 +540,6 @@ static inline void fc_lport_state_enter(struct fc_lport *lp,
 					enum fc_lport_state state)
 {
 	WARN_ON(!fc_lport_locked(lp));
-	del_timer(&lp->state_timer);
 	if (state != lp->state)
 		lp->retry_count = 0;
 	lp->state = state;




More information about the devel mailing list