[Open-FCoE] [PATCH] libfc: Retry flogi on reject if retry count not exhausted

Abhijeet Joglekar abjoglek at cisco.com
Wed Apr 8 18:02:11 UTC 2009


Currently, libFC does not retry a flogi if it gets a flogi reject. Thus,
if the upstream fabric is busy and rejects the flogi, libfc/fnic does not
log back to the fabric unless the port is reset. This patch retries the
flogi after ed_tov if the retries have not been exhaused

For other local port frames/states like rpn_id, scr etc, fc_lport_retry()
was getting called on receiving a reject, but a retry would not be
initiated since the retry was being done only if fp allocation failed or
it was a timedout exchange. With this patch, if local port retries are
not exhaused, a reject in any of the states would cause a retry of that
state, since the first level check of doing the retry only for null frames
and timedout exchanges is removed. If a retry is not the right answer for
non-flogi states, then we should add a local_port_reset here for non-flogi
states.

If retries are exhaused, then the local port enters reset for any state.

Signed-off-by: Abhijeet Joglekar <abjoglek at cisco.com>
---
 drivers/scsi/libfc/fc_lport.c |   48 ++++++++++++++++++++---------------------
 1 files changed, 23 insertions(+), 25 deletions(-)


diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 745fa55..2db9f78 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -977,33 +977,30 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
 		     PTR_ERR(fp), fc_lport_state(lport),
 		     lport->retry_count);
 
-	if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
+	if (lport->retry_count < lport->max_retry_count) {
+		lport->retry_count++;
 		/*
-		 * Memory allocation failure, or the exchange timed out.
-		 *  Retry after delay
+		 * for frame alloc failures, different delay than e_d_tov
 		 */
-		if (lport->retry_count < lport->max_retry_count) {
-			lport->retry_count++;
-			if (!fp)
-				delay = msecs_to_jiffies(500);
-			else
-				delay =	msecs_to_jiffies(lport->e_d_tov);
-
-			schedule_delayed_work(&lport->retry_work, delay);
-		} else {
-			switch (lport->state) {
-			case LPORT_ST_NONE:
-			case LPORT_ST_READY:
-			case LPORT_ST_RESET:
-			case LPORT_ST_RPN_ID:
-			case LPORT_ST_RFT_ID:
-			case LPORT_ST_SCR:
-			case LPORT_ST_DNS:
-			case LPORT_ST_FLOGI:
-			case LPORT_ST_LOGO:
-				fc_lport_enter_reset(lport);
-				break;
-			}
+		if (!fp)
+			delay = msecs_to_jiffies(500);
+		else
+			delay =	msecs_to_jiffies(lport->e_d_tov);
+
+		schedule_delayed_work(&lport->retry_work, delay);
+	} else {
+		switch (lport->state) {
+		case LPORT_ST_NONE:
+		case LPORT_ST_READY:
+		case LPORT_ST_RESET:
+		case LPORT_ST_RPN_ID:
+		case LPORT_ST_RFT_ID:
+		case LPORT_ST_SCR:
+		case LPORT_ST_DNS:
+		case LPORT_ST_FLOGI:
+		case LPORT_ST_LOGO:
+			fc_lport_enter_reset(lport);
+			break;
 		}
 	}
 }
@@ -1511,6 +1508,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 		}
 	} else {
 		FC_LPORT_DBG(lport, "Bad FLOGI response\n");
+		fc_lport_error(lport, fp);
 	}
 
 out:





More information about the devel mailing list