[Open-FCoE] [RFC PATCH 3/6] libfc, fcoe: allows adding existing em instance to a lport

Vasu Dev vasu.dev at intel.com
Wed Apr 29 15:15:08 UTC 2009


This is to allow same offload xid em instance to be shared
by all VN_PORTs/lport on a eth device.

Adds em instance pointer mp to fc_exch_mgr_alloc and reference
counting for a em instance by added em_user counter.

The fc_exch_mgr_alloc adds specified mp to em_list of lport
and bumps up em_user count, the fc_exch_mgr_free does inverse
of this to free an mp.

Removes unnecessary initialization of mp->total_exches.

Signed-off-by: Vasu Dev <vasu.dev at intel.com>
---

 drivers/scsi/fcoe/fcoe.c     |    2 +-
 drivers/scsi/libfc/fc_exch.c |   27 +++++++++++++++++++++++----
 include/scsi/libfc.h         |    4 ++++
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index e829630..fde0f29 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -328,7 +328,7 @@ static inline int fcoe_em_config(struct fc_lport *lp)
 {
 	BUG_ON(lp->emp);
 
-	lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
+	lp->emp = fc_exch_mgr_alloc(lp, NULL, FC_CLASS_3,
 				    FCOE_MIN_XID, FCOE_MAX_XID);
 	if (!lp->emp)
 		return -ENOMEM;
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index bf50fc2..c640886 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -68,6 +68,7 @@ struct fc_exch_mgr {
 	enum fc_class	class;		/* default class for sequences */
 	spinlock_t	em_lock;	/* exchange manager lock,
 					   must be taken before ex_lock */
+	u16		em_user;	/* exchange manager user count */
 	u16		last_xid;	/* last allocated exchange ID */
 	u16		min_xid;	/* min exchange ID */
 	u16		max_xid;	/* max exchange ID */
@@ -1688,12 +1689,25 @@ reject:
 }
 
 struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
+				      struct fc_exch_mgr *mp,
 				      enum fc_class class,
 				      u16 min_xid, u16 max_xid)
 {
-	struct fc_exch_mgr *mp;
 	size_t len;
 
+	/*
+	 * if an existing em instance specified
+	 * then skip allocating new em instance
+	 */
+	if (mp) {
+		if (mp->min_xid != min_xid || mp->max_xid != max_xid ||
+		    mp->class != class) {
+			FC_DBG("Existing em instance config mismatched\n");
+			return NULL;
+		}
+		goto add_em;
+	}
+
 	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN) {
 		FC_DBG("Invalid min_xid 0x:%x and max_xid 0x:%x\n",
 		       min_xid, max_xid);
@@ -1711,7 +1725,6 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 		return NULL;
 
 	mp->class = class;
-	mp->total_exches = 0;
 	mp->exches = (struct fc_exch **)(mp + 1);
 	mp->lp = lp;
 	/* adjust em exch xid range for offload */
@@ -1726,6 +1739,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 	if (!mp->ep_pool)
 		goto free_mp;
 
+add_em:
+	mp->em_user++;
 	/* add em to the em_list */
 	list_add_tail(&mp->em_list, &lp->em_list);
 	return mp;
@@ -1739,13 +1754,17 @@ EXPORT_SYMBOL(fc_exch_mgr_alloc);
 void fc_exch_mgr_free(struct fc_exch_mgr *mp)
 {
 	WARN_ON(!mp);
+
+	/* remove em from the em_list */
+	list_del(&mp->em_list);
+	if (--mp->em_user)
+		return;
+
 	/*
 	 * The total exch count must be zero
 	 * before freeing exchange manager.
 	 */
 	WARN_ON(mp->total_exches != 0);
-	/* remove em from the em_list */
-	list_del(&mp->em_list);
 	mempool_destroy(mp->ep_pool);
 	kfree(mp);
 }
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index edfd9da..9ec2b25 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -911,6 +911,9 @@ int fc_exch_init(struct fc_lport *lp);
  * free, also allows exchange lookup for received
  * frame.
  *
+ * Caller may specify an existing EM instance to be
+ * added to the fc_lport in mp instead allocating new EM.
+ *
  * The class is used for initializing FC class of
  * allocated exchange from EM.
  *
@@ -926,6 +929,7 @@ int fc_exch_init(struct fc_lport *lp);
  * The em_idx to uniquely identify an EM instance.
  */
 struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
+				      struct fc_exch_mgr *mp,
 				      enum fc_class class,
 				      u16 min_xid,
 				      u16 max_xid);




More information about the devel mailing list