From: Robert Love <robert.w.love@intel.com>
To: James.Bottomley@HansenPartnership.com, linux-scsi@vger.kernel.org
Cc: Vasu Dev <vasu.dev@intel.com>, Robert Love <robert.w.love@intel.com>
Subject: [PATCH 14/22] fcoe, libfc: adds exchange manager(EM) anchor list per lport and related APIs
Date: Wed, 29 Jul 2009 17:05:00 -0700 [thread overview]
Message-ID: <20090730000459.24658.80908.stgit@localhost.localdomain> (raw)
In-Reply-To: <20090730000345.24658.24830.stgit@localhost.localdomain>
From: Vasu Dev <vasu.dev@intel.com>
Adds EM list using a anchor struct fc_exch_mgr_anchor, anchor is used
to allow same EM instance sharing across more than one lport on a eth
device, this implementation is per discussed design posted at
http://www.open-fcoe.org/pipermail/devel/2009-June/002566.html.
The shared EM is required for multiple lports on eth device when
using multiple VLANs or NPIV.
Adds fc_exch_mgr_add API to add a EM to the lport and fc_exch_mgr_del
API to delete previously added EM.
Also adds function fc_exch_mgr_destroy() to destroy allocated EM.
The kref is added to the EM to keep track of EM usage count, the EM is
destroyed when no longer in use upon kref reaching to zero.
The caller can specify match function to fc_exch_mgr_add, this
will be used in determining exchange allocation from its EM or not.
Moved calling of fcoe_em_config below fcoe_libfc_config calling,
so that list head lp->ema_list is initialized before configuring
EM.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
---
drivers/scsi/fcoe/fcoe.c | 14 ++++++------
drivers/scsi/libfc/fc_exch.c | 48 +++++++++++++++++++++++++++++++++++++++++
drivers/scsi/libfc/fc_lport.c | 1 +
include/scsi/libfc.h | 24 +++++++++++++++++++++
4 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 14a4017..719a99d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -603,18 +603,18 @@ static int fcoe_if_create(struct net_device *netdev)
goto out_netdev_cleanup;
}
- /* lport exch manager allocation */
- rc = fcoe_em_config(lp);
+ /* Initialize the library */
+ rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
if (rc) {
- FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
+ FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
"interface\n");
- goto out_netdev_cleanup;
+ goto out_lp_destroy;
}
- /* Initialize the library */
- rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
+ /* lport exch manager allocation */
+ rc = fcoe_em_config(lp);
if (rc) {
- FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
+ FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
"interface\n");
goto out_lp_destroy;
}
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index cab5499..f1fa2b1 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -55,6 +55,7 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
*/
struct fc_exch_mgr {
enum fc_class class; /* default class for sequences */
+ struct kref kref; /* exchange mgr reference count */
spinlock_t em_lock; /* exchange manager lock,
must be taken before ex_lock */
u16 last_xid; /* last allocated exchange ID */
@@ -84,6 +85,12 @@ struct fc_exch_mgr {
};
#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
+struct fc_exch_mgr_anchor {
+ struct list_head ema_list;
+ struct fc_exch_mgr *mp;
+ bool (*match)(struct fc_frame *);
+};
+
static void fc_exch_rrq(struct fc_exch *);
static void fc_seq_ls_acc(struct fc_seq *);
static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
@@ -1729,6 +1736,47 @@ reject:
fc_frame_free(fp);
}
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
+ struct fc_exch_mgr *mp,
+ bool (*match)(struct fc_frame *))
+{
+ struct fc_exch_mgr_anchor *ema;
+
+ ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
+ if (!ema)
+ return ema;
+
+ ema->mp = mp;
+ ema->match = match;
+ /* add EM anchor to EM anchors list */
+ list_add_tail(&ema->ema_list, &lport->ema_list);
+ kref_get(&mp->kref);
+ return ema;
+}
+EXPORT_SYMBOL(fc_exch_mgr_add);
+
+static void fc_exch_mgr_destroy(struct kref *kref)
+{
+ struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
+
+ /*
+ * The total exch count must be zero
+ * before freeing exchange manager.
+ */
+ WARN_ON(mp->total_exches != 0);
+ mempool_destroy(mp->ep_pool);
+ kfree(mp);
+}
+
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
+{
+ /* remove EM anchor from EM anchors list */
+ list_del(&ema->ema_list);
+ kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
+ kfree(ema);
+}
+EXPORT_SYMBOL(fc_exch_mgr_del);
+
struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
enum fc_class class,
u16 min_xid, u16 max_xid)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index a430335..ca8ea26 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1618,6 +1618,7 @@ int fc_lport_init(struct fc_lport *lport)
if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
+ INIT_LIST_HEAD(&lport->ema_list);
return 0;
}
EXPORT_SYMBOL(fc_lport_init);
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 04db7a9..b381b1c 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -348,6 +348,7 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
*/
struct fc_exch_mgr;
+struct fc_exch_mgr_anchor;
/*
* Sequence.
@@ -709,6 +710,7 @@ struct fc_lport {
/* Associations */
struct Scsi_Host *host;
struct fc_exch_mgr *emp;
+ struct list_head ema_list;
struct fc_rport *dns_rp;
struct fc_rport *ptp_rp;
void *scsi_priv;
@@ -964,6 +966,28 @@ int fc_elsct_init(struct fc_lport *lp);
int fc_exch_init(struct fc_lport *lp);
/*
+ * Adds Exchange Manager (EM) mp to lport.
+ *
+ * Adds specified mp to lport using struct fc_exch_mgr_anchor,
+ * the struct fc_exch_mgr_anchor allows same EM sharing by
+ * more than one lport with their specified match function,
+ * the match function is used in allocating exchange from
+ * added mp.
+ */
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
+ struct fc_exch_mgr *mp,
+ bool (*match)(struct fc_frame *));
+
+/*
+ * Deletes Exchange Manager (EM) from lport by removing
+ * its anchor ema from lport.
+ *
+ * If removed anchor ema was the last user of its associated EM
+ * then also destroys associated EM.
+ */
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema);
+
+/*
* Allocates an Exchange Manager (EM).
*
* The EM manages exchanges for their allocation and
next prev parent reply other threads:[~2009-07-30 0:04 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-30 0:03 [PATCH 00/22] Open-FCoE Features for 2.6.32 Robert Love
2009-07-30 0:03 ` [PATCH 01/22] fcoe: Fix validation of mac address when checking for spma support Robert Love
2009-07-30 0:03 ` [PATCH 02/22] libfcoe: Set fip_flags according to fcf and lport's capability of SPMA support Robert Love
2009-07-30 0:04 ` [PATCH 03/22] fcoe: Call dev_ethtool_get_settings() in fcoe_link_ok Robert Love
2009-07-30 0:04 ` [PATCH 04/22] libfc: remove extra semicolons from debug macros Robert Love
2009-07-30 0:04 ` [PATCH 05/22] libfc: change debug messages to give host number Robert Love
2009-07-30 0:04 ` [PATCH 06/22] fcoe: stop delivery of received frames before doing lport_destroy() Robert Love
2009-07-30 0:04 ` [PATCH 07/22] libfc: rename lport NONE state to DISABLED Robert Love
2009-07-30 0:04 ` [PATCH 08/22] libfc: stop login after fabric logoff Robert Love
2009-07-30 0:04 ` [PATCH 09/22] libfc: in fc_lport_destroy, flush rports after turning off link Robert Love
2009-07-30 0:04 ` [PATCH 10/22] libfc: fix WARNING from fc_seq_start_next on closed exchanges Robert Love
2009-07-30 0:04 ` [PATCH 11/22] libfc: rename rport state "NONE" to "DELETE" Robert Love
2009-07-30 0:04 ` [PATCH 12/22] libfc: fc_rport_logoff should not drop the lock Robert Love
2009-07-30 0:04 ` [PATCH 13/22] libfc: fix: cancel rport retry timer Robert Love
2009-07-30 0:05 ` Robert Love [this message]
2009-07-30 0:05 ` [PATCH 15/22] libfc: Remove the FC_EM_DBG macro Robert Love
2009-07-30 0:05 ` [PATCH 16/22] fcoe, fnic, libfc: modifies current code paths to use EM anchor list Robert Love
2009-07-30 0:05 ` [PATCH 17/22] fcoe: modifies fcoe_hostlist_lock uses as prep work to add shared offload EM Robert Love
2009-07-30 0:05 ` [PATCH 18/22] fcoe, libfc: adds offload EM per eth device with only single xid range per EM Robert Love
2009-07-30 0:05 ` [PATCH 19/22] fcoe: Remove ifdef for NETIF_F_FCOE_CRC and NETIF_F_FSO Robert Love
2009-07-30 0:05 ` [PATCH 20/22] libfc: Remove FC_FRAME_SG_LEN in fc_fcp_send_data Robert Love
2009-07-30 0:05 ` [PATCH 21/22] libfc: Remove page flags check for sglist Robert Love
2009-07-30 0:05 ` [PATCH 22/22] fcoe: removes phys_dev and renames real_dev to netdev 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=20090730000459.24658.80908.stgit@localhost.localdomain \
--to=robert.w.love@intel.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=linux-scsi@vger.kernel.org \
--cc=vasu.dev@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox