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
