linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).