* [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC
@ 2009-10-21 23:26 Robert Love
2009-10-21 23:26 ` [PATCH 01/20] libfc: fix typo in retry check on received PRLI Robert Love
` (19 more replies)
0 siblings, 20 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:26 UTC (permalink / raw)
To: James.Bottomley, linux-scsi
The following series fixes some bugs in the 2.6.32 kernel. A few of the patches fix regressions in fcoe offloads as previously mentioned on linux-scsi.
This series reorders patches previously mailed to the list. Please disregard previously mailed patches from me. I will resend the other patches for the 2.6.33 merge window.
This series is tested against today's scsi-rc-fixes tree.
---
Abhijeet Joglekar (3):
fnic: Pad the unused bytes of CDB to 0s
fnic: Set max_cmd_len to driver supported CDB length
fnic: Process all cq entries per ISR
Chris Leech (1):
libfc: fix memory corruption caused by double frees and bad error handling
Joe Eykholt (4):
libfc: fix free of fc_rport_priv with timer pending
libfc: don't WARN_ON in lport_timeout for RESET state
libfc: lport: fix minor documentation errors
libfc: fix typo in retry check on received PRLI
Mike Christie (1):
fcoe: initialize return value in fcoe_destroy
Robert Love (2):
libfc: Remove unused fc_lport pointer from fc_fcp_pkt_abort
libfc, fcoe: Don't EXPORT_SYMBOLS unnecessarily
Vasu Dev (3):
libfc: removes unused disc_work and ex_list
libfc: adds missing exch release for accepted RRQ
libfc: removes initializing fc_cpu_order and fc_cpu_mask per lport
Yi Zou (6):
fcoe: Call ndo_fcoe_enable/disable to turn FCoE feature on/off in LLD
libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data
fcoe: Use NETIF_F_FCOE_MTU flag to set up max frame size (lport->mfs)
libfc: Fix wrong scsi return status under FC_DATA_UNDRUN
fcoe: remove redundant checking of netdev->netdev_ops
libfc: fix ddp in fc_fcp for 0 xid
drivers/scsi/fcoe/fcoe.c | 34 ++++++++++++++---
drivers/scsi/fcoe/fcoe.h | 6 +++
drivers/scsi/fnic/fnic.h | 2 -
drivers/scsi/fnic/fnic_isr.c | 18 ++++-----
drivers/scsi/fnic/fnic_main.c | 1
drivers/scsi/fnic/fnic_res.h | 4 +-
drivers/scsi/fnic/fnic_scsi.c | 3 +
drivers/scsi/libfc/fc_disc.c | 2 -
drivers/scsi/libfc/fc_elsct.c | 4 +-
drivers/scsi/libfc/fc_exch.c | 35 +++++++++--------
drivers/scsi/libfc/fc_fcp.c | 26 +++++++------
drivers/scsi/libfc/fc_frame.c | 1
drivers/scsi/libfc/fc_lport.c | 33 +++++++++-------
drivers/scsi/libfc/fc_rport.c | 83 ++++++++++++++++++++++++++++-------------
include/scsi/fc_frame.h | 3 +
include/scsi/libfc.h | 2 -
16 files changed, 166 insertions(+), 91 deletions(-)
--
//Rob
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 01/20] libfc: fix typo in retry check on received PRLI
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
@ 2009-10-21 23:26 ` Robert Love
2009-10-21 23:26 ` [PATCH 02/20] libfc: fix ddp in fc_fcp for 0 xid Robert Love
` (18 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:26 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Joe Eykholt, Robert Love
From: Joe Eykholt <jeykholt@cisco.com>
A received Fibre Channel ELS PRLI request contains a bit that
indicates whether the remote port supports certain retry processing
sequences. The test for this bit was somehow coded to use multiply
instead of AND!
This case would apply only for target mode operation, and it is
unlikely to be noticed as an initiator.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_rport.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 03ea674..bdc9732 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -1402,7 +1402,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
break;
case FC_TYPE_FCP:
fcp_parm = ntohl(rspp->spp_params);
- if (fcp_parm * FCP_SPPF_RETRY)
+ if (fcp_parm & FCP_SPPF_RETRY)
rdata->flags |= FC_RP_FLAGS_RETRY;
rdata->supported_classes = FC_COS_CLASS3;
if (fcp_parm & FCP_SPPF_INIT_FCN)
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 02/20] libfc: fix ddp in fc_fcp for 0 xid
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
2009-10-21 23:26 ` [PATCH 01/20] libfc: fix typo in retry check on received PRLI Robert Love
@ 2009-10-21 23:26 ` Robert Love
2009-10-21 23:26 ` [PATCH 03/20] fcoe: remove redundant checking of netdev->netdev_ops Robert Love
` (17 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:26 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
xid 0 was used as an indication of invalid xid before but now xid 0
can be used as a valid exchange i. This patch fixes the ddp completion
in fcp layer, i.e., in fc_fcp.c:fc_fcp_ddp_done() function, to make sure it
does not use xid 0 for indication of an invalid xid, instead, it now
uses use FC_XID_UNKNOWN for such indication.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_fcp.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 59a4408..e6c6f47 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -302,10 +302,13 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
if (!fsp)
return;
+ if (fsp->xfer_ddp == FC_XID_UNKNOWN)
+ return;
+
lp = fsp->lp;
- if (fsp->xfer_ddp && lp->tt.ddp_done) {
+ if (lp->tt.ddp_done) {
fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
- fsp->xfer_ddp = 0;
+ fsp->xfer_ddp = FC_XID_UNKNOWN;
}
}
@@ -1708,6 +1711,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
fsp->cmd = sc_cmd; /* save the cmd */
fsp->lp = lp; /* save the softc ptr */
fsp->rport = rport; /* set the remote port ptr */
+ fsp->xfer_ddp = FC_XID_UNKNOWN;
sc_cmd->scsi_done = done;
/*
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 03/20] fcoe: remove redundant checking of netdev->netdev_ops
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
2009-10-21 23:26 ` [PATCH 01/20] libfc: fix typo in retry check on received PRLI Robert Love
2009-10-21 23:26 ` [PATCH 02/20] libfc: fix ddp in fc_fcp for 0 xid Robert Love
@ 2009-10-21 23:26 ` Robert Love
2009-10-21 23:27 ` [PATCH 04/20] libfc, fcoe: Don't EXPORT_SYMBOLS unnecessarily Robert Love
` (16 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:26 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
Remove the redundant checking of netdev->netdev_ops as it will never be NULL.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 704b8e0..7c89887 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -664,7 +664,7 @@ static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
{
struct net_device *n = fcoe_netdev(lp);
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
+ if (n->netdev_ops->ndo_fcoe_ddp_setup)
return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
return 0;
@@ -681,7 +681,7 @@ static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
{
struct net_device *n = fcoe_netdev(lp);
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
+ if (n->netdev_ops->ndo_fcoe_ddp_done)
return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
return 0;
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 04/20] libfc, fcoe: Don't EXPORT_SYMBOLS unnecessarily
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (2 preceding siblings ...)
2009-10-21 23:26 ` [PATCH 03/20] fcoe: remove redundant checking of netdev->netdev_ops Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 05/20] libfc: Remove unused fc_lport pointer from fc_fcp_pkt_abort Robert Love
` (15 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Robert Love
These are a few functions that were not used by other
modules. They did not need to be exported so this patch
removes the EXPORT_SYMBOLS call for each.
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_exch.c | 1 -
drivers/scsi/libfc/fc_fcp.c | 1 -
drivers/scsi/libfc/fc_frame.c | 1 -
drivers/scsi/libfc/fc_rport.c | 2 --
4 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index c1c1574..ae8f9e9 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -422,7 +422,6 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
error = -ENOBUFS;
return error;
}
-EXPORT_SYMBOL(fc_seq_exch_abort);
/*
* Exchange timeout - handle exchange timer expiration.
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index e6c6f47..e613eb8 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -285,7 +285,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid)
fsp->xfer_ddp = xid;
}
}
-EXPORT_SYMBOL(fc_fcp_ddp_setup);
/*
* fc_fcp_ddp_done - calls to LLD's ddp_done to release any
diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c
index 63fe00c..ac3681a 100644
--- a/drivers/scsi/libfc/fc_frame.c
+++ b/drivers/scsi/libfc/fc_frame.c
@@ -69,7 +69,6 @@ struct fc_frame *__fc_frame_alloc(size_t len)
}
EXPORT_SYMBOL(__fc_frame_alloc);
-
struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len)
{
struct fc_frame *fp;
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index bdc9732..1f795e4 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -1565,13 +1565,11 @@ int fc_setup_rport(void)
return -ENOMEM;
return 0;
}
-EXPORT_SYMBOL(fc_setup_rport);
void fc_destroy_rport(void)
{
destroy_workqueue(rport_event_queue);
}
-EXPORT_SYMBOL(fc_destroy_rport);
void fc_rport_terminate_io(struct fc_rport *rport)
{
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 05/20] libfc: Remove unused fc_lport pointer from fc_fcp_pkt_abort
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (3 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 04/20] libfc, fcoe: Don't EXPORT_SYMBOLS unnecessarily Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 06/20] libfc: Fix wrong scsi return status under FC_DATA_UNDRUN Robert Love
` (14 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Robert Love
This argument isn't used, let's not pass it into the routine.
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_fcp.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index e613eb8..ade962d 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1097,7 +1097,7 @@ unlock:
* Scsi abort handler- calls to send an abort
* and then wait for abort completion
*/
-static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
+static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp)
{
int rc = FAILED;
@@ -1945,7 +1945,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
goto release_pkt;
}
- rc = fc_fcp_pkt_abort(lp, fsp);
+ rc = fc_fcp_pkt_abort(fsp);
fc_fcp_unlock_pkt(fsp);
release_pkt:
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 06/20] libfc: Fix wrong scsi return status under FC_DATA_UNDRUN
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (4 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 05/20] libfc: Remove unused fc_lport pointer from fc_fcp_pkt_abort Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 07/20] libfc: lport: fix minor documentation errors Robert Love
` (13 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
This bug is exposed when there is a link flap in LLD. Particularly, when it
happens right after a SCSI write command is sent out, no FCP_DATA is sent,
causing fsp->status_code to be set as FC_DATA_UNDRUN in fc_fcp_complete_locked
even no SCSI status is received. Consequently, fc_io_compl treats this as DID_OK.
This results in SCSI returning successful to the initial I/O request even
there is no DATA actually sent. Particularly, if you run an I/O tool w/ data
verification on, the read back for verification is gonna fail.
This is fixed here by checking when FC_DATA_UNDRUN happens, SCSI status is
received w/ FC_SRB_RCV_STATUS set in fsp->state.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_fcp.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index ade962d..40ed744 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1849,7 +1849,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
* scsi status is good but transport level
* underrun.
*/
- sc_cmd->result = DID_OK << 16;
+ sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ?
+ DID_OK : DID_ERROR) << 16;
} else {
/*
* scsi got underrun, this is an error
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 07/20] libfc: lport: fix minor documentation errors
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (5 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 06/20] libfc: Fix wrong scsi return status under FC_DATA_UNDRUN Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 08/20] libfc: don't WARN_ON in lport_timeout for RESET state Robert Love
` (12 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Joe Eykholt, Robert Love
From: Joe Eykholt <jeykholt@cisco.com>
Fix minor errors.
A debug message said an RLIR was received instead of ECHO.
"Expected" was misspelled in several places.
Fix a type cast from u32 to __be32.
Rob, Some of these may have been also taken care of in your
other doc cleanup patch. Feel free to fold them in.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index bd2f771..eefe87d 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -329,7 +329,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
* @sp: current sequence in the RLIR exchange
* @fp: RLIR request frame
*
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
* this function.
*/
static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
@@ -348,7 +348,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
* @sp: current sequence in the ECHO exchange
* @fp: ECHO request frame
*
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
* this function.
*/
static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -361,7 +361,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
void *dp;
u32 f_ctl;
- FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
+ FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
fc_lport_state(lport));
len = fr_len(in_fp) - sizeof(struct fc_frame_header);
@@ -374,7 +374,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
if (fp) {
dp = fc_frame_payload_get(fp, len);
memcpy(dp, pp, len);
- *((u32 *)dp) = htonl(ELS_LS_ACC << 24);
+ *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
sp = lport->tt.seq_start_next(sp);
f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
@@ -385,12 +385,12 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
}
/**
- * fc_lport_recv_echo_req() - Handle received Request Node ID data request
- * @lport: Fibre Channel local port recieving the RNID
- * @sp: current sequence in the RNID exchange
- * @fp: RNID request frame
+ * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
+ * @sp: The sequence in the RNID exchange
+ * @fp: The RNID request frame
+ * @lport: The local port recieving the RNID
*
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
* this function.
*/
static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -667,7 +667,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
* Accept it with the common service parameters indicating our N port.
* Set up to do a PLOGI if we have the higher-number WWPN.
*
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
* this function.
*/
static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 08/20] libfc: don't WARN_ON in lport_timeout for RESET state
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (6 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 07/20] libfc: lport: fix minor documentation errors Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 09/20] libfc: removes initializing fc_cpu_order and fc_cpu_mask per lport Robert Love
` (11 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Joe Eykholt, Robert Love
From: Joe Eykholt <jeykholt@cisco.com>
It's possible and harmless to get FLOGI timeouts
while in RESET state. Don't do a WARN_ON in that case.
Also, split out the other WARN_ONs in fc_lport_timeout, so
we can tell which one is hit by its line number.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index eefe87d..0d19ffa 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1237,10 +1237,13 @@ static void fc_lport_timeout(struct work_struct *work)
switch (lport->state) {
case LPORT_ST_DISABLED:
+ WARN_ON(1);
+ break;
case LPORT_ST_READY:
- case LPORT_ST_RESET:
WARN_ON(1);
break;
+ case LPORT_ST_RESET:
+ break;
case LPORT_ST_FLOGI:
fc_lport_enter_flogi(lport);
break;
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 09/20] libfc: removes initializing fc_cpu_order and fc_cpu_mask per lport
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (7 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 08/20] libfc: don't WARN_ON in lport_timeout for RESET state Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 10/20] libfc: adds missing exch release for accepted RRQ Robert Love
` (10 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Vasu Dev, Robert Love
From: Vasu Dev <vasu.dev@intel.com>
Initializing these libfc globals per lport could mess up exch
allocation/free for existing lport.
So this patch moves their initialization to fc_setup_exch_mgr
so that these globals gets initialized only once for libfc.
Reported-by: Alex Lyakas <alexl@mellanox.co.il>
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_exch.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index ae8f9e9..bdae9a9 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -2046,6 +2046,20 @@ int fc_exch_init(struct fc_lport *lp)
if (!lp->tt.seq_exch_abort)
lp->tt.seq_exch_abort = fc_seq_exch_abort;
+ return 0;
+}
+EXPORT_SYMBOL(fc_exch_init);
+
+/**
+ * fc_setup_exch_mgr() - Setup an exchange manager
+ */
+int fc_setup_exch_mgr()
+{
+ fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!fc_em_cachep)
+ return -ENOMEM;
+
/*
* Initialize fc_cpu_mask and fc_cpu_order. The
* fc_cpu_mask is set for nr_cpu_ids rounded up
@@ -2070,16 +2084,6 @@ int fc_exch_init(struct fc_lport *lp)
return 0;
}
-EXPORT_SYMBOL(fc_exch_init);
-
-int fc_setup_exch_mgr(void)
-{
- fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
- 0, SLAB_HWCACHE_ALIGN, NULL);
- if (!fc_em_cachep)
- return -ENOMEM;
- return 0;
-}
void fc_destroy_exch_mgr(void)
{
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 10/20] libfc: adds missing exch release for accepted RRQ
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (8 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 09/20] libfc: removes initializing fc_cpu_order and fc_cpu_mask per lport Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 11/20] libfc: removes unused disc_work and ex_list Robert Love
` (9 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Vasu Dev, Robert Love
From: Vasu Dev <vasu.dev@intel.com>
Adds missing exch release when RRQ is accepted by calling
fc_seq_ls_acc. Adds common exch release for fc_exch_els_rrq
by use of out label.
Reported-by: Alex Lyakas <alexl@mellanox.co.il>
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_exch.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index bdae9a9..8ce4182 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -1718,7 +1718,7 @@ retry:
*/
static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
{
- struct fc_exch *ep; /* request or subject exchange */
+ struct fc_exch *ep = NULL; /* request or subject exchange */
struct fc_els_rrq *rp;
u32 sid;
u16 xid;
@@ -1768,15 +1768,16 @@ static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
* Send LS_ACC.
*/
fc_seq_ls_acc(sp);
- fc_frame_free(fp);
- return;
+ goto out;
unlock_reject:
spin_unlock_bh(&ep->ex_lock);
- fc_exch_release(ep); /* drop hold from fc_exch_find */
reject:
fc_seq_ls_rjt(sp, ELS_RJT_LOGIC, explan);
+out:
fc_frame_free(fp);
+ if (ep)
+ fc_exch_release(ep); /* drop hold from fc_exch_find */
}
struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 11/20] libfc: removes unused disc_work and ex_list
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (9 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 10/20] libfc: adds missing exch release for accepted RRQ Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 12/20] fcoe: initialize return value in fcoe_destroy Robert Love
` (8 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Vasu Dev, Robert Love
From: Vasu Dev <vasu.dev@intel.com>
Reported-by: Alex Lyakas <alexl@mellanox.co.il>
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_exch.c | 1 -
include/scsi/libfc.h | 1 -
2 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 8ce4182..170cdf4 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -75,7 +75,6 @@ struct fc_exch_mgr {
struct kref kref; /* exchange mgr reference count */
u16 min_xid; /* min exchange ID */
u16 max_xid; /* max exchange ID */
- struct list_head ex_list; /* allocated exchanges list */
mempool_t *ep_pool; /* reserve ep's */
u16 pool_max_index; /* max exch array index in exch pool */
struct fc_exch_pool *pool; /* per cpu exch pool */
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 65dc9aa..4ff1485 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -742,7 +742,6 @@ struct fc_lport {
/* Miscellaneous */
struct delayed_work retry_work;
- struct delayed_work disc_work;
};
/*
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 12/20] fcoe: initialize return value in fcoe_destroy
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (10 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 11/20] libfc: removes unused disc_work and ex_list Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 13/20] fcoe: Use NETIF_F_FCOE_MTU flag to set up max frame size (lport->mfs) Robert Love
` (7 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Mike Christie, Robert Love
From: Mike Christie <michaelc@cs.wisc.edu>
When doing echo ethX > /sys..../destroy I am getting
errors when the tear down succeeds. It looks like the
reason for this is because the rc var is not getting set
when the destruction works. This just sets it to zero.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 7c89887..8702c8d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1631,7 +1631,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
{
struct fcoe_interface *fcoe;
struct net_device *netdev;
- int rc;
+ int rc = 0;
mutex_lock(&fcoe_config_mutex);
#ifdef CONFIG_FCOE_MODULE
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 13/20] fcoe: Use NETIF_F_FCOE_MTU flag to set up max frame size (lport->mfs)
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (11 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 12/20] fcoe: initialize return value in fcoe_destroy Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:27 ` [PATCH 14/20] libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data Robert Love
` (6 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
Add a define of FCOE_MTU as 2158 bytes and use FCOE_MTU when the LLD is found
to support NETIF_F_FCOE_MTU. The lport->mfs is then calculated out of the
2158 FCOE_MTU. Otherwise, we stick with the netdev->mtu, i.e., LAN MTU. Also,
change the notification on NETDEV_CHANGEMTU event to bypass changing mfs when
LAN MTU is changed if NETIF_F_FCOE_MTU is supported.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 10 ++++++++--
drivers/scsi/fcoe/fcoe.h | 6 ++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 8702c8d..c66b9fa 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -439,8 +439,12 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
* user-configured limit. If the MFS is too low, fcoe_link_ok()
* will return 0, so do this first.
*/
- mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
- sizeof(struct fcoe_crc_eof));
+ mfs = netdev->mtu;
+ if (netdev->features & NETIF_F_FCOE_MTU) {
+ mfs = FCOE_MTU;
+ FCOE_NETDEV_DBG(netdev, "Supports FCOE_MTU of %d bytes\n", mfs);
+ }
+ mfs -= (sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof));
if (fc_set_mfs(lp, mfs))
return -EINVAL;
@@ -1570,6 +1574,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
case NETDEV_CHANGE:
break;
case NETDEV_CHANGEMTU:
+ if (netdev->features & NETIF_F_FCOE_MTU)
+ break;
mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
sizeof(struct fcoe_crc_eof));
if (mfs >= FC_MIN_MAX_FRAME)
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index ce7f60f..c578082 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -40,6 +40,12 @@
#define FCOE_MIN_XID 0x0000 /* the min xid supported by fcoe_sw */
#define FCOE_MAX_XID 0x0FFF /* the max xid supported by fcoe_sw */
+/*
+ * Max MTU for FCoE: 14 (FCoE header) + 24 (FC header) + 2112 (max FC payload)
+ * + 4 (FC CRC) + 4 (FCoE trailer) = 2158 bytes
+ */
+#define FCOE_MTU 2158
+
unsigned int fcoe_debug_logging;
module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 14/20] libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (12 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 13/20] fcoe: Use NETIF_F_FCOE_MTU flag to set up max frame size (lport->mfs) Robert Love
@ 2009-10-21 23:27 ` Robert Love
2009-10-21 23:28 ` [PATCH 15/20] fcoe: Call ndo_fcoe_enable/disable to turn FCoE feature on/off in LLD Robert Love
` (5 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:27 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
In case of sequence offload, in fc_fcp_send_data(), the skb_fill_page_info()
called may end up adding more frags to the skb_shinfo(fp_skb(fp))->frags[],
exceeding SKB_MAX_FRAGS, this eventually corrupts the memory. I am adding the
FR_FRAME_SG_LEN back, but as SKB_MAX_FRAGS -1, leaving 1 for our fcoe_eof_crc
page. And send will be broken into multiple large sends if the frame already
contains more frags than skb handle.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_fcp.c | 3 ++-
include/scsi/fc_frame.h | 3 +++
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 40ed744..28bfe1c 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -574,7 +574,8 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
tlen -= sg_bytes;
remaining -= sg_bytes;
- if (tlen)
+ if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) &&
+ (tlen))
continue;
/*
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index c35d238..148126d 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -37,6 +37,9 @@
#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
+/* Max number of skb frags allowed, reserving one for fcoe_crc_eof page */
+#define FC_FRAME_SG_LEN (MAX_SKB_FRAGS - 1)
+
#define fp_skb(fp) (&((fp)->skb))
#define fr_hdr(fp) ((fp)->skb.data)
#define fr_len(fp) ((fp)->skb.len)
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 15/20] fcoe: Call ndo_fcoe_enable/disable to turn FCoE feature on/off in LLD
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (13 preceding siblings ...)
2009-10-21 23:27 ` [PATCH 14/20] libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data Robert Love
@ 2009-10-21 23:28 ` Robert Love
2009-10-21 23:28 ` [PATCH 16/20] libfc: fix memory corruption caused by double frees and bad error handling Robert Love
` (4 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love
From: Yi Zou <yi.zou@intel.com>
Calls ndo_fcoe_enabled() of the associated netdev upon creating the FCoE
instance to make sure LLD has all necessary resources allocated and setup
properly before passing FCoE traffic. Similarly, calls ndo_fcoe_disable()
upon destroying the FCoE instance on the associated netdev to allow the LLD
to release all allocated resources for FCoE.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index c66b9fa..aef29af 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -161,9 +161,18 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
struct fcoe_ctlr *fip = &fcoe->ctlr;
struct netdev_hw_addr *ha;
u8 flogi_maddr[ETH_ALEN];
+ const struct net_device_ops *ops;
fcoe->netdev = netdev;
+ /* Let LLD initialize for FCoE */
+ ops = netdev->netdev_ops;
+ if (ops->ndo_fcoe_enable) {
+ if (ops->ndo_fcoe_enable(netdev))
+ FCOE_NETDEV_DBG(netdev, "Failed to enable FCoE"
+ " specific feature for LLD.\n");
+ }
+
/* Do not support for bonding device */
if ((netdev->priv_flags & IFF_MASTER_ALB) ||
(netdev->priv_flags & IFF_SLAVE_INACTIVE) ||
@@ -262,6 +271,7 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
struct net_device *netdev = fcoe->netdev;
struct fcoe_ctlr *fip = &fcoe->ctlr;
u8 flogi_maddr[ETH_ALEN];
+ const struct net_device_ops *ops;
/*
* Don't listen for Ethernet packets anymore.
@@ -281,6 +291,14 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
if (fip->spma)
dev_unicast_delete(netdev, fip->ctl_src_addr);
dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+
+ /* Tell the LLD we are done w/ FCoE */
+ ops = netdev->netdev_ops;
+ if (ops->ndo_fcoe_disable) {
+ if (ops->ndo_fcoe_disable(netdev))
+ FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
+ " specific feature for LLD.\n");
+ }
}
/**
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 16/20] libfc: fix memory corruption caused by double frees and bad error handling
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (14 preceding siblings ...)
2009-10-21 23:28 ` [PATCH 15/20] fcoe: Call ndo_fcoe_enable/disable to turn FCoE feature on/off in LLD Robert Love
@ 2009-10-21 23:28 ` Robert Love
2009-10-21 23:28 ` [PATCH 17/20] fnic: Process all cq entries per ISR Robert Love
` (3 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Chris Leech, Robert Love
From: Chris Leech <christopher.leech@intel.com>
I was running into several different panics under stress, which I traced down
to a few different possible slab corruption issues in error handling paths.
I have not yet looked into why these exchange sends fail, but with these
fixes my test system is much more stable under stress than before.
fc_elsct_send() could fail and either leave the passed in frame intact
(failure in fc_ct/els_fill) or the frame could have been freed if the
failure was is fc_exch_seq_send(). The caller had no way of knowing, and
there was a potential double free in the error handling in fc_fcp_rec().
Make fc_elsct_send() always free the frame before returning, and remove the
fc_frame_free() call in fc_fcp_rec().
While fc_exch_seq_send() did always consume the frame, there were double free
bugs in the error handling of fc_fcp_cmd_send() and fc_fcp_srr() as well.
Numerous calls to error handling routines (fc_disc_error(),
fc_lport_error(), fc_rport_error_retry() ) were passing in a frame pointer that
had already been freed in the case of an error. I have changed the call
sites to pass in a NULL pointer, but there may be more appropriate error
codes to use.
Question: Why do these error routines take a frame pointer anyway? I
understand passing in a pointer encoded error to the response handlers, but
the error routines take no action on a valid pointer and should never be
called that way.
Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_disc.c | 2 +-
drivers/scsi/libfc/fc_elsct.c | 4 +++-
drivers/scsi/libfc/fc_fcp.c | 7 ++-----
drivers/scsi/libfc/fc_lport.c | 8 ++++----
drivers/scsi/libfc/fc_rport.c | 10 +++++-----
5 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index c48799e..d4cb3f9 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -371,7 +371,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc)
disc, lport->e_d_tov))
return;
err:
- fc_disc_error(disc, fp);
+ fc_disc_error(disc, NULL);
}
/**
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index 5cfa687..9298458 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -53,8 +53,10 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
did = FC_FID_DIR_SERV;
}
- if (rc)
+ if (rc) {
+ fc_frame_free(fp);
return NULL;
+ }
fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 28bfe1c..a67f53a 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1051,7 +1051,6 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
if (!seq) {
- fc_frame_free(fp);
rc = -1;
goto unlock;
}
@@ -1316,7 +1315,6 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
return;
}
- fc_frame_free(fp);
retry:
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
@@ -1564,10 +1562,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
- if (!seq) {
- fc_frame_free(fp);
+ if (!seq)
goto retry;
- }
+
fsp->recov_seq = seq;
fsp->xfer_len = offset;
fsp->xfer_contig_end = offset;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 0d19ffa..536492a 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1115,7 +1115,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
fc_lport_scr_resp, lport, lport->e_d_tov))
- fc_lport_error(lport, fp);
+ fc_lport_error(lport, NULL);
}
/**
@@ -1186,7 +1186,7 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID,
fc_lport_rpn_id_resp,
lport, lport->e_d_tov))
- fc_lport_error(lport, fp);
+ fc_lport_error(lport, NULL);
}
static struct fc_rport_operations fc_lport_rport_ops = {
@@ -1340,7 +1340,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
fc_lport_logo_resp, lport, lport->e_d_tov))
- fc_lport_error(lport, fp);
+ fc_lport_error(lport, NULL);
}
/**
@@ -1456,7 +1456,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
fc_lport_flogi_resp, lport, lport->e_d_tov))
- fc_lport_error(lport, fp);
+ fc_lport_error(lport, NULL);
}
/* Configure a fc_lport */
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 1f795e4..49abb83 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -632,7 +632,7 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
fc_rport_plogi_resp, rdata, lport->e_d_tov))
- fc_rport_error_retry(rdata, fp);
+ fc_rport_error_retry(rdata, NULL);
else
kref_get(&rdata->kref);
}
@@ -793,7 +793,7 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
fc_rport_prli_resp, rdata, lport->e_d_tov))
- fc_rport_error_retry(rdata, fp);
+ fc_rport_error_retry(rdata, NULL);
else
kref_get(&rdata->kref);
}
@@ -889,7 +889,7 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
fc_rport_rtv_resp, rdata, lport->e_d_tov))
- fc_rport_error_retry(rdata, fp);
+ fc_rport_error_retry(rdata, NULL);
else
kref_get(&rdata->kref);
}
@@ -919,7 +919,7 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
fc_rport_logo_resp, rdata, lport->e_d_tov))
- fc_rport_error_retry(rdata, fp);
+ fc_rport_error_retry(rdata, NULL);
else
kref_get(&rdata->kref);
}
@@ -1006,7 +1006,7 @@ static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
}
if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
fc_rport_adisc_resp, rdata, lport->e_d_tov))
- fc_rport_error_retry(rdata, fp);
+ fc_rport_error_retry(rdata, NULL);
else
kref_get(&rdata->kref);
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 17/20] fnic: Process all cq entries per ISR
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (15 preceding siblings ...)
2009-10-21 23:28 ` [PATCH 16/20] libfc: fix memory corruption caused by double frees and bad error handling Robert Love
@ 2009-10-21 23:28 ` Robert Love
2009-10-21 23:28 ` [PATCH 18/20] fnic: Set max_cmd_len to driver supported CDB length Robert Love
` (2 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Herman Lee, Abhijeet Joglekar, Robert Love
From: Abhijeet Joglekar <abjoglek@cisco.com>
Driver was processing a fixed max number of cq descriptors per ISR. For
instance, for the SCSI IO queue, number of IOs processed per ISR were 8.
If hardware writes 9 cq descriptors to the cq and generates an interrupt,
driver would process only 8 descriptors and decrement the outstanding
credit count by 8. Unless another interrupt event happens, the hw does
not generate any additional interrupt. This results in the cq descriptor
sitting in the queue without being procesed and can cause IO timeouts
and aborts.
Modify all ISR functions to process all queued cq descriptors in one shot.
Since bulk of ELS frame processing is done in thread context and bulk
of SCSI IO processing is done in soft ISR deferred context, the cycles
spent in the ISR per cq descriptor is small.
Signed-off-by: Herman Lee <hermlee@cisco.com>
Signed-off-by: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fnic/fnic_isr.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c
index 2b30648..5c1f223 100644
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -48,9 +48,9 @@ static irqreturn_t fnic_isr_legacy(int irq, void *data)
}
if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) {
- work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
- work_done += fnic_wq_cmpl_handler(fnic, 4);
- work_done += fnic_rq_cmpl_handler(fnic, 4);
+ work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+ work_done += fnic_wq_cmpl_handler(fnic, -1);
+ work_done += fnic_rq_cmpl_handler(fnic, -1);
vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ],
work_done,
@@ -66,9 +66,9 @@ static irqreturn_t fnic_isr_msi(int irq, void *data)
struct fnic *fnic = data;
unsigned long work_done = 0;
- work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
- work_done += fnic_wq_cmpl_handler(fnic, 4);
- work_done += fnic_rq_cmpl_handler(fnic, 4);
+ work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+ work_done += fnic_wq_cmpl_handler(fnic, -1);
+ work_done += fnic_rq_cmpl_handler(fnic, -1);
vnic_intr_return_credits(&fnic->intr[0],
work_done,
@@ -83,7 +83,7 @@ static irqreturn_t fnic_isr_msix_rq(int irq, void *data)
struct fnic *fnic = data;
unsigned long rq_work_done = 0;
- rq_work_done = fnic_rq_cmpl_handler(fnic, 4);
+ rq_work_done = fnic_rq_cmpl_handler(fnic, -1);
vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ],
rq_work_done,
1 /* unmask intr */,
@@ -97,7 +97,7 @@ static irqreturn_t fnic_isr_msix_wq(int irq, void *data)
struct fnic *fnic = data;
unsigned long wq_work_done = 0;
- wq_work_done = fnic_wq_cmpl_handler(fnic, 4);
+ wq_work_done = fnic_wq_cmpl_handler(fnic, -1);
vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ],
wq_work_done,
1 /* unmask intr */,
@@ -110,7 +110,7 @@ static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data)
struct fnic *fnic = data;
unsigned long wq_copy_work_done = 0;
- wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, 8);
+ wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1);
vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY],
wq_copy_work_done,
1 /* unmask intr */,
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 18/20] fnic: Set max_cmd_len to driver supported CDB length
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (16 preceding siblings ...)
2009-10-21 23:28 ` [PATCH 17/20] fnic: Process all cq entries per ISR Robert Love
@ 2009-10-21 23:28 ` Robert Love
2009-10-21 23:28 ` [PATCH 19/20] fnic: Pad the unused bytes of CDB to 0s Robert Love
2009-10-21 23:28 ` [PATCH 20/20] libfc: fix free of fc_rport_priv with timer pending Robert Love
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Abhijeet Joglekar, Robert Love
From: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fnic/fnic.h | 2 +-
drivers/scsi/fnic/fnic_main.c | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index e4c0a3d..1bc267e 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -44,7 +44,7 @@
#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */
#define FNIC_DFLT_QUEUE_DEPTH 32
#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
-
+#define FNIC_MAX_CMD_LEN 16 /* Supported CDB length */
/*
* Tag bits used for special requests.
*/
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 71c7bbe..b0d425a 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -560,6 +560,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
}
host->max_lun = fnic->config.luns_per_tgt;
host->max_id = FNIC_MAX_FCP_TARGET;
+ host->max_cmd_len = FNIC_MAX_CMD_LEN;
fnic_get_res_counts(fnic);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 19/20] fnic: Pad the unused bytes of CDB to 0s
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (17 preceding siblings ...)
2009-10-21 23:28 ` [PATCH 18/20] fnic: Set max_cmd_len to driver supported CDB length Robert Love
@ 2009-10-21 23:28 ` Robert Love
2009-10-21 23:28 ` [PATCH 20/20] libfc: fix free of fc_rport_priv with timer pending Robert Love
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Abhijeet Joglekar, Robert Love
From: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Abhijeet Joglekar <abjoglek@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fnic/fnic_res.h | 4 +++-
drivers/scsi/fnic/fnic_scsi.c | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/fnic/fnic_res.h b/drivers/scsi/fnic/fnic_res.h
index b6f3102..88c4471 100644
--- a/drivers/scsi/fnic/fnic_res.h
+++ b/drivers/scsi/fnic/fnic_res.h
@@ -58,6 +58,7 @@ static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
u64 sgl_addr, u64 sns_addr,
u8 crn, u8 pri_ta,
u8 flags, u8 *scsi_cdb,
+ u8 cdb_len,
u32 data_len, u8 *lun,
u32 d_id, u16 mss,
u32 ratov, u32 edtov)
@@ -82,7 +83,8 @@ static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
desc->u.icmnd_16.pri_ta = pri_ta; /* SCSI Pri & Task attribute */
desc->u.icmnd_16._resvd1 = 0; /* reserved: should be 0 */
desc->u.icmnd_16.flags = flags; /* command flags */
- memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, CDB_16); /* SCSI CDB */
+ memset(desc->u.icmnd_16.scsi_cdb, 0, CDB_16);
+ memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, cdb_len); /* SCSI CDB */
desc->u.icmnd_16.data_len = data_len; /* length of data expected */
memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS); /* LUN address */
desc->u.icmnd_16._resvd2 = 0; /* reserved */
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index bfc9969..b5d1738 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -319,7 +319,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
0, /* scsi cmd ref, always 0 */
pri_tag, /* scsi pri and tag */
flags, /* command flags */
- sc->cmnd, scsi_bufflen(sc),
+ sc->cmnd, sc->cmd_len,
+ scsi_bufflen(sc),
fc_lun.scsi_lun, io_req->port_id,
rport->maxframe_size, rp->r_a_tov,
rp->e_d_tov);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 20/20] libfc: fix free of fc_rport_priv with timer pending
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
` (18 preceding siblings ...)
2009-10-21 23:28 ` [PATCH 19/20] fnic: Pad the unused bytes of CDB to 0s Robert Love
@ 2009-10-21 23:28 ` Robert Love
19 siblings, 0 replies; 21+ messages in thread
From: Robert Love @ 2009-10-21 23:28 UTC (permalink / raw)
To: James.Bottomley, linux-scsi; +Cc: Joe Eykholt, Robert Love
From: Joe Eykholt <jeykholt@cisco.com>
Timer crashes were caused by freeing a struct fc_rport_priv
with a timer pending, causing the timer facility list to be
corrupted. This was during FC uplink flap tests with a lot
of targets.
After discovery, we were doing an PLOGI on an rdata that was
in DELETE state but not yet removed from the lookup list.
This moved the rdata from DELETE state to PLOGI state.
If the PLOGI exchange allocation failed and needed to be
retried, the timer scheduling could race with the free
being done by fc_rport_work().
When fc_rport_login() is called on a rport in DELETE state,
move it to a new state RESTART. In fc_rport_work, when
handling a LOGO, STOPPED or FAILED event, look for restart
state. In the RESTART case, don't take the rdata off the
list and after the transport remote port is deleted and
exchanges are reset, re-login to the remote port.
Note that the new RESTART state also corrects a problem we
had when re-discovering a port that had moved to DELETE state.
In that case, a new rdata was created, but the old rdata
would do an exchange manager reset affecting the FC_ID
for both the new rdata and old rdata. With the new state,
the new port isn't logged into until after any old exchanges
are reset.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_rport.c | 69 ++++++++++++++++++++++++++++++-----------
include/scsi/libfc.h | 1 +
2 files changed, 51 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 49abb83..324e156 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -86,6 +86,7 @@ static const char *fc_rport_state_names[] = {
[RPORT_ST_LOGO] = "LOGO",
[RPORT_ST_ADISC] = "ADISC",
[RPORT_ST_DELETE] = "Delete",
+ [RPORT_ST_RESTART] = "Restart",
};
/**
@@ -99,8 +100,7 @@ static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
struct fc_rport_priv *rdata;
list_for_each_entry(rdata, &lport->disc.rports, peers)
- if (rdata->ids.port_id == port_id &&
- rdata->rp_state != RPORT_ST_DELETE)
+ if (rdata->ids.port_id == port_id)
return rdata;
return NULL;
}
@@ -235,6 +235,7 @@ static void fc_rport_work(struct work_struct *work)
struct fc_rport_operations *rport_ops;
struct fc_rport_identifiers ids;
struct fc_rport *rport;
+ int restart = 0;
mutex_lock(&rdata->rp_mutex);
event = rdata->event;
@@ -287,8 +288,19 @@ static void fc_rport_work(struct work_struct *work)
mutex_unlock(&rdata->rp_mutex);
if (port_id != FC_FID_DIR_SERV) {
+ /*
+ * We must drop rp_mutex before taking disc_mutex.
+ * Re-evaluate state to allow for restart.
+ * A transition to RESTART state must only happen
+ * while disc_mutex is held and rdata is on the list.
+ */
mutex_lock(&lport->disc.disc_mutex);
- list_del(&rdata->peers);
+ mutex_lock(&rdata->rp_mutex);
+ if (rdata->rp_state == RPORT_ST_RESTART)
+ restart = 1;
+ else
+ list_del(&rdata->peers);
+ mutex_unlock(&rdata->rp_mutex);
mutex_unlock(&lport->disc.disc_mutex);
}
@@ -312,7 +324,13 @@ static void fc_rport_work(struct work_struct *work)
mutex_unlock(&rdata->rp_mutex);
fc_remote_port_delete(rport);
}
- kref_put(&rdata->kref, lport->tt.rport_destroy);
+ if (restart) {
+ mutex_lock(&rdata->rp_mutex);
+ FC_RPORT_DBG(rdata, "work restart\n");
+ fc_rport_enter_plogi(rdata);
+ mutex_unlock(&rdata->rp_mutex);
+ } else
+ kref_put(&rdata->kref, lport->tt.rport_destroy);
break;
default:
@@ -342,6 +360,12 @@ int fc_rport_login(struct fc_rport_priv *rdata)
FC_RPORT_DBG(rdata, "ADISC port\n");
fc_rport_enter_adisc(rdata);
break;
+ case RPORT_ST_RESTART:
+ break;
+ case RPORT_ST_DELETE:
+ FC_RPORT_DBG(rdata, "Restart deleted port\n");
+ fc_rport_state_enter(rdata, RPORT_ST_RESTART);
+ break;
default:
FC_RPORT_DBG(rdata, "Login to port\n");
fc_rport_enter_plogi(rdata);
@@ -397,20 +421,21 @@ int fc_rport_logoff(struct fc_rport_priv *rdata)
if (rdata->rp_state == RPORT_ST_DELETE) {
FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
- mutex_unlock(&rdata->rp_mutex);
goto out;
}
- fc_rport_enter_logo(rdata);
+ if (rdata->rp_state == RPORT_ST_RESTART)
+ FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n");
+ else
+ fc_rport_enter_logo(rdata);
/*
* Change the state to Delete so that we discard
* the response.
*/
fc_rport_enter_delete(rdata, RPORT_EV_STOP);
- mutex_unlock(&rdata->rp_mutex);
-
out:
+ mutex_unlock(&rdata->rp_mutex);
return 0;
}
@@ -466,6 +491,7 @@ static void fc_rport_timeout(struct work_struct *work)
case RPORT_ST_READY:
case RPORT_ST_INIT:
case RPORT_ST_DELETE:
+ case RPORT_ST_RESTART:
break;
}
@@ -499,6 +525,7 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
fc_rport_enter_logo(rdata);
break;
case RPORT_ST_DELETE:
+ case RPORT_ST_RESTART:
case RPORT_ST_READY:
case RPORT_ST_INIT:
break;
@@ -1248,6 +1275,7 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
}
break;
case RPORT_ST_PRLI:
+ case RPORT_ST_RTV:
case RPORT_ST_READY:
case RPORT_ST_ADISC:
FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
@@ -1255,11 +1283,14 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
/* XXX TBD - should reset */
break;
case RPORT_ST_DELETE:
- default:
- FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n",
- rdata->rp_state);
- fc_frame_free(rx_fp);
- goto out;
+ case RPORT_ST_LOGO:
+ case RPORT_ST_RESTART:
+ FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
+ fc_rport_state(rdata));
+ mutex_unlock(&rdata->rp_mutex);
+ rjt_data.reason = ELS_RJT_BUSY;
+ rjt_data.explan = ELS_EXPL_NONE;
+ goto reject;
}
/*
@@ -1510,14 +1541,14 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport,
FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
fc_rport_state(rdata));
+ fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+
/*
- * If the remote port was created due to discovery,
- * log back in. It may have seen a stale RSCN about us.
+ * If the remote port was created due to discovery, set state
+ * to log back in. It may have seen a stale RSCN about us.
*/
- if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id)
- fc_rport_enter_plogi(rdata);
- else
- fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+ if (rdata->disc_id)
+ fc_rport_state_enter(rdata, RPORT_ST_RESTART);
mutex_unlock(&rdata->rp_mutex);
} else
FC_RPORT_ID_DBG(lport, sid,
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 4ff1485..1662d73 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -145,6 +145,7 @@ enum fc_rport_state {
RPORT_ST_LOGO, /* port logout sent */
RPORT_ST_ADISC, /* Discover Address sent */
RPORT_ST_DELETE, /* port being deleted */
+ RPORT_ST_RESTART, /* remote port being deleted and will restart */
};
/**
^ permalink raw reply related [flat|nested] 21+ messages in thread
end of thread, other threads:[~2009-10-21 23:30 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-21 23:26 [PATCH 00/20] libfc, fcoe and fnci fixes for 2.6.32 RC Robert Love
2009-10-21 23:26 ` [PATCH 01/20] libfc: fix typo in retry check on received PRLI Robert Love
2009-10-21 23:26 ` [PATCH 02/20] libfc: fix ddp in fc_fcp for 0 xid Robert Love
2009-10-21 23:26 ` [PATCH 03/20] fcoe: remove redundant checking of netdev->netdev_ops Robert Love
2009-10-21 23:27 ` [PATCH 04/20] libfc, fcoe: Don't EXPORT_SYMBOLS unnecessarily Robert Love
2009-10-21 23:27 ` [PATCH 05/20] libfc: Remove unused fc_lport pointer from fc_fcp_pkt_abort Robert Love
2009-10-21 23:27 ` [PATCH 06/20] libfc: Fix wrong scsi return status under FC_DATA_UNDRUN Robert Love
2009-10-21 23:27 ` [PATCH 07/20] libfc: lport: fix minor documentation errors Robert Love
2009-10-21 23:27 ` [PATCH 08/20] libfc: don't WARN_ON in lport_timeout for RESET state Robert Love
2009-10-21 23:27 ` [PATCH 09/20] libfc: removes initializing fc_cpu_order and fc_cpu_mask per lport Robert Love
2009-10-21 23:27 ` [PATCH 10/20] libfc: adds missing exch release for accepted RRQ Robert Love
2009-10-21 23:27 ` [PATCH 11/20] libfc: removes unused disc_work and ex_list Robert Love
2009-10-21 23:27 ` [PATCH 12/20] fcoe: initialize return value in fcoe_destroy Robert Love
2009-10-21 23:27 ` [PATCH 13/20] fcoe: Use NETIF_F_FCOE_MTU flag to set up max frame size (lport->mfs) Robert Love
2009-10-21 23:27 ` [PATCH 14/20] libfc: Fix frags in frame exceeding SKB_MAX_FRAGS in fc_fcp_send_data Robert Love
2009-10-21 23:28 ` [PATCH 15/20] fcoe: Call ndo_fcoe_enable/disable to turn FCoE feature on/off in LLD Robert Love
2009-10-21 23:28 ` [PATCH 16/20] libfc: fix memory corruption caused by double frees and bad error handling Robert Love
2009-10-21 23:28 ` [PATCH 17/20] fnic: Process all cq entries per ISR Robert Love
2009-10-21 23:28 ` [PATCH 18/20] fnic: Set max_cmd_len to driver supported CDB length Robert Love
2009-10-21 23:28 ` [PATCH 19/20] fnic: Pad the unused bytes of CDB to 0s Robert Love
2009-10-21 23:28 ` [PATCH 20/20] libfc: fix free of fc_rport_priv with timer pending Robert Love
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox