All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33)
@ 2009-11-20 22:54 Robert Love
  2009-11-20 22:54 ` [PATCH 1/9] libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request Robert Love
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:54 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi

The following series adds the following-

1) Support for a link status error block (LESB) command.

2) A performance optimization. If an incoming FCP frame is already on the correct CPU then bypass the Rx threads and process in irq context.

3) At least one fix.

---

Chris Leech (1):
      fcoe: allow SCSI-FCP to be processed directly in softirq context

Yi Zou (8):
      libfc: add support of receiving ELS_RLS
      fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB)
      libfc: add fcoe_fc_els_lesb to fc_fcoe.h for FC-BB-5 LESB definitions
      libfcoe: add tracking FIP Missing Discovery Advertisement count
      libfcoe: add tracking FIP Virtual Link Failure count
      libfcoe: add checking disable flag in FIP_FKA_ADV
      libfc: add FC-BB-5 LESB counters to fcoe_dev_stats
      libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request


 drivers/scsi/fcoe/fcoe.c      |  279 +++++++++++++++++++++++++----------------
 drivers/scsi/fcoe/libfcoe.c   |   20 +++
 drivers/scsi/libfc/fc_lport.c |    3 
 drivers/scsi/libfc/fc_rport.c |   76 +++++++++++
 include/scsi/fc/fc_fcoe.h     |   12 ++
 include/scsi/fc/fc_fip.h      |   12 ++
 include/scsi/libfc.h          |   10 +
 include/scsi/libfcoe.h        |    1 
 8 files changed, 299 insertions(+), 114 deletions(-)

-- 
//Rob

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/9] libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
@ 2009-11-20 22:54 ` Robert Love
  2009-11-20 22:54 ` [PATCH 2/9] fcoe: allow SCSI-FCP to be processed directly in softirq context Robert Love
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:54 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Frame header room is already incluced, just pass the length of payload.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/libfc/fc_lport.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index c841d54..bbf4152 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1679,8 +1679,7 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
 	char *pp;
 	int len;
 
-	fp = fc_frame_alloc(lport, sizeof(struct fc_frame_header) +
-			    job->request_payload.payload_len);
+	fp = fc_frame_alloc(lport, job->request_payload.payload_len);
 	if (!fp)
 		return -ENOMEM;
 


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/9] fcoe: allow SCSI-FCP to be processed directly in softirq context
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
  2009-11-20 22:54 ` [PATCH 1/9] libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request Robert Love
@ 2009-11-20 22:54 ` Robert Love
  2009-11-20 22:54 ` [PATCH 3/9] libfc: add FC-BB-5 LESB counters to fcoe_dev_stats Robert Love
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:54 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Chris Leech, Robert Love

From: Chris Leech <christopher.leech@intel.com>

Allow FCP frames to bypass the FCoE receive processing threads and handle
them directly in softirq context, if they are received on the correct CPU.
This preserves the queuing to threads for scaling out receive processing
to multiple CPUs, but allows FCoE-aware multi-queue network drivers that
direct frames to the originating CPUs to handle FCP processing with less
scheduling latency.

Only FCP is handled directly, because libfc makes use of mutexes in ELS
handling routines.

The bulk of this change is just moving the FCoE receive processing out of
the receive thread function, leaving behind just the thread and queue
management.  The interesting bits are in fcoe_rcv()

Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/fcoe/fcoe.c |  245 +++++++++++++++++++++++++---------------------
 1 files changed, 135 insertions(+), 110 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 4a43b74..32298ed 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -109,6 +109,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
 						   struct fc_frame *,
 						   void *),
 				      void *, u32 timeout);
+static void fcoe_recv_frame(struct sk_buff *skb);
 
 module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
 __MODULE_PARM_TYPE(create, "string");
@@ -1241,11 +1242,25 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
 	 * this skb. We also have this receive thread locked,
 	 * so we're free to queue skbs into it's queue.
 	 */
-	__skb_queue_tail(&fps->fcoe_rx_list, skb);
-	if (fps->fcoe_rx_list.qlen == 1)
-		wake_up_process(fps->thread);
 
-	spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	/* If this is a SCSI-FCP frame, and this is already executing on the
+	 * correct CPU, and the queue for this CPU is empty, then go ahead
+	 * and process the frame directly in the softirq context.
+	 * This lets us process completions without context switching from the
+	 * NET_RX softirq, to our receive processing thread, and then back to
+	 * BLOCK softirq context.
+	 */
+	if (fh->fh_type == FC_TYPE_FCP &&
+	    cpu == smp_processor_id() &&
+	    skb_queue_empty(&fps->fcoe_rx_list)) {
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+		fcoe_recv_frame(skb);
+	} else {
+		__skb_queue_tail(&fps->fcoe_rx_list, skb);
+		if (fps->fcoe_rx_list.qlen == 1)
+			wake_up_process(fps->thread);
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	}
 
 	return 0;
 err:
@@ -1503,26 +1518,134 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb)
 }
 
 /**
- * fcoe_percpu_receive_thread() - The per-CPU packet receive thread
- * @arg: The per-CPU context
- *
- * Return: 0 for success
+ * fcoe_recv_frame() - process a single received frame
+ * @skb: frame to process
  */
-int fcoe_percpu_receive_thread(void *arg)
+static void fcoe_recv_frame(struct sk_buff *skb)
 {
-	struct fcoe_percpu_s *p = arg;
 	u32 fr_len;
 	struct fc_lport *lport;
 	struct fcoe_rcv_info *fr;
 	struct fcoe_dev_stats *stats;
 	struct fc_frame_header *fh;
-	struct sk_buff *skb;
 	struct fcoe_crc_eof crc_eof;
 	struct fc_frame *fp;
 	u8 *mac = NULL;
 	struct fcoe_port *port;
 	struct fcoe_hdr *hp;
 
+	fr = fcoe_dev_from_skb(skb);
+	lport = fr->fr_dev;
+	if (unlikely(!lport)) {
+		if (skb->destructor != fcoe_percpu_flush_done)
+			FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
+		kfree_skb(skb);
+		return;
+	}
+
+	FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
+			"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
+			skb->len, skb->data_len,
+			skb->head, skb->data, skb_tail_pointer(skb),
+			skb_end_pointer(skb), skb->csum,
+			skb->dev ? skb->dev->name : "<NULL>");
+
+	/*
+	 * Save source MAC address before discarding header.
+	 */
+	port = lport_priv(lport);
+	if (skb_is_nonlinear(skb))
+		skb_linearize(skb);	/* not ideal */
+	mac = eth_hdr(skb)->h_source;
+
+	/*
+	 * Frame length checks and setting up the header pointers
+	 * was done in fcoe_rcv already.
+	 */
+	hp = (struct fcoe_hdr *) skb_network_header(skb);
+	fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+	stats = fc_lport_get_stats(lport);
+	if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
+		if (stats->ErrorFrames < 5)
+			printk(KERN_WARNING "fcoe: FCoE version "
+			       "mismatch: The frame has "
+			       "version %x, but the "
+			       "initiator supports version "
+			       "%x\n", FC_FCOE_DECAPS_VER(hp),
+			       FC_FCOE_VER);
+		stats->ErrorFrames++;
+		kfree_skb(skb);
+		return;
+	}
+
+	skb_pull(skb, sizeof(struct fcoe_hdr));
+	fr_len = skb->len - sizeof(struct fcoe_crc_eof);
+
+	stats->RxFrames++;
+	stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
+	fp = (struct fc_frame *)skb;
+	fc_frame_init(fp);
+	fr_dev(fp) = lport;
+	fr_sof(fp) = hp->fcoe_sof;
+
+	/* Copy out the CRC and EOF trailer for access */
+	if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
+		kfree_skb(skb);
+		return;
+	}
+	fr_eof(fp) = crc_eof.fcoe_eof;
+	fr_crc(fp) = crc_eof.fcoe_crc32;
+	if (pskb_trim(skb, fr_len)) {
+		kfree_skb(skb);
+		return;
+	}
+
+	/*
+	 * We only check CRC if no offload is available and if it is
+	 * it's solicited data, in which case, the FCP layer would
+	 * check it during the copy.
+	 */
+	if (lport->crc_offload &&
+	    skb->ip_summed == CHECKSUM_UNNECESSARY)
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	else
+		fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
+
+	fh = fc_frame_header_get(fp);
+	if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
+	    fh->fh_type == FC_TYPE_FCP) {
+		fc_exch_recv(lport, fp);
+		return;
+	}
+	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+		if (le32_to_cpu(fr_crc(fp)) !=
+		    ~crc32(~0, skb->data, fr_len)) {
+			if (stats->InvalidCRCCount < 5)
+				printk(KERN_WARNING "fcoe: dropping "
+				       "frame with CRC error\n");
+			stats->InvalidCRCCount++;
+			stats->ErrorFrames++;
+			fc_frame_free(fp);
+			return;
+		}
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	}
+	fc_exch_recv(lport, fp);
+}
+
+/**
+ * fcoe_percpu_receive_thread() - The per-CPU packet receive thread
+ * @arg: The per-CPU context
+ *
+ * Return: 0 for success
+ */
+int fcoe_percpu_receive_thread(void *arg)
+{
+	struct fcoe_percpu_s *p = arg;
+	struct sk_buff *skb;
+
 	set_user_nice(current, -20);
 
 	while (!kthread_should_stop()) {
@@ -1538,105 +1661,7 @@ int fcoe_percpu_receive_thread(void *arg)
 			spin_lock_bh(&p->fcoe_rx_list.lock);
 		}
 		spin_unlock_bh(&p->fcoe_rx_list.lock);
-		fr = fcoe_dev_from_skb(skb);
-		lport = fr->fr_dev;
-		if (unlikely(!lport)) {
-			if (skb->destructor != fcoe_percpu_flush_done)
-				FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
-			kfree_skb(skb);
-			continue;
-		}
-
-		FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
-				"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
-				skb->len, skb->data_len,
-				skb->head, skb->data, skb_tail_pointer(skb),
-				skb_end_pointer(skb), skb->csum,
-				skb->dev ? skb->dev->name : "<NULL>");
-
-		/*
-		 * Save source MAC address before discarding header.
-		 */
-		port = lport_priv(lport);
-		if (skb_is_nonlinear(skb))
-			skb_linearize(skb);	/* not ideal */
-		mac = eth_hdr(skb)->h_source;
-
-		/*
-		 * Frame length checks and setting up the header pointers
-		 * was done in fcoe_rcv already.
-		 */
-		hp = (struct fcoe_hdr *) skb_network_header(skb);
-		fh = (struct fc_frame_header *) skb_transport_header(skb);
-
-		stats = fc_lport_get_stats(lport);
-		if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
-			if (stats->ErrorFrames < 5)
-				printk(KERN_WARNING "fcoe: FCoE version "
-				       "mismatch: The frame has "
-				       "version %x, but the "
-				       "initiator supports version "
-				       "%x\n", FC_FCOE_DECAPS_VER(hp),
-				       FC_FCOE_VER);
-			stats->ErrorFrames++;
-			kfree_skb(skb);
-			continue;
-		}
-
-		skb_pull(skb, sizeof(struct fcoe_hdr));
-		fr_len = skb->len - sizeof(struct fcoe_crc_eof);
-
-		stats->RxFrames++;
-		stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
-
-		fp = (struct fc_frame *)skb;
-		fc_frame_init(fp);
-		fr_dev(fp) = lport;
-		fr_sof(fp) = hp->fcoe_sof;
-
-		/* Copy out the CRC and EOF trailer for access */
-		if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
-			kfree_skb(skb);
-			continue;
-		}
-		fr_eof(fp) = crc_eof.fcoe_eof;
-		fr_crc(fp) = crc_eof.fcoe_crc32;
-		if (pskb_trim(skb, fr_len)) {
-			kfree_skb(skb);
-			continue;
-		}
-
-		/*
-		 * We only check CRC if no offload is available and if it is
-		 * it's solicited data, in which case, the FCP layer would
-		 * check it during the copy.
-		 */
-		if (lport->crc_offload &&
-		    skb->ip_summed == CHECKSUM_UNNECESSARY)
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		else
-			fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
-
-		fh = fc_frame_header_get(fp);
-		if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
-		    fh->fh_type == FC_TYPE_FCP) {
-			fc_exch_recv(lport, fp);
-			continue;
-		}
-		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
-			if (le32_to_cpu(fr_crc(fp)) !=
-			    ~crc32(~0, skb->data, fr_len)) {
-				if (stats->InvalidCRCCount < 5)
-					printk(KERN_WARNING "fcoe: dropping "
-					       "frame with CRC error\n");
-				stats->InvalidCRCCount++;
-				stats->ErrorFrames++;
-				fc_frame_free(fp);
-				continue;
-			}
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		}
-		fc_exch_recv(lport, fp);
+		fcoe_recv_frame(skb);
 	}
 	return 0;
 }


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/9] libfc: add FC-BB-5 LESB counters to fcoe_dev_stats
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
  2009-11-20 22:54 ` [PATCH 1/9] libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request Robert Love
  2009-11-20 22:54 ` [PATCH 2/9] fcoe: allow SCSI-FCP to be processed directly in softirq context Robert Love
@ 2009-11-20 22:54 ` Robert Love
  2009-11-20 22:54 ` [PATCH 4/9] libfcoe: add checking disable flag in FIP_FKA_ADV Robert Love
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:54 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

FC-BB-5 Rev2.0, Clause 7.10 extends the FC-LS-3 LESB for FC-BB_E. We are
already tracking Link Failure Count so add the rest in this patch.

For VLinkFailureCount and MissDiscAdvCount, they are part of the per-cpu
fcoe_dev_stats. For SymbolErrorCount, ErroredBlockCount, and FCSErrorCount,
they are defined in IEEE 802.3-2008 and are per LLD. They are expected to
come from LLD.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 include/scsi/libfc.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 2936fba..b97be29 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -231,6 +231,8 @@ struct fc_rport_priv {
  * @ControlRequests:       Number of control requests
  * @InputMegabytes:        Number of received megabytes
  * @OutputMegabytes:       Number of transmitted megabytes
+ * @VLinkFailureCount:     Number of virtual link failures
+ * @MissDiscAdvCount:      Number of missing FIP discovery advertisement
  */
 struct fcoe_dev_stats {
 	u64		SecondsSinceLastReset;
@@ -249,6 +251,8 @@ struct fcoe_dev_stats {
 	u64		ControlRequests;
 	u64		InputMegabytes;
 	u64		OutputMegabytes;
+	u64		VLinkFailureCount;
+	u64		MissDiscAdvCount;
 };
 
 /**


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/9] libfcoe: add checking disable flag in FIP_FKA_ADV
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (2 preceding siblings ...)
  2009-11-20 22:54 ` [PATCH 3/9] libfc: add FC-BB-5 LESB counters to fcoe_dev_stats Robert Love
@ 2009-11-20 22:54 ` Robert Love
  2009-11-20 22:55 ` [PATCH 5/9] libfcoe: add tracking FIP Virtual Link Failure count Robert Love
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:54 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

When the D bit is set if the FKA_ADV_Period of the FIP Discovery
Advertisement, the ENode should not transmit period ENode FIP Keep Alive and
VN_Port FIP Keep Alive (FC-BB-5 Rev2, 7.8.3.13).

Note that fcf->flags is taken directly from the fip_header, I am claiming one
bit for the purpose of the FIP_FKA_Period D bit as FIP_FL_FK_ADV_B, and use
FIP_HEADER_FLAGS as bitmask for bits used in fip_header.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/fcoe/libfcoe.c |    4 +++-
 include/scsi/fc/fc_fip.h    |   12 +++++++++++-
 include/scsi/libfcoe.h      |    1 +
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 3c501d4..9961fd7 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -665,6 +665,8 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
 			if (dlen != sizeof(struct fip_fka_desc))
 				goto len_err;
 			fka = (struct fip_fka_desc *)desc;
+			if (fka->fd_flags & FIP_FKA_ADV_D)
+				fcf->fd_flags = 1;
 			t = ntohl(fka->fd_fka_period);
 			if (t >= FCOE_CTLR_MIN_FKA)
 				fcf->fka_period = msecs_to_jiffies(t);
@@ -1160,7 +1162,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
 		}
 	}
 
-	if (sel) {
+	if (sel && !sel->fd_flags) {
 		if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
 			fip->ctlr_ka_time = jiffies + sel->fka_period;
 			fip->send_ctlr_ka = 1;
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h
index 3d138c1..17baa19 100644
--- a/include/scsi/fc/fc_fip.h
+++ b/include/scsi/fc/fc_fip.h
@@ -214,11 +214,21 @@ struct fip_vn_desc {
  */
 struct fip_fka_desc {
 	struct fip_desc fd_desc;
-	__u8		fd_resvd[2];
+	__u8		fd_resvd;
+	__u8		fd_flags;	/* bit0 is fka disable flag */
 	__be32		fd_fka_period;	/* adv./keep-alive period in mS */
 } __attribute__((packed));
 
 /*
+ * flags for fip_fka_desc.fd_flags
+ */
+enum fip_fka_flags {
+	FIP_FKA_ADV_D =	0x01,		/* no need for FKA from ENode */
+};
+
+/* FIP_DT_FKA flags */
+
+/*
  * FIP_DT_VENDOR descriptor.
  */
 struct fip_vendor_desc {
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 3837872..c603f4a 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -155,6 +155,7 @@ struct fcoe_fcf {
 	u8 pri;
 	u16 flags;
 	u32 fka_period;
+	u8 fd_flags:1;
 };
 
 /* FIP API functions */


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/9] libfcoe: add tracking FIP Virtual Link Failure count
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (3 preceding siblings ...)
  2009-11-20 22:54 ` [PATCH 4/9] libfcoe: add checking disable flag in FIP_FKA_ADV Robert Love
@ 2009-11-20 22:55 ` Robert Love
  2009-11-20 22:55 ` [PATCH 6/9] libfcoe: add tracking FIP Missing Discovery Advertisement count Robert Love
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:55 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Add tracking the Virtual Link Failure count when either we have found
the FCF as "aged" or we are receiving FIP Clear Virtual Link from the
FCF.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/fcoe/libfcoe.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 9961fd7..34800af 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -578,6 +578,7 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
 			WARN_ON(!fip->fcf_count);
 			fip->fcf_count--;
 			kfree(fcf);
+			fc_lport_get_stats(fip->lp)->VLinkFailureCount++;
 		} else if (fcoe_ctlr_mtu_valid(fcf) &&
 			   (!sel_time || time_before(sel_time, fcf->time))) {
 			sel_time = fcf->time;
@@ -990,6 +991,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
 		LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
 
 		spin_lock_bh(&fip->lock);
+		fc_lport_get_stats(lport)->VLinkFailureCount++;
 		fcoe_ctlr_reset(fip);
 		spin_unlock_bh(&fip->lock);
 


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/9] libfcoe: add tracking FIP Missing Discovery Advertisement count
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (4 preceding siblings ...)
  2009-11-20 22:55 ` [PATCH 5/9] libfcoe: add tracking FIP Virtual Link Failure count Robert Love
@ 2009-11-20 22:55 ` Robert Love
  2009-11-20 22:55 ` [PATCH 7/9] libfc: add fcoe_fc_els_lesb to fc_fcoe.h for FC-BB-5 LESB definitions Robert Love
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:55 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Add tracking the Missing Discovery Advertisement count for FIP Fiber Channel
Forwarder (FCF) as described in FC-BB-5 Rev2.0 for LESB. The time is 1.5 times
the FKA_ADV_PERIOD of the corresponding FCF.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/fcoe/libfcoe.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 34800af..9823291 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -562,14 +562,28 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
  * times its keep-alive period including fuzz.
  *
  * In addition, determine the time when an FCF selection can occur.
+ *
+ * Also, increment the MissDiscAdvCount when no advertisement is received
+ * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
  */
 static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
 {
 	struct fcoe_fcf *fcf;
 	struct fcoe_fcf *next;
 	unsigned long sel_time = 0;
+	unsigned long mda_time = 0;
 
 	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+		mda_time = fcf->fka_period + (fcf->fka_period >> 1);
+		if ((fip->sel_fcf == fcf) &&
+		    (time_after(jiffies, fcf->time + mda_time))) {
+			mod_timer(&fip->timer, jiffies + mda_time);
+			fc_lport_get_stats(fip->lp)->MissDiscAdvCount++;
+			printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
+			       "Advertisement for fab %llx count %lld\n",
+			       fip->lp->host->host_no, fcf->fabric_name,
+			       fc_lport_get_stats(fip->lp)->MissDiscAdvCount);
+		}
 		if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
 			       msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
 			if (fip->sel_fcf == fcf)


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/9] libfc: add fcoe_fc_els_lesb to fc_fcoe.h for FC-BB-5 LESB definitions
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (5 preceding siblings ...)
  2009-11-20 22:55 ` [PATCH 6/9] libfcoe: add tracking FIP Missing Discovery Advertisement count Robert Love
@ 2009-11-20 22:55 ` Robert Love
  2009-11-20 22:55 ` [PATCH 8/9] fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB) Robert Love
  2009-11-20 22:55 ` [PATCH 9/9] libfc: add support of receiving ELS_RLS Robert Love
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:55 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Add struct fcoe_fc_els_lesb as described in FC-BB-5 LESB for FCoE. It has
the same size as LESB defined in FC-FS-3 (struct fc_els_lesb) but members
have different meanings according to FC-BB-5.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 include/scsi/fc/fc_fcoe.h |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h
index ccb3dbe..e6ad3d2 100644
--- a/include/scsi/fc/fc_fcoe.h
+++ b/include/scsi/fc/fc_fcoe.h
@@ -86,6 +86,18 @@ struct fcoe_crc_eof {
 #define FCOE_MIN_FRAME 46
 
 /*
+ * FCoE Link Error Status Block: T11 FC-BB-5 Rev2.0, Clause 7.10.
+ */
+struct fcoe_fc_els_lesb {
+	__be32		lesb_link_fail;	/* link failure count */
+	__be32		lesb_vlink_fail; /* virtual link failure count */
+	__be32		lesb_miss_fka;	/* missing FIP keep-alive count */
+	__be32		lesb_symb_err;	/* symbol error during carrier count */
+	__be32		lesb_err_block;	/* errored block count */
+	__be32		lesb_fcs_error; /* frame check sequence error count */
+};
+
+/*
  * fc_fcoe_set_mac - Store OUI + DID into MAC address field.
  * @mac: mac address to be set
  * @did: fc dest id to use


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/9] fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB)
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (6 preceding siblings ...)
  2009-11-20 22:55 ` [PATCH 7/9] libfc: add fcoe_fc_els_lesb to fc_fcoe.h for FC-BB-5 LESB definitions Robert Love
@ 2009-11-20 22:55 ` Robert Love
  2009-11-20 22:55 ` [PATCH 9/9] libfc: add support of receiving ELS_RLS Robert Love
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:55 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Add a member function pointer as get_lesb to libfc_function_template so LLD
can fill the LESB based on its own statistics. For fcoe, it fills the LESB
as a fcoe_fc_els_lesb struct according to FC-BB-5.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/fcoe/fcoe.c |   34 ++++++++++++++++++++++++++++++++++
 include/scsi/libfc.h     |    6 ++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 32298ed..a30ffaa 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -111,6 +111,8 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
 				      void *, u32 timeout);
 static void fcoe_recv_frame(struct sk_buff *skb);
 
+static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
+
 module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
 __MODULE_PARM_TYPE(create, "string");
 MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
@@ -141,6 +143,7 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
 	.ddp_setup = fcoe_ddp_setup,
 	.ddp_done = fcoe_ddp_done,
 	.elsct_send = fcoe_elsct_send,
+	.get_lesb = fcoe_get_lesb,
 };
 
 struct fc_function_template fcoe_transport_function = {
@@ -2455,3 +2458,34 @@ static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
 	lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID,
 			     NULL, NULL, 3 * lport->r_a_tov);
 }
+
+/**
+ * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
+ * @lport: the local port
+ * @fc_lesb: the link error status block
+ */
+static void fcoe_get_lesb(struct fc_lport *lport,
+			 struct fc_els_lesb *fc_lesb)
+{
+	unsigned int cpu;
+	u32 lfc, vlfc, mdac;
+	struct fcoe_dev_stats *devst;
+	struct fcoe_fc_els_lesb *lesb;
+	struct net_device *netdev = fcoe_netdev(lport);
+
+	lfc = 0;
+	vlfc = 0;
+	mdac = 0;
+	lesb = (struct fcoe_fc_els_lesb *)fc_lesb;
+	memset(lesb, 0, sizeof(*lesb));
+	for_each_possible_cpu(cpu) {
+		devst = per_cpu_ptr(lport->dev_stats, cpu);
+		lfc += devst->LinkFailureCount;
+		vlfc += devst->VLinkFailureCount;
+		mdac += devst->MissDiscAdvCount;
+	}
+	lesb->lesb_link_fail = htonl(lfc);
+	lesb->lesb_vlink_fail = htonl(vlfc);
+	lesb->lesb_miss_fka = htonl(mdac);
+	lesb->lesb_fcs_error = htonl(dev_get_stats(netdev)->rx_crc_errors);
+}
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index b97be29..4b912ee 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -511,6 +511,12 @@ struct libfc_function_template {
 	 */
 	int (*ddp_done)(struct fc_lport *, u16);
 	/*
+	 * Allow LLD to fill its own Link Error Status Block
+	 *
+	 * STATUS: OPTIONAL
+	 */
+	void (*get_lesb)(struct fc_lport *, struct fc_els_lesb *lesb);
+	/*
 	 * Send a frame using an existing sequence and exchange.
 	 *
 	 * STATUS: OPTIONAL


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 9/9] libfc: add support of receiving ELS_RLS
  2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
                   ` (7 preceding siblings ...)
  2009-11-20 22:55 ` [PATCH 8/9] fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB) Robert Love
@ 2009-11-20 22:55 ` Robert Love
  8 siblings, 0 replies; 10+ messages in thread
From: Robert Love @ 2009-11-20 22:55 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi; +Cc: Yi Zou, Robert Love

From: Yi Zou <yi.zou@intel.com>

Upon receiving ELS_RLS, send the Link Error Status Block (LESB) back.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---

 drivers/scsi/libfc/fc_rport.c |   76 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 91e2ba2..35ca0e7 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -1098,6 +1098,78 @@ drop:
 }
 
 /**
+ * fc_rport_recv_rls_req() - Handle received Read Link Status request
+ * @rdata: The remote port that sent the RLS request
+ * @sp:	The sequence that the RLS was on
+ * @rx_fp: The PRLI request frame
+ *
+ * Locking Note: The rport lock is expected to be held before calling
+ * this function.
+ */
+static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
+				  struct fc_seq *sp, struct fc_frame *rx_fp)
+
+{
+	struct fc_lport *lport = rdata->local_port;
+	struct fc_frame *fp;
+	struct fc_exch *ep = fc_seq_exch(sp);
+	struct fc_els_rls *rls;
+	struct fc_els_rls_resp *rsp;
+	struct fc_els_lesb *lesb;
+	struct fc_seq_els_data rjt_data;
+	struct fc_host_statistics *hst;
+	u32 f_ctl;
+
+	FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",
+		     fc_rport_state(rdata));
+
+	rls = fc_frame_payload_get(rx_fp, sizeof(*rls));
+	if (!rls) {
+		rjt_data.reason = ELS_RJT_PROT;
+		rjt_data.explan = ELS_EXPL_INV_LEN;
+		goto out_rjt;
+	}
+
+	fp = fc_frame_alloc(lport, sizeof(*rsp));
+	if (!fp) {
+		rjt_data.reason = ELS_RJT_UNAB;
+		rjt_data.explan = ELS_EXPL_INSUF_RES;
+		goto out_rjt;
+	}
+
+	rsp = fc_frame_payload_get(fp, sizeof(*rsp));
+	memset(rsp, 0, sizeof(*rsp));
+	rsp->rls_cmd = ELS_LS_ACC;
+	lesb = &rsp->rls_lesb;
+	if (lport->tt.get_lesb) {
+		/* get LESB from LLD if it supports it */
+		lport->tt.get_lesb(lport, lesb);
+	} else {
+		fc_get_host_stats(lport->host);
+		hst = &lport->host_stats;
+		lesb->lesb_link_fail = htonl(hst->link_failure_count);
+		lesb->lesb_sync_loss = htonl(hst->loss_of_sync_count);
+		lesb->lesb_sig_loss = htonl(hst->loss_of_signal_count);
+		lesb->lesb_prim_err = htonl(hst->prim_seq_protocol_err_count);
+		lesb->lesb_inv_word = htonl(hst->invalid_tx_word_count);
+		lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);
+	}
+
+	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,
+		       FC_TYPE_ELS, f_ctl, 0);
+	lport->tt.seq_send(lport, sp, fp);
+	goto out;
+
+out_rjt:
+	rjt_data.fp = NULL;
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
+out:
+	fc_frame_free(rx_fp);
+}
+
+/**
  * fc_rport_recv_els_req() - Handler for validated ELS requests
  * @lport: The local port that received the ELS request
  * @sp:	   The sequence that the ELS request was on
@@ -1159,6 +1231,9 @@ static void fc_rport_recv_els_req(struct fc_lport *lport,
 		els_data.fp = fp;
 		lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
 		break;
+	case ELS_RLS:
+		fc_rport_recv_rls_req(rdata, sp, fp);
+		break;
 	default:
 		fc_frame_free(fp);	/* can't happen */
 		break;
@@ -1203,6 +1278,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
 	case ELS_ADISC:
 	case ELS_RRQ:
 	case ELS_REC:
+	case ELS_RLS:
 		fc_rport_recv_els_req(lport, sp, fp);
 		break;
 	default:


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-11-20 22:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-20 22:54 [PATCH 0/9] libfc, libfcoe and fcoe updates for scsi-misc.git (2.6.33) Robert Love
2009-11-20 22:54 ` [PATCH 1/9] libfc: fix payload size passed to fc_frame_alloc() in fc_lport_els_request Robert Love
2009-11-20 22:54 ` [PATCH 2/9] fcoe: allow SCSI-FCP to be processed directly in softirq context Robert Love
2009-11-20 22:54 ` [PATCH 3/9] libfc: add FC-BB-5 LESB counters to fcoe_dev_stats Robert Love
2009-11-20 22:54 ` [PATCH 4/9] libfcoe: add checking disable flag in FIP_FKA_ADV Robert Love
2009-11-20 22:55 ` [PATCH 5/9] libfcoe: add tracking FIP Virtual Link Failure count Robert Love
2009-11-20 22:55 ` [PATCH 6/9] libfcoe: add tracking FIP Missing Discovery Advertisement count Robert Love
2009-11-20 22:55 ` [PATCH 7/9] libfc: add fcoe_fc_els_lesb to fc_fcoe.h for FC-BB-5 LESB definitions Robert Love
2009-11-20 22:55 ` [PATCH 8/9] fcoe, libfc: add get_lesb() to allow LLD to fill the link error status block (LESB) Robert Love
2009-11-20 22:55 ` [PATCH 9/9] libfc: add support of receiving ELS_RLS Robert Love

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.