linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Robert Love <robert.w.love@intel.com>
To: James.Bottomley@suse.de, linux-scsi@vger.kernel.org
Cc: Joe Eykholt <jeykholt@cisco.com>
Subject: [PATCH 06/28] libfc: convert rport lookup to be RCU safe
Date: Tue, 20 Jul 2010 15:19:37 -0700	[thread overview]
Message-ID: <20100720221937.17116.35940.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100720221904.17116.78553.stgit@localhost.localdomain>

From: Joe Eykholt <jeykholt@cisco.com>

To allow LLD to do lookups on rports without grabbing a mutex,
make them RCU-safe.  The caller of lport->tt.rport_lookup will
have the choice of holding disc_mutex or the rcu_read_lock().

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
 drivers/scsi/libfc/fc_disc.c  |    6 +++---
 drivers/scsi/libfc/fc_rport.c |   22 ++++++++++++++++++----
 include/scsi/libfc.h          |    2 ++
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index c7985da..d0fa9a0 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -63,12 +63,12 @@ static void fc_disc_restart(struct fc_disc *);
 void fc_disc_stop_rports(struct fc_disc *disc)
 {
 	struct fc_lport *lport;
-	struct fc_rport_priv *rdata, *next;
+	struct fc_rport_priv *rdata;
 
 	lport = disc->lport;
 
 	mutex_lock(&disc->disc_mutex);
-	list_for_each_entry_safe(rdata, next, &disc->rports, peers)
+	list_for_each_entry_rcu(rdata, &disc->rports, peers)
 		lport->tt.rport_logoff(rdata);
 	mutex_unlock(&disc->disc_mutex);
 }
@@ -292,7 +292,7 @@ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event)
 	 * Skip ports which were never discovered.  These are the dNS port
 	 * and ports which were created by PLOGI.
 	 */
