From: Robert Love <robert.w.love@intel.com>
To: James.Bottomley@HansenPartnership.com, linux-scsi@vger.kernel.org
Cc: Chris Leech <christopher.leech@intel.com>,
Robert Love <robert.w.love@intel.com>
Subject: [PATCH 09/54] libfc: vport link handling and fc_vport state managment
Date: Tue, 03 Nov 2009 11:46:19 -0800 [thread overview]
Message-ID: <20091103194619.4085.47300.stgit@localhost.localdomain> (raw)
In-Reply-To: <20091103194530.4085.37963.stgit@localhost.localdomain>
From: Chris Leech <christopher.leech@intel.com>
NPIV vports are managed in libfc by changing their virtual link state
when the parent N_Ports internal state changes. The vport link is only
online when the N_Port is in a ready state (logged into the fabric).
vport_state is updated as needed in this patch as well, currently the states
LINKDOWN, INITIALIZING, ACTIVE, DSIABLED, and NO_FABRIC_SUPP are used.
This also changes the fc_host port_state handling to differentiate between
LINKDOWN and OFFLINE.
Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/libfc/fc_lport.c | 72 +++++++++++++++++++++++++++++++--------
drivers/scsi/libfc/fc_npiv.c | 75 +++++++++++++++++++++++++++++++++++++++++
include/scsi/libfc.h | 8 ++++
3 files changed, 140 insertions(+), 15 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 41650d3..46897cf 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -224,10 +224,18 @@ void fc_get_host_port_state(struct Scsi_Host *shost)
{
struct fc_lport *lp = shost_priv(shost);
- if (lp->link_up)
- fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+ mutex_lock(&lp->lp_mutex);
+ if (!lp->link_up)
+ fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
else
- fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+ switch (lp->state) {
+ case LPORT_ST_READY:
+ fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+ break;
+ default:
+ fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+ }
+ mutex_unlock(&lp->lp_mutex);
}
EXPORT_SYMBOL(fc_get_host_port_state);
@@ -493,40 +501,62 @@ int fc_fabric_login(struct fc_lport *lport)
EXPORT_SYMBOL(fc_fabric_login);
/**
- * fc_linkup() - Handler for transport linkup events
+ * __fc_linkup() - Handler for transport linkup events
* @lport: The lport whose link is up
+ *
+ * Locking: must be called with the lp_mutex held
*/
-void fc_linkup(struct fc_lport *lport)
+void __fc_linkup(struct fc_lport *lport)
{
- printk(KERN_INFO "libfc: Link up on port (%6x)\n",
- fc_host_port_id(lport->host));
-
- mutex_lock(&lport->lp_mutex);
if (!lport->link_up) {
lport->link_up = 1;
if (lport->state == LPORT_ST_RESET)
fc_lport_enter_flogi(lport);
}
+}
+
+/**
+ * fc_linkup() - Handler for transport linkup events
+ * @lport: The lport whose link is up
+ */
+void fc_linkup(struct fc_lport *lport)
+{
+ printk(KERN_INFO "libfc: Link up on port (%6x)\n",
+ fc_host_port_id(lport->host));
+
+ mutex_lock(&lport->lp_mutex);
+ __fc_linkup(lport);
mutex_unlock(&lport->lp_mutex);
}
EXPORT_SYMBOL(fc_linkup);
/**
- * fc_linkdown() - Handler for transport linkdown events
+ * __fc_linkdown() - Handler for transport linkdown events
* @lport: The lport whose link is down
+ *
+ * Locking: must be called with the lp_mutex held
*/
-void fc_linkdown(struct fc_lport *lport)
+void __fc_linkdown(struct fc_lport *lport)
{
- mutex_lock(&lport->lp_mutex);
- printk(KERN_INFO "libfc: Link down on port (%6x)\n",
- fc_host_port_id(lport->host));
-
if (lport->link_up) {
lport->link_up = 0;
fc_lport_enter_reset(lport);
lport->tt.fcp_cleanup(lport);
}
+}
+
+/**
+ * fc_linkdown() - Handler for transport linkdown events
+ * @lport: The lport whose link is down
+ */
+void fc_linkdown(struct fc_lport *lport)
+{
+ printk(KERN_INFO "libfc: Link down on port (%6x)\n",
+ fc_host_port_id(lport->host));
+
+ mutex_lock(&lport->lp_mutex);
+ __fc_linkdown(lport);
mutex_unlock(&lport->lp_mutex);
}
EXPORT_SYMBOL(fc_linkdown);
@@ -654,6 +684,9 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_READY);
+ if (lport->vport)
+ fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
+ fc_vports_linkchange(lport);
if (!lport->ptp_rp)
lport->tt.disc_start(fc_lport_disc_callback, lport);
@@ -868,7 +901,14 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
fc_lport_state(lport));
+ if (lport->vport) {
+ if (lport->link_up)
+ fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
+ else
+ fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
+ }
fc_lport_state_enter(lport, LPORT_ST_RESET);
+ fc_vports_linkchange(lport);
fc_lport_reset_locked(lport);
if (lport->link_up)
fc_lport_enter_flogi(lport);
@@ -887,6 +927,7 @@ static void fc_lport_enter_disabled(struct fc_lport *lport)
fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_DISABLED);
+ fc_vports_linkchange(lport);
fc_lport_reset_locked(lport);
}
@@ -1333,6 +1374,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
fc_lport_state(lport));
fc_lport_state_enter(lport, LPORT_ST_LOGO);
+ fc_vports_linkchange(lport);
fp = fc_frame_alloc(lport, sizeof(*logo));
if (!fp) {
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c
index 39f02c0..c68f6c7 100644
--- a/drivers/scsi/libfc/fc_npiv.c
+++ b/drivers/scsi/libfc/fc_npiv.c
@@ -84,3 +84,78 @@ struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
return lport;
}
+/*
+ * When setting the link state of vports during an lport state change, it's
+ * necessary to hold the lp_mutex of both the N_Port and the VN_Port.
+ * This tells the lockdep engine to treat the nested locking of the VN_Port
+ * as a different lock class.
+ */
+enum libfc_lport_mutex_class {
+ LPORT_MUTEX_NORMAL = 0,
+ LPORT_MUTEX_VN_PORT = 1,
+};
+
+/**
+ * __fc_vport_setlink() - update link and status on a VN_Port
+ * @n_port: parent N_Port
+ * @vn_port: VN_Port to update
+ *
+ * Locking: must be called with both the N_Port and VN_Port lp_mutex held
+ */
+static void __fc_vport_setlink(struct fc_lport *n_port,
+ struct fc_lport *vn_port)
+{
+ struct fc_vport *vport = vn_port->vport;
+
+ if (vn_port->state == LPORT_ST_DISABLED)
+ return;
+
+ if (n_port->state == LPORT_ST_READY) {
+ if (n_port->npiv_enabled) {
+ fc_vport_set_state(vport, FC_VPORT_INITIALIZING);
+ __fc_linkup(vn_port);
+ } else {
+ fc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
+ __fc_linkdown(vn_port);
+ }
+ } else {
+ fc_vport_set_state(vport, FC_VPORT_LINKDOWN);
+ __fc_linkdown(vn_port);
+ }
+}
+
+/**
+ * fc_vport_setlink() - update link and status on a VN_Port
+ * @vn_port: virtual port to update
+ */
+void fc_vport_setlink(struct fc_lport *vn_port)
+{
+ struct fc_vport *vport = vn_port->vport;
+ struct Scsi_Host *shost = vport_to_shost(vport);
+ struct fc_lport *n_port = shost_priv(shost);
+
+ mutex_lock(&n_port->lp_mutex);
+ mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+ __fc_vport_setlink(n_port, vn_port);
+ mutex_unlock(&vn_port->lp_mutex);
+ mutex_unlock(&n_port->lp_mutex);
+}
+EXPORT_SYMBOL(fc_vport_setlink);
+
+/**
+ * fc_vports_linkchange() - change the link state of all vports
+ * @n_port: Parent N_Port that has changed state
+ *
+ * Locking: called with the n_port lp_mutex held
+ */
+void fc_vports_linkchange(struct fc_lport *n_port)
+{
+ struct fc_lport *vn_port;
+
+ list_for_each_entry(vn_port, &n_port->vports, list) {
+ mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+ __fc_vport_setlink(n_port, vn_port);
+ mutex_unlock(&vn_port->lp_mutex);
+ }
+}
+
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 2c6d55d..dfeb1ee 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -788,11 +788,13 @@ int fc_fabric_login(struct fc_lport *lp);
/*
* The link is up for the given local port.
*/
+void __fc_linkup(struct fc_lport *);
void fc_linkup(struct fc_lport *);
/*
* Link is down for the given local port.
*/
+void __fc_linkdown(struct fc_lport *);
void fc_linkdown(struct fc_lport *);
/*
@@ -821,6 +823,12 @@ struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize);
struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id);
/*
+ * NPIV VN_Port link state management
+ */
+void fc_vport_setlink(struct fc_lport *vn_port);
+void fc_vports_linkchange(struct fc_lport *n_port);
+
+/*
* REMOTE PORT LAYER
*****************************/
int fc_rport_init(struct fc_lport *lp);
next prev parent reply other threads:[~2009-11-03 19:46 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-03 19:45 [PATCH 00/54] libfc, libfcoe, fcoe and fnic updates for 2.6.33 Robert Love
2009-11-03 19:45 ` [PATCH 01/54] fnic: Allocate OS interrupt resources just before enabling interrupts Robert Love
2009-11-03 19:45 ` [PATCH 02/54] fcoe: Increase FCOE_MAX_LUN to 0xFFFF (65535) Robert Love
2009-11-03 19:45 ` [PATCH 03/54] libfc: Move non-common routines and prototypes out of libfc.h Robert Love
2009-11-03 19:45 ` [PATCH 04/54] libfc: Remove fc_fcp_complete Robert Love
2009-11-03 19:45 ` [PATCH 05/54] libfc: Add libfc/fc_libfc.[ch] for libfc internal routines Robert Love
2009-11-03 19:46 ` [PATCH 06/54] libfc: Move libfc_init and libfc_exit to fc_libfc.c Robert Love
2009-11-03 19:46 ` [PATCH 07/54] libfc: changes to libfc_host_alloc to consolidate initialization with allocation Robert Love
2009-11-03 19:46 ` [PATCH 08/54] libfc: add some generic NPIV support routines to libfc Robert Love
2009-11-03 19:46 ` Robert Love [this message]
2009-11-03 19:46 ` [PATCH 10/54] libfc, libfcoe: FDISC ELS for NPIV Robert Love
2009-11-03 19:46 ` [PATCH 11/54] libfcoe, fcoe: libfcoe NPIV support Robert Love
2009-11-03 19:46 ` [PATCH 12/54] fcoe: add a separate scsi transport template for NPIV vports Robert Love
2009-11-03 19:46 ` [PATCH 13/54] fcoe: NPIV vport create/destroy Robert Love
2009-11-03 19:46 ` [PATCH 14/54] libfc: RPN_ID is obsolete and unnecessary Robert Love
2009-11-03 19:46 ` [PATCH 15/54] libfc: RNN_ID may be required before RSNN_NN with some switches Robert Love
2009-11-03 19:46 ` [PATCH 16/54] libfc: Register Symbolic Node Name (RSNN_NN) Robert Love
2009-11-03 19:47 ` [PATCH 17/54] libfc: Register Symbolic Port Name (RSPN_ID) Robert Love
2009-11-03 19:47 ` [PATCH 18/54] libfc: combine name server registration response handlers Robert Love
2009-11-03 19:47 ` [PATCH 19/54] libfc: combine name server registration request functions Robert Love
2009-11-03 19:47 ` [PATCH 20/54] fcoe: vport symbolic name support Robert Love
2009-11-03 19:47 ` [PATCH 21/54] libfc: Export FC headers Robert Love
2009-11-03 19:47 ` [PATCH 22/54] libfc: Add routine to copy data from a buffer to a SG list Robert Love
2009-11-03 19:47 ` [PATCH 23/54] libfc, fcoe: Add FC passthrough support Robert Love
2009-11-03 19:47 ` [PATCH 24/54] libfc: Formatting cleanups across libfc Robert Love
2009-11-03 19:47 ` [PATCH 25/54] libfcoe: formatting and comment cleanups Robert Love
2009-11-03 19:47 ` [PATCH 26/54] fcoe: Formatting cleanups and commenting Robert Love
2009-11-03 19:47 ` [PATCH 27/54] fcoe, libfc: use single frame allocation API Robert Love
2009-11-03 19:48 ` [PATCH 28/54] libfc: reduce can_queue for all FCP frame allocation failures Robert Love
2009-11-03 19:48 ` [PATCH 29/54] libfc: adds can_queue ramp up Robert Love
2009-11-03 19:48 ` [PATCH 30/54] libfcoe: Allow FIP to be disabled by the driver Robert Love
2009-11-03 19:48 ` [PATCH 31/54] libfcoe: fip: use SCSI host number to identify debug messages Robert Love
2009-11-03 19:48 ` [PATCH 32/54] libfcoe: fip: allow FIP receive to be called from IRQ Robert Love
2009-11-03 19:48 ` [PATCH 33/54] libfcoe: FIP should report link to libfc whether selected or not Robert Love
2009-11-03 19:48 ` [PATCH 34/54] libfcoe: don't send ELS in FIP mode if no FCF selected Robert Love
2009-11-03 19:48 ` [PATCH 35/54] fcoe: remove extra function decalrations Robert Love
2009-11-03 19:48 ` [PATCH 36/54] fcoe: add check to fail gracefully in bonding mode Robert Love
2009-11-03 19:48 ` [PATCH 37/54] libfc: fix RNN_ID smashing skb payload Robert Love
2009-11-03 19:48 ` [PATCH 38/54] libfc: fix symbolic name registrations smashing skb data Robert Love
2009-11-03 19:49 ` [PATCH 39/54] libfc: fix fc_els_resp_type to correct display of CT responses Robert Love
2009-11-03 19:49 ` [PATCH 40/54] libfc: add set_fid function to libfc template Robert Love
2009-11-03 19:49 ` [PATCH 41/54] libfc: add host number to lport link up/down messages Robert Love
2009-11-03 19:49 ` [PATCH 42/54] libfcoe: fcoe: simplify receive FLOGI response Robert Love
2009-11-03 19:49 ` [PATCH 43/54] fnic: Add FIP support to the fnic driver Robert Love
2009-11-03 19:49 ` [PATCH 44/54] libfc: register FC4 features with the FC switch Robert Love
2009-11-03 19:49 ` [PATCH 45/54] fnic: enable bsg pass-thru for fcping Robert Love
2009-11-03 19:49 ` [PATCH 46/54] fcoe: Fix checking san mac address Robert Love
2009-11-03 19:49 ` [PATCH 47/54] fcoe: Fix getting san mac for VLAN interface Robert Love
2009-11-03 19:49 ` [PATCH 48/54] fcoe: Fix setting lport's WWNN/WWPN to use san mac address Robert Love
2009-11-03 19:49 ` [PATCH 49/54] libfc: do not use DID_NO_CONNECT for pkt alloc failures Robert Love
2009-11-03 19:49 ` [PATCH 50/54] fcoe: Fix using VLAN ID in creating lport's WWWN/WWPN Robert Love
2009-11-03 19:50 ` [PATCH 51/54] libfc, fcoe: fixes for highmem skb linearize panics Robert Love
2009-11-03 19:50 ` [PATCH 52/54] libfc: fix an issue of pending exch/es after i/f destroyed or rmmod fcoe Robert Love
2009-11-03 19:50 ` [PATCH 53/54] libfcoe: Do not pad FIP keep-alive to full frame size Robert Love
2009-11-03 19:50 ` [PATCH 54/54] libfc fcoe: increase ELS and CT timeouts 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=20091103194619.4085.47300.stgit@localhost.localdomain \
--to=robert.w.love@intel.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=christopher.leech@intel.com \
--cc=linux-scsi@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox