* [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc
@ 2012-07-06 17:39 Robert Love
2012-07-06 17:40 ` [PATCH 1/6] fcoe: Cleanup locking on fcoe_percpu_receive_thread Robert Love
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:39 UTC (permalink / raw)
To: linux-scsi
Here are a few bug fixes across libfc, libfcoe and fcoe.
---
Neil Horman (1):
fcoe: Cleanup locking on fcoe_percpu_receive_thread
Robert Love (1):
fcoe: Remove redundant 'less than zero' check
Vasu Dev (2):
libfc: add exch timer debug info
libfc: fix retries with FDMI lport states
Yi Zou (2):
libfc: don't exch_done() on invalid sequence ptr
libfc: fix sending REC after FCP_RESP is received
drivers/scsi/fcoe/fcoe.c | 18 ++++----
drivers/scsi/fcoe/fcoe_sysfs.c | 2 -
drivers/scsi/libfc/fc_exch.c | 96 ++++++++++++++++++++++------------------
drivers/scsi/libfc/fc_fcp.c | 6 +--
drivers/scsi/libfc/fc_lport.c | 8 ++-
5 files changed, 72 insertions(+), 58 deletions(-)
--
Thanks, //Rob
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/6] fcoe: Cleanup locking on fcoe_percpu_receive_thread
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
@ 2012-07-06 17:40 ` Robert Love
2012-07-06 17:40 ` [PATCH 2/6] libfc: add exch timer debug info Robert Love
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi; +Cc: Neil Horman, Vasu Dev
From: Neil Horman <nhorman@tuxdriver.com>
Noticed that we can shuffle the code around in fcoe_percpu_receive_thread a bit
and avoid taking the fcoe_rx_list lock twice per iteration. This should improve
throughput somewhat. With this change we take the lock, and check for new
frames in a single critical section. Only if the list is empty do we drop the
lock and re-acquire it after being signaled to wake up.
Change Notes:
v2) did some further cleanup on the patch by replacing the 2nd call of
spin_lock/splice_init with a goto to the top of the outer loop. This allows me
to change the inner while loop to an if conditional and remove the sencond check
of kthread_should_stop. Based on suggestion from Vasu Dev.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index fe30b1b..656ff65 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1851,23 +1851,25 @@ static int fcoe_percpu_receive_thread(void *arg)
set_user_nice(current, -20);
+retry:
while (!kthread_should_stop()) {
spin_lock_bh(&p->fcoe_rx_list.lock);
skb_queue_splice_init(&p->fcoe_rx_list, &tmp);
- spin_unlock_bh(&p->fcoe_rx_list.lock);
-
- while ((skb = __skb_dequeue(&tmp)) != NULL)
- fcoe_recv_frame(skb);
- spin_lock_bh(&p->fcoe_rx_list.lock);
- if (!skb_queue_len(&p->fcoe_rx_list)) {
+ if (!skb_queue_len(&tmp)) {
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_bh(&p->fcoe_rx_list.lock);
schedule();
set_current_state(TASK_RUNNING);
- } else
- spin_unlock_bh(&p->fcoe_rx_list.lock);
+ goto retry;
+ }
+
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+
+ while ((skb = __skb_dequeue(&tmp)) != NULL)
+ fcoe_recv_frame(skb);
+
}
return 0;
}
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] libfc: add exch timer debug info
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
2012-07-06 17:40 ` [PATCH 1/6] fcoe: Cleanup locking on fcoe_percpu_receive_thread Robert Love
@ 2012-07-06 17:40 ` Robert Love
2012-07-06 17:40 ` [PATCH 3/6] libfc: fix retries with FDMI lport states Robert Love
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi; +Cc: Vasu Dev
From: Vasu Dev <vasu.dev@intel.com>
Add exch timeout info to have debug log with exch timeout
value to match with retries, also add debug info
on exch timer cancel.
Added common fc_exch_timer_cancel() func and grouped this
along with fc_exch_timer_set() function, so that
added debug code is not repeated.
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 | 96 +++++++++++++++++++++++-------------------
1 file changed, 53 insertions(+), 43 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index aceffad..0c8a61b 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -339,6 +339,52 @@ static void fc_exch_release(struct fc_exch *ep)
}
/**
+ * fc_exch_timer_cancel() - cancel exch timer
+ * @ep: The exchange whose timer to be canceled
+ */
+static inline void fc_exch_timer_cancel(struct fc_exch *ep)
+{
+ if (cancel_delayed_work(&ep->timeout_work)) {
+ FC_EXCH_DBG(ep, "Exchange timer canceled\n");
+ atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
+ }
+}
+
+/**
+ * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
+ * the exchange lock held
+ * @ep: The exchange whose timer will start
+ * @timer_msec: The timeout period
+ *
+ * Used for upper level protocols to time out the exchange.
+ * The timer is cancelled when it fires or when the exchange completes.
+ */
+static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
+ unsigned int timer_msec)
+{
+ if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
+ return;
+
+ FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec);
+
+ if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
+ msecs_to_jiffies(timer_msec)))
+ fc_exch_hold(ep); /* hold for timer */
+}
+
+/**
+ * fc_exch_timer_set() - Lock the exchange and set the timer
+ * @ep: The exchange whose timer will start
+ * @timer_msec: The timeout period
+ */
+static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
+{
+ spin_lock_bh(&ep->ex_lock);
+ fc_exch_timer_set_locked(ep, timer_msec);
+ spin_unlock_bh(&ep->ex_lock);
+}
+
+/**
* fc_exch_done_locked() - Complete an exchange with the exchange lock held
* @ep: The exchange that is complete
*/
@@ -359,8 +405,7 @@ static int fc_exch_done_locked(struct fc_exch *ep)
if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
ep->state |= FC_EX_DONE;
- if (cancel_delayed_work(&ep->timeout_work))
- atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
+ fc_exch_timer_cancel(ep);
rc = 0;
}
return rc;
@@ -424,40 +469,6 @@ static void fc_exch_delete(struct fc_exch *ep)
}
/**
- * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
- * the exchange lock held
- * @ep: The exchange whose timer will start
- * @timer_msec: The timeout period
- *
- * Used for upper level protocols to time out the exchange.
- * The timer is cancelled when it fires or when the exchange completes.
- */
-static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
- unsigned int timer_msec)
-{
- if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
- return;
-
- FC_EXCH_DBG(ep, "Exchange timer armed\n");
-
- if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
- msecs_to_jiffies(timer_msec)))
- fc_exch_hold(ep); /* hold for timer */
-}
-
-/**
- * fc_exch_timer_set() - Lock the exchange and set the timer
- * @ep: The exchange whose timer will start
- * @timer_msec: The timeout period
- */
-static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
-{
- spin_lock_bh(&ep->ex_lock);
- fc_exch_timer_set_locked(ep, timer_msec);
- spin_unlock_bh(&ep->ex_lock);
-}
-
-/**
* fc_seq_send() - Send a frame using existing sequence/exchange pair
* @lport: The local port that the exchange will be sent on
* @sp: The sequence to be sent
@@ -1549,8 +1560,10 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl,
fc_exch_rctl_name(fh->fh_r_ctl));
- if (cancel_delayed_work_sync(&ep->timeout_work))
+ if (cancel_delayed_work_sync(&ep->timeout_work)) {
+ FC_EXCH_DBG(ep, "Exchange timer canceled\n");
fc_exch_release(ep); /* release from pending timer hold */
+ }
spin_lock_bh(&ep->ex_lock);
switch (fh->fh_r_ctl) {
@@ -1737,8 +1750,7 @@ static void fc_exch_reset(struct fc_exch *ep)
spin_lock_bh(&ep->ex_lock);
fc_exch_abort_locked(ep, 0);
ep->state |= FC_EX_RST_CLEANUP;
- if (cancel_delayed_work(&ep->timeout_work))
- atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
+ fc_exch_timer_cancel(ep);
resp = ep->resp;
ep->resp = NULL;
if (ep->esb_stat & ESB_ST_REC_QUAL)
@@ -2133,10 +2145,8 @@ static void fc_exch_els_rrq(struct fc_frame *fp)
ep->esb_stat &= ~ESB_ST_REC_QUAL;
atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */
}
- if (ep->esb_stat & ESB_ST_COMPLETE) {
- if (cancel_delayed_work(&ep->timeout_work))
- atomic_dec(&ep->ex_refcnt); /* drop timer hold */
- }
+ if (ep->esb_stat & ESB_ST_COMPLETE)
+ fc_exch_timer_cancel(ep);
spin_unlock_bh(&ep->ex_lock);
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] libfc: fix retries with FDMI lport states
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
2012-07-06 17:40 ` [PATCH 1/6] fcoe: Cleanup locking on fcoe_percpu_receive_thread Robert Love
2012-07-06 17:40 ` [PATCH 2/6] libfc: add exch timer debug info Robert Love
@ 2012-07-06 17:40 ` Robert Love
2012-07-06 17:40 ` [PATCH 4/6] fcoe: Remove redundant 'less than zero' check Robert Love
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi; +Cc: Marcus Dennis, Vasu Dev
From: Vasu Dev <vasu.dev@intel.com>
The FC-GS-3 sepc requires to wait for least 3 times R_A_TOV per
sec 4.6.1 "If the Requesting_CT does not receive a Response
CT_IU from the Responding_CT within three times R_A_TOV,
it shall consider this to be a protocol error."
This means added four new states with management server
could add significant delay with multiple retries
on default 12 second timeout(3 * R_A_TOV), so instead
just skip these states on very first timeout on any of
these states to not stuck with states for such longer
period.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Tested-by: Marcus Dennis <marcusx.e.dennis@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index c1402fb..45b24a4 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1590,8 +1590,9 @@ static void fc_lport_timeout(struct work_struct *work)
case LPORT_ST_RPA:
case LPORT_ST_DHBA:
case LPORT_ST_DPRT:
- fc_lport_enter_ms(lport, lport->state);
- break;
+ FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n",
+ fc_lport_state(lport));
+ /* fall thru */
case LPORT_ST_SCR:
fc_lport_enter_scr(lport);
break;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] fcoe: Remove redundant 'less than zero' check
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
` (2 preceding siblings ...)
2012-07-06 17:40 ` [PATCH 3/6] libfc: fix retries with FDMI lport states Robert Love
@ 2012-07-06 17:40 ` Robert Love
2012-07-06 17:40 ` [PATCH 5/6] libfc: don't exch_done() on invalid sequence ptr Robert Love
2012-07-06 17:40 ` [PATCH 6/6] libfc: fix sending REC after FCP_RESP is received Robert Love
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi
strtoul returns an 'unsigned long' so there is no
reason to check if the value is less than zero.
strtoul already checks for the '-' character deep
in its bowels. It will return an error if the user
has provided a negative value and fcoe_str_to_dev_loss
will return that error to its caller.
This patch fixes the following Coverity reported warning:
CID 703581 - NO_EFFECT Unsigned compared against 0 - This
less-than-zero comparison of an unsigned value is never true. "*val < 0UL".
drivers/scsi/fcoe/fcoe_sysfs.c:105
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe_sysfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c
index 2bc1631..5e75168 100644
--- a/drivers/scsi/fcoe/fcoe_sysfs.c
+++ b/drivers/scsi/fcoe/fcoe_sysfs.c
@@ -102,7 +102,7 @@ static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val)
int ret;
ret = kstrtoul(buf, 0, val);
- if (ret || *val < 0)
+ if (ret)
return -EINVAL;
/*
* Check for overflow; dev_loss_tmo is u32
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] libfc: don't exch_done() on invalid sequence ptr
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
` (3 preceding siblings ...)
2012-07-06 17:40 ` [PATCH 4/6] fcoe: Remove redundant 'less than zero' check Robert Love
@ 2012-07-06 17:40 ` Robert Love
2012-07-06 17:40 ` [PATCH 6/6] libfc: fix sending REC after FCP_RESP is received Robert Love
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi; +Cc: Ross Brattain, Yi Zou
From: Yi Zou <yi.zou@intel.com>
The lport_recv(), i.e., fc_lport_recv_req() may get called w/o the sequence ptr
being set in fr_seq(), particularly in the case of vn2vn mode, this may happen
if the passive fcp provider, e.g., tcm_fc, has not been registered yet.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 45b24a4..55f58ee 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -973,7 +973,8 @@ drop:
rcu_read_unlock();
FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
fc_frame_free(fp);
- lport->tt.exch_done(sp);
+ if (sp)
+ lport->tt.exch_done(sp);
}
/**
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] libfc: fix sending REC after FCP_RESP is received
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
` (4 preceding siblings ...)
2012-07-06 17:40 ` [PATCH 5/6] libfc: don't exch_done() on invalid sequence ptr Robert Love
@ 2012-07-06 17:40 ` Robert Love
5 siblings, 0 replies; 7+ messages in thread
From: Robert Love @ 2012-07-06 17:40 UTC (permalink / raw)
To: linux-scsi; +Cc: Ross Brattain, Yi Zou
From: Yi Zou <yi.zou@intel.com>
This is exposed in the case the FCP_DATA frames somehow got lost and fc_fcp got
the FCP_RSP, in fc_fcp_recv_resp(), since xfer_len is less than the expected_len
it resets the the timer to wait to 2 more jiffies in case the data frames are
already queued locally. However, for target does not support REC, it would just
send RJT w/ ELS_RJT_UNSUP. The rec response handler thus only clears the rport
flag for not doing REC later, but does not do fcp_io_complete() on the
associated fsp.
The fix is just check status of FCP_RSP being received already, i.e. using the
FC_SRB_RCV_STATUS flag, in fc_fcp_timeout before start sending REC. We should
have waited long enough if there is truely data frames queued locally.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_fcp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index f735730..5c8074b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1372,10 +1372,10 @@ static void fc_fcp_timeout(unsigned long data)
fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
- if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
- fc_fcp_rec(fsp);
- else if (fsp->state & FC_SRB_RCV_STATUS)
+ if (fsp->state & FC_SRB_RCV_STATUS)
fc_fcp_complete_locked(fsp);
+ else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
+ fc_fcp_rec(fsp);
else
fc_fcp_recovery(fsp, FC_TIMED_OUT);
fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-07-06 17:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-06 17:39 [PATCH 0/6] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
2012-07-06 17:40 ` [PATCH 1/6] fcoe: Cleanup locking on fcoe_percpu_receive_thread Robert Love
2012-07-06 17:40 ` [PATCH 2/6] libfc: add exch timer debug info Robert Love
2012-07-06 17:40 ` [PATCH 3/6] libfc: fix retries with FDMI lport states Robert Love
2012-07-06 17:40 ` [PATCH 4/6] fcoe: Remove redundant 'less than zero' check Robert Love
2012-07-06 17:40 ` [PATCH 5/6] libfc: don't exch_done() on invalid sequence ptr Robert Love
2012-07-06 17:40 ` [PATCH 6/6] libfc: fix sending REC after FCP_RESP is received Robert Love
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).