-	list_for_each_entry(rdata, &disc->rports, peers) {
+	list_for_each_entry_rcu(rdata, &disc->rports, peers) {
 		if (!rdata->disc_id)
 			continue;
 		if (rdata->disc_id == disc->disc_id)
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 363cde3..6b56973 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -95,13 +95,15 @@ static const char *fc_rport_state_names[] = {
  * fc_rport_lookup() - Lookup a remote port by port_id
  * @lport:   The local port to lookup the remote port on
  * @port_id: The remote port ID to look up
+ *
+ * The caller must hold either disc_mutex or rcu_read_lock().
  */
 static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
 					     u32 port_id)
 {
 	struct fc_rport_priv *rdata;
 
-	list_for_each_entry(rdata, &lport->disc.rports, peers)
+	list_for_each_entry_rcu(rdata, &lport->disc.rports, peers)
 		if (rdata->ids.port_id == port_id)
 			return rdata;
 	return NULL;
@@ -146,11 +148,23 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
 	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
 	INIT_WORK(&rdata->event_work, fc_rport_work);
 	if (port_id != FC_FID_DIR_SERV)
-		list_add(&rdata->peers, &lport->disc.rports);
+		list_add_rcu(&rdata->peers, &lport->disc.rports);
 	return rdata;
 }
 
 /**
+ * fc_rport_free_rcu() - Free a remote port
+ * @rcu: The rcu_head structure inside the remote port
+ */
+static void fc_rport_free_rcu(struct rcu_head *rcu)
+{
+	struct fc_rport_priv *rdata;
+
+	rdata = container_of(rcu, struct fc_rport_priv, rcu);
+	kfree(rdata);
+}
+
+/**
  * fc_rport_destroy() - Free a remote port after last reference is released
  * @kref: The remote port's kref
  */
@@ -159,7 +173,7 @@ static void fc_rport_destroy(struct kref *kref)
 	struct fc_rport_priv *rdata;
 
 	rdata = container_of(kref, struct fc_rport_priv, kref);
-	kfree(rdata);
+	call_rcu(&rdata->rcu, fc_rport_free_rcu);
 }
 
 /**
@@ -334,7 +348,7 @@ static void fc_rport_work(struct work_struct *work)
 				mutex_unlock(&rdata->rp_mutex);
 			} else {
 				FC_RPORT_DBG(rdata, "work delete\n");
-				list_del(&rdata->peers);
+				list_del_rcu(&rdata->peers);
 				mutex_unlock(&rdata->rp_mutex);
 				kref_put(&rdata->kref, lport->tt.rport_destroy);
 			}
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 6d78df7..b0310b9 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -195,6 +195,7 @@ struct fc_rport_libfc_priv {
  * @rp_mutex:       The mutex that protects the remote port
  * @retry_work:     Handle for retries
  * @event_callback: Callback when READY, FAILED or LOGO states complete
+ * @rcu:	    Structure used for freeing in an RCU-safe manner
  */
 struct fc_rport_priv {
 	struct fc_lport		    *local_port;
@@ -217,6 +218,7 @@ struct fc_rport_priv {
 	struct list_head            peers;
 	struct work_struct          event_work;
 	u32			    supported_classes;
+	struct rcu_head		    rcu;
 };
 
 /**


  parent reply	other threads:[~2010-07-20 22:19 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-20 22:19 [PATCH 00/28] libfc, libfcoe and fcoe updates for scsi-misc Robert Love
2010-07-20 22:19 ` [PATCH 01/28] libfc: fix slowpath error from WARN_ON in fc_fcp_send_data Robert Love
2010-07-20 22:19 ` [PATCH 02/28] fcoe: make it possible to verify fcoe with sparse Robert Love
2010-07-20 22:19 ` [PATCH 03/28] libfc: IO errors on link down due to cable unplug Robert Love
2010-07-21  3:29   ` Mike Christie
2010-07-27 21:32     ` Vasu Dev
2010-07-27 22:08       ` Mike Christie
2010-07-28  7:32       ` Mike Christie
2010-07-30 20:34         ` Vasu Dev
2010-07-20 22:19 ` [PATCH 04/28] fcoe: cleans up fcoe_disable and fcoe_enable Robert Love
2010-07-20 22:19 ` [PATCH 05/28] fcoe: adds src and dest mac address checking for fcoe frames Robert Love
2010-07-20 22:19 ` Robert Love [this message]
2010-07-20 22:19 ` [PATCH 07/28] libfc: provide space for LLD after remote port structure Robert Love
2010-07-20 22:19 ` [PATCH 08/28] libfcoe: convert FIP to lock with mutex instead of spin lock Robert Love
2010-07-20 22:19 ` [PATCH 09/28] libfc: add discovery-private pointer for LLD Robert Love
2010-07-20 22:19 ` [PATCH 10/28] libfcoe: fcoe: fnic: change fcoe_ctlr_init interface to specify mode Robert Love
2010-07-20 22:20 ` [PATCH 11/28] libfc: Add local port point-to-multipoint flag Robert Love
2010-07-20 22:20 ` [PATCH 12/28] libfc: add FLOGI state to rport for VN2VN Robert Love
2010-07-20 22:20 ` [PATCH 13/28] libfc: track FIP exchanges Robert Love
2010-07-20 22:20 ` [PATCH 14/28] libfcoe: add protocol description of FIP VN2VN mode Robert Love
2010-07-20 22:20 ` [PATCH 15/28] libfcoe: add state change debugging Robert Love
2010-07-20 22:20 ` [PATCH 16/28] libfcoe: fcoe: fnic: add FIP VN2VN point-to-multipoint support Robert Love
2010-07-20 22:20 ` [PATCH 17/28] libfcoe: Fix FIP ELS encapsulation details for FLOGI responses Robert Love
2010-07-20 22:20 ` [PATCH 18/28] fcoe libfcoe: use correct FC-MAP for VN2VN mode Robert Love
2010-07-20 22:20 ` [PATCH 19/28] fcoe: config via separate create_vn2vn module parameter Robert Love
2010-07-20 22:20 ` [PATCH 20/28] libfc: eliminate rport LOGO state Robert Love
2010-07-20 22:20 ` [PATCH 21/28] libfc: add fc_frame_sid() and fc_frame_did() functions Robert Love
2010-07-20 22:21 ` [PATCH 22/28] libfc: add fc_fill_reply_hdr() and fc_fill_hdr() Robert Love
2010-07-20 22:21 ` [PATCH 23/28] libfc: add interface to allocate a sequence for incoming requests Robert Love
2010-07-20 22:21 ` [PATCH 24/28] libfc: don't require a local exchange " Robert Love
2010-07-20 22:21 ` [PATCH 25/28] fcoe: fix offload feature flag change from netdev Robert Love
2010-07-20 22:21 ` [PATCH 26/28] Revert "[SCSI] fcoe: Fix using VLAN ID in creating lport's WWWN/WWPN" Robert Love
2010-07-20 22:21 ` [PATCH 27/28] libfc: Add retry logic to lport state machine when receiving LS_RJT Robert Love
2010-07-20 22:21 ` [PATCH 28/28] fcoe: remove check for zero fabric name 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=20100720221937.17116.35940.stgit@localhost.localdomain \
    --to=robert.w.love@intel.com \
    --cc=James.Bottomley@suse.de \
    --cc=jeykholt@cisco.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;
as well as URLs for NNTP newsgroup(s).