All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Love <robert.w.love@intel.com>
To: linux-scsi@vger.kernel.org
Cc: Bart Van Assche <bvanassche@acm.org>,
	Neil Horman <nhorman@tuxdriver.com>
Subject: [PATCH 10/16] libfc: Avoid that sending after an abort triggers a kernel warning
Date: Thu, 05 Sep 2013 12:13:11 -0700	[thread overview]
Message-ID: <20130905191311.15235.39902.stgit@fritz> (raw)
In-Reply-To: <20130905191218.15235.85917.stgit@fritz>

From: Bart Van Assche <bvanassche@acm.org>

Calling fc_seq_send() after an ABTS message has been received triggers
a kernel warning (WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT))). Avoid
this by returning -ENXIO to the caller if fc_seq_send() is invoked after
an ABTS message has been received.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
 drivers/scsi/libfc/fc_exch.c |   59 ++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index bc0aba4..2a7fd5a 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -463,15 +463,21 @@ static void fc_exch_delete(struct fc_exch *ep)
 }
 
 static int fc_seq_send_locked(struct fc_lport *lport, struct fc_seq *sp,
-		       struct fc_frame *fp)
+			      struct fc_frame *fp)
 {
 	struct fc_exch *ep;
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
-	int error;
+	int error = -ENXIO;
 	u32 f_ctl;
 	u8 fh_type = fh->fh_type;
 
 	ep = fc_seq_exch(sp);
+
+	if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL)) {
+		fc_frame_free(fp);
+		goto out;
+	}
+
 	WARN_ON(!(ep->esb_stat & ESB_ST_SEQ_INIT));
 
 	f_ctl = ntoh24(fh->fh_f_ctl);
@@ -514,6 +520,9 @@ out:
  * @lport: The local port that the exchange will be sent on
  * @sp:	   The sequence to be sent
  * @fp:	   The frame to be sent on the exchange
+ *
+ * Note: The frame will be freed either by a direct call to fc_frame_free(fp)
+ * or indirectly by calling libfc_function_template.frame_send().
  */
 static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
 		       struct fc_frame *fp)
@@ -621,27 +630,31 @@ static int fc_exch_abort_locked(struct fc_exch *ep,
 	if (!sp)
 		return -ENOMEM;
 
-	ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL;
 	if (timer_msec)
 		fc_exch_timer_set_locked(ep, timer_msec);
 
-	/*
-	 * If not logged into the fabric, don't send ABTS but leave
-	 * sequence active until next timeout.
-	 */
-	if (!ep->sid)
-		return 0;
-
-	/*
-	 * Send an abort for the sequence that timed out.
-	 */
-	fp = fc_frame_alloc(ep->lp, 0);
-	if (fp) {
-		fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
-			       FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
-		error = fc_seq_send_locked(ep->lp, sp, fp);
-	} else
-		error = -ENOBUFS;
+	if (ep->sid) {
+		/*
+		 * Send an abort for the sequence that timed out.
+		 */
+		fp = fc_frame_alloc(ep->lp, 0);
+		if (fp) {
+			ep->esb_stat |= ESB_ST_SEQ_INIT;
+			fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
+				       FC_TYPE_BLS, FC_FC_END_SEQ |
+				       FC_FC_SEQ_INIT, 0);
+			error = fc_seq_send_locked(ep->lp, sp, fp);
+		} else {
+			error = -ENOBUFS;
+		}
+	} else {
+		/*
+		 * If not logged into the fabric, don't send ABTS but leave
+		 * sequence active until next timeout.
+		 */
+		error = 0;
+	}
+	ep->esb_stat |= ESB_ST_ABNORMAL;
 	return error;
 }
 
@@ -1299,9 +1312,10 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
 		spin_unlock_bh(&ep->ex_lock);
 		goto reject;
 	}
-	if (!(ep->esb_stat & ESB_ST_REC_QUAL))
+	if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
+		ep->esb_stat |= ESB_ST_REC_QUAL;
 		fc_exch_hold(ep);		/* hold for REC_QUAL */
-	ep->esb_stat |= ESB_ST_ABNORMAL | ESB_ST_REC_QUAL;
+	}
 	fc_exch_timer_set_locked(ep, ep->r_a_tov);
 
 	fp = fc_frame_alloc(ep->lp, sizeof(*ap));
@@ -1322,6 +1336,7 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
 	}
 	sp = fc_seq_start_next_locked(sp);
 	fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
+	ep->esb_stat |= ESB_ST_ABNORMAL;
 	spin_unlock_bh(&ep->ex_lock);
 	fc_frame_free(rx_fp);
 	return;


  parent reply	other threads:[~2013-09-05 19:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-05 19:12 [PATCH 00/16] libfc, libfcoe, fcoe updates for 3.12(+) Robert Love
2013-09-05 19:12 ` [PATCH 01/16] fcoe: ensure that skb placed on the fip_recv_list are unshared Robert Love
2013-09-05 19:12 ` [PATCH 02/16] fcoe: make sure fcoe frames are unshared prior to manipulating them Robert Love
2013-09-05 19:12 ` [PATCH 03/16] fcoe: cleanup return codes from fcoe_rcv Robert Love
2013-09-05 19:12 ` [PATCH 04/16] libfc: Source code comment spelling fixes Robert Love
2013-09-05 19:12 ` [PATCH 05/16] libfc: Debug code fixes Robert Love
2013-09-05 19:12 ` [PATCH 06/16] libfc: Micro-optimize fc_setup_exch_mgr() Robert Love
2013-09-05 19:12 ` [PATCH 07/16] libfc: Clarify fc_exch_find() Robert Love
2013-09-05 19:13 ` [PATCH 08/16] libfc: Fix a race in fc_exch_timer_set_locked() Robert Love
2013-09-05 19:13 ` [PATCH 09/16] libfc: Protect ep->esb_stat changes via ex_lock Robert Love
2013-09-05 19:13 ` Robert Love [this message]
2013-09-05 19:13 ` [PATCH 11/16] libfc: Reduce exchange lock contention in fc_exch_recv_abts() Robert Love
2013-09-05 19:13 ` [PATCH 12/16] libfc: Do not invoke the response handler after fc_exch_done() Robert Love
2013-09-05 19:13 ` [PATCH 13/16] fcp: Do not interpret check condition as underrun Robert Love
2013-09-05 19:13 ` [PATCH 14/16] fcoe: Declare fcoe_ctlr_mode_set() static Robert Love
2013-09-05 19:13 ` [PATCH 15/16] fcoe: Add missing newlines in debug messages Robert Love
2013-09-05 19:13 ` [PATCH 16/16] fcoe: Reduce fcoe_sysfs_fcf_add() stack usage Robert Love

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130905191311.15235.39902.stgit@fritz \
    --to=robert.w.love@intel.com \
    --cc=bvanassche@acm.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.