[Open-FCoE] [RFC PATCH 1/6] libfc: removes code for reserving offload exch ids (xids) range

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


Reserving offload xids(DDP) range within single exchange manger (EM)
instance of a lport won't allow full DDP xid range sharing on demand
across multiple VN_PORT on a eth device, in case of libfc the
VN_PORT is the lport.

These multiple VN_PORT could be for either NPIV or FCoE over VLAN
and in that case same offload xids range tied to their eth device
need to be shared by all VN_PORTs, for that this patch series
allocates a dedicated EM instance for offload xids and then have it
shared by all VN_PORTs on demand using exch_get interface of libfc.

This patch removes offload xids range related code from libfc
from func fc_exch_mgr_alloc and completely removes related func
fc_em_alloc_xid earlier needed for selecting a xid from two ranges
of xids within a EM instance, which is no loner required after
dedicated EM instance in this patch series.

Instead of fc_em_alloc_xid, adds simple logic to allocate xid
which also make use of xid zero, xid zero was unused before, also
removes redundant fp and xid args to fc_exch_alloc.

Also removes unconditionally called to func fc_fcp_ddp_setup for
now and this patch series will add this again to exch_get once
dedicated EM instance for offload xid(DDP) range is done.

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

 drivers/scsi/libfc/fc_exch.c |   97 +++++++++---------------------------------
 include/scsi/libfc.h         |    5 --
 2 files changed, 21 insertions(+), 81 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 992af05..9869820 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -71,9 +71,7 @@ struct fc_exch_mgr {
 	u16		last_xid;	/* last allocated exchange ID */
 	u16		min_xid;	/* min exchange ID */
 	u16		max_xid;	/* max exchange ID */
-	u16		max_read;	/* max exchange ID for read */
-	u16		last_read;	/* last xid allocated for read */
-	u32	total_exches;		/* total allocated exchanges */
+	u32		total_exches;	/* total allocated exchanges */
 	struct list_head	ex_list;	/* allocated exchanges list */
 	struct fc_lport	*lp;		/* fc device instance */
 	mempool_t	*ep_pool;	/* reserve ep's */
@@ -472,64 +470,15 @@ static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
 }
 
 /*
- * fc_em_alloc_xid - returns an xid based on request type
- * @lp : ptr to associated lport
- * @fp : ptr to the assocated frame
- *
- * check the associated fc_fsp_pkt to get scsi command type and
- * command direction to decide from which range this exch id
- * will be allocated from.
- *
- * Returns : 0 or an valid xid
- */
-static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp)
-{
-	u16 xid, min, max;
-	u16 *plast;
-	struct fc_exch *ep = NULL;
-
-	if (mp->max_read) {
-		if (fc_fcp_is_read(fr_fsp(fp))) {
-			min = mp->min_xid;
-			max = mp->max_read;
-			plast = &mp->last_read;
-		} else {
-			min = mp->max_read + 1;
-			max = mp->max_xid;
-			plast = &mp->last_xid;
-		}
-	} else {
-		min = mp->min_xid;
-		max = mp->max_xid;
-		plast = &mp->last_xid;
-	}
-	xid = *plast;
-	do {
-		xid = (xid == max) ? min : xid + 1;
-		ep = mp->exches[xid - mp->min_xid];
-	} while ((ep != NULL) && (xid != *plast));
-
-	if (unlikely(ep))
-		xid = 0;
-	else
-		*plast = xid;
-
-	return xid;
-}
-
-/*
- * fc_exch_alloc - allocate an exchange.
+ * fc_exch_alloc - allocate an exchange and its exchange id.
  * @mp : ptr to the exchange manager
- * @xid: input xid
  *
- * if xid is supplied zero then assign next free exchange ID
- * from exchange manager, otherwise use supplied xid.
  * Returns with exch lock held.
  */
-struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
-			      struct fc_frame *fp, u16 xid)
+struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp)
 {
 	struct fc_exch *ep;
+	u16 min, max, xid;
 
 	/* allocate memory for exchange */
 	ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
@@ -539,16 +488,23 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
 	}
 	memset(ep, 0, sizeof(*ep));
 
+	min = mp->min_xid;
+	max = mp->max_xid;
+
 	spin_lock_bh(&mp->em_lock);
-	/* alloc xid if input xid 0 */
-	if (!xid) {
-		/* alloc a new xid */
-		xid = fc_em_alloc_xid(mp, fp);
-		if (!xid) {
-			printk(KERN_ERR "fc_em_alloc_xid() failed\n");
+
+	xid = mp->last_xid;
+	/* alloc a new xid */
+	while (mp->exches[xid - min]) {
+		xid = (xid == max) ? min : xid + 1;
+		if (xid == mp->last_xid) {
+			printk(KERN_ERR "out of free exch ids on em:"
+				"%p, min xid:%x and max xid:%x\n",
+				mp, min, max);
 			goto err;
 		}
 	}
+	mp->last_xid = xid;
 
 	fc_exch_hold(ep);	/* hold for exch in mp */
 	spin_lock_init(&ep->ex_lock);
@@ -1735,7 +1691,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 	struct fc_exch_mgr *mp;
 	size_t len;
 
-	if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) {
+	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);
 		return NULL;
@@ -1744,7 +1700,6 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 	/*
 	 * Memory need for EM
 	 */
-#define xid_ok(i, m1, m2) (((i) >= (m1)) && ((i) <= (m2)))
 	len = (max_xid - min_xid + 1) * (sizeof(struct fc_exch *));
 	len += sizeof(struct fc_exch_mgr);
 
@@ -1759,17 +1714,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 	/* adjust em exch xid range for offload */
 	mp->min_xid = min_xid;
 	mp->max_xid = max_xid;
-	mp->last_xid = min_xid - 1;
-	mp->max_read = 0;
-	mp->last_read = 0;
-	if (lp->lro_enabled && xid_ok(lp->lro_xid, min_xid, max_xid)) {
-		mp->max_read = lp->lro_xid;
-		mp->last_read = min_xid - 1;
-		mp->last_xid = mp->max_read;
-	} else {
-		/* disable lro if no xid control over read */
-		lp->lro_enabled = 0;
-	}
+	mp->last_xid = min_xid;
 
 	INIT_LIST_HEAD(&mp->ex_list);
 	spin_lock_init(&mp->em_lock);
@@ -1804,7 +1749,7 @@ struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp)
 	if (!lp || !lp->emp)
 		return NULL;
 
-	return fc_exch_alloc(lp->emp, fp, 0);
+	return fc_exch_alloc(lp->emp);
 }
 EXPORT_SYMBOL(fc_exch_get);
 
@@ -1841,8 +1786,6 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
 	sp->cnt++;
 
-	fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
-
 	if (unlikely(lp->tt.frame_send(lp, fp)))
 		goto err;
 
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 45f9cc6..fc2cbb9 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -988,11 +988,8 @@ struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
 
 /*
  * Allocate a new exchange and sequence pair.
- * if ex_id is zero then next free exchange id
- * from specified exchange manger mp will be assigned.
  */
-struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
-			      struct fc_frame *fp, u16 ex_id);
+struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp);
 /*
  * Start a new sequence on the same exchange as the supplied sequence.
  */




More information about the devel mailing list