[Open-FCoE] [RFC PATCH 25/28] libfc: consolodate all retrying into fc_lport_error

Robert Love robert.w.love at intel.com
Thu Sep 11 23:37:22 UTC 2008


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

 drivers/scsi/libfc/fc_lport.c |  155 ++++++++++++++++++-----------------------
 1 files changed, 67 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index c15e37c..4856f5b 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -36,6 +36,8 @@
 
 static int fc_lport_debug;
 
+static void fc_lport_error(struct fc_lport *, struct fc_frame *);
+
 static void fc_lport_enter_flogi(struct fc_lport *);
 static void fc_lport_enter_dns(struct fc_lport *);
 static void fc_lport_enter_reg_pn(struct fc_lport *);
@@ -466,42 +468,10 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
 }
 
 /*
- * re-enter state for retrying a request after a timeout or alloc failure.
- */
-static void fc_lport_enter_retry(struct fc_lport *lport)
-{
-	switch (lport->state) {
-	case LPORT_ST_NONE:
-	case LPORT_ST_READY:
-	case LPORT_ST_RESET:
-		WARN_ON(1);
-		break;
-	case LPORT_ST_FLOGI:
-		fc_lport_enter_flogi(lport);
-		break;
-	case LPORT_ST_DNS:
-		fc_lport_enter_dns(lport);
-		break;
-	case LPORT_ST_REG_PN:
-		fc_lport_enter_reg_pn(lport);
-		break;
-	case LPORT_ST_REG_FT:
-		fc_lport_enter_reg_ft(lport);
-		break;
-	case LPORT_ST_SCR:
-		fc_lport_enter_scr(lport);
-		break;
-	case LPORT_ST_LOGO:
-		fc_lport_enter_logo(lport);
-		break;
-	}
-}
-
-/*
  * enter next state for handling an exchange reject or retry exhaustion
  * in the current state.
  */
-static void fc_lport_enter_reject(struct fc_lport *lport)
+static void fc_lport_reject(struct fc_lport *lport)
 {
 	switch (lport->state) {
 	case LPORT_ST_NONE:
@@ -519,28 +489,6 @@ static void fc_lport_enter_reject(struct fc_lport *lport)
 }
 
 /*
- * Handle resource allocation problem by retrying in a bit.
- */
-static void fc_lport_retry(struct fc_lport *lport)
-{
-	if (lport->retry_count == 0)
-		FC_DBG("local port %6x alloc failure in state %s "
-		       "- will retry\n", lport->fid, fc_lport_state(lport));
-
-	if (lport->retry_count < lport->max_retry_count) {
-		lport->retry_count++;
-		schedule_delayed_work(&lport->retry_work,
-				      jiffies +
-				      msecs_to_jiffies(lport->e_d_tov));
-	} else {
-		FC_DBG("local port %6x alloc failure in state %s "
-		       "- retries exhausted\n", lport->fid,
-		       fc_lport_state(lport));
-		fc_lport_enter_reject(lport);
-	}
-}
-
-/*
  * A received FLOGI request indicates a point-to-point connection.
  * Accept it with the common service parameters indicating our N port.
  * Set up to do a PLOGI if we have the higher-number WWPN.
@@ -604,7 +552,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
 		lport->tt.seq_send(lport, sp, fp, f_ctl);
 
 	} else {
-		fc_lport_retry(lport);
+		fc_lport_error(lport, fp);
 	}
 	fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
 			   get_unaligned_be64(&flp->fl_wwnn));
@@ -725,30 +673,34 @@ int fc_lport_enter_reset(struct fc_lport *lport)
 }
 EXPORT_SYMBOL(fc_lport_enter_reset);
 
-/*
- * Handle errors on local port requests.
- * Don't get locks if in RESET state.
- * The only possible errors so far are exchange TIMEOUT and CLOSED (reset).
+/**
+ * fc_lport_error - Handler for any errors
+ * @lport: The fc_lport object
+ * @fp: The frame pointer
+ *
+ * If the error was caused by a resource allocation failure
+ * then wait for half a second and retry, otherwise retry
+ * after the e_d_tov time.
  */
 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
 {
-	if (lport->state == LPORT_ST_RESET)
-		return;
-
-	fc_lport_lock(lport);
-	if (PTR_ERR(fp) == -FC_EX_TIMEOUT) {
-		if (lport->retry_count < lport->max_retry_count) {
-			lport->retry_count++;
-			fc_lport_enter_retry(lport);
-		} else {
-			fc_lport_enter_reject(lport);
-
-		}
-	}
+	unsigned long delay = 0;
 	if (fc_lport_debug)
-		FC_DBG("error %ld retries %d limit %d\n",
-		       PTR_ERR(fp), lport->retry_count, lport->max_retry_count);
-	fc_lport_unlock(lport);
+		FC_DBG("Error %ld in state %s, retries %d\n",
+		       PTR_ERR(fp), fc_lport_state(lport),
+		       lport->retry_count);
+
+	if (lport->retry_count < lport->max_retry_count) {
+		lport->retry_count++;
+		if (!fp)
+			delay = msecs_to_jiffies(500);
+		else
+			delay =	jiffies +
+				msecs_to_jiffies(lport->e_d_tov);
+	
+		schedule_delayed_work(&lport->retry_work, delay);
+	} else
+		fc_lport_reject(lport);
 }
 
 /*
@@ -769,7 +721,7 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
 				fc_lport_enter_scr(lport);
 
 		} else {
-			fc_lport_retry(lport);
+			fc_lport_error(lport, fp);
 		}
 		fc_lport_unlock(lport);
 		fc_frame_free(fp);
@@ -877,9 +829,9 @@ static void fc_lport_enter_reg_ft(struct fc_lport *lport)
 						     FC_FID_DIR_SERV,
 						     FC_FC_SEQ_INIT |
 						     FC_FC_END_SEQ))
-				fc_lport_retry(lport);
+				fc_lport_error(lport, fp);
 		} else {
-			fc_lport_retry(lport);
+			fc_lport_error(lport, fp);
 		}
 	} else {
 		fc_lport_enter_scr(lport);
@@ -903,7 +855,7 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
 	fc_lport_state_enter(lport, LPORT_ST_REG_PN);
 	fp = fc_frame_alloc(lport, sizeof(*req));
 	if (!fp) {
-		fc_lport_retry(lport);
+		fc_lport_error(lport, fp);
 		return;
 	}
 	req = fc_frame_payload_get(fp, sizeof(*req));
@@ -918,7 +870,7 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
 				     lport->fid,
 				     FC_FID_DIR_SERV,
 				     FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_lport_retry(lport);
+		fc_lport_error(lport, fp);
 }
 
 /*
@@ -966,13 +918,14 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
 	}
 	return;
 
-	/*
-	 * Resource allocation problem (malloc).  Try again in 500 mS.
-	 */
 err:
-	fc_lport_retry(lport);
+	fc_lport_error(lport, NULL);
 }
 
