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 <[email protected]>
---
 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:


_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to