+/**
+ * fc_lport_timeout - Handler for the retry_work timer.
+ * @work: The work struct of the fc_lport
+ */
 static void fc_lport_timeout(struct work_struct *work)
 {
 	struct fc_lport *lport =
@@ -980,7 +933,33 @@ static void fc_lport_timeout(struct work_struct *work)
 			     retry_work.work);
 	
 	fc_lport_lock(lport);
-	fc_lport_enter_retry(lport);
+
+	switch (lport->state) {
+	case LPORT_ST_NONE:
+	case LPORT_ST_READY:
+	case LPORT_ST_RESET:
+		WARN_ON(1);
+		break;
+	case LPORT_ST_FLOGI:
+		fc_lport_enter_flogi(lport);
+		break;
+	case LPORT_ST_DNS:
+		fc_lport_enter_dns(lport);
+		break;
+	case LPORT_ST_REG_PN:
+		fc_lport_enter_reg_pn(lport);
+		break;
+	case LPORT_ST_REG_FT:
+		fc_lport_enter_reg_ft(lport);
+		break;
+	case LPORT_ST_SCR:
+		fc_lport_enter_scr(lport);
+		break;
+	case LPORT_ST_LOGO:
+		fc_lport_enter_logo(lport);
+		break;
+	}
+	
 	fc_lport_unlock(lport);
 }
 
@@ -1117,7 +1096,7 @@ static void fc_lport_flogi_send(struct fc_lport *lport)
 
 	fp = fc_frame_alloc(lport, sizeof(*flp));
 	if (!fp)
-		return fc_lport_retry(lport);
+		return fc_lport_error(lport, fp);
 
 	flp = fc_frame_payload_get(fp, sizeof(*flp));
 	fc_lport_flogi_fill(lport, flp, ELS_FLOGI);
@@ -1130,7 +1109,7 @@ static void fc_lport_flogi_send(struct fc_lport *lport)
 				     lport, lport->e_d_tov,
 				     0, FC_FID_FLOGI,
 				     FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_lport_retry(lport);
+		fc_lport_error(lport, fp);
 }
 
 void fc_lport_enter_flogi(struct fc_lport *lport)




More information about the devel mailing list