Currently part of total xid range of default exchange manger (EM)
lp->emp is reserved as offload xids(DDP) range, this is not
effective for these reason:
1. This won't allow full DDP xid range sharing on demand across
multiple VN_PORT on a eth device for either NPIV or VLAN,
the VN_PORT is the lport instance in libfc implementation.
2. Requires additional checks in fast path for two xid range
management within a single EM instance
This patch removes code reserving offload xids range and instead
by end of this patch series, a dedicated EM instance will be
allocated for this range to allow effective offload xid space
sharing across multiple lports on a eth device.
Completely removes func fc_em_alloc_xid needed for selecting a
xid from two ranges, instead adds simple logic to allocate xid
with fewer args to fc_exch_alloc, removes no longer needed fp
and xid args to fc_exch_alloc.
RFC notes:-
1. Get review comments for modified code to address review comments
from http://www.open-fcoe.org/pipermail/devel/2009-May/002329.html
2. I've tested this series for single interface since I could n't
get setup ready for multiple VLAN on eth interface on fabric
side to test shared em code. Now that NPIV is ready so I will
test with NPIV but NPIV code is also new code, so finding any
issues by review will be more helpful to test shared EM code with
NPIV, so I'd appreciate your feedback on any issues on this.
3. The patch 3 could be combined with patch 2, but to help review
and keep original code authorship clean, I kept patch 3 separate.
However if Rob agrees then I'll merge this patch 3 with patch 2.
4. The discussed em_list with match function will require more design
thoughts for shared em instance across lports, so I implemented
shared em using previously designed libfc interface of exch_get,
therefore the em_list with match func for shared em cannot be done
now or any soon. I think going into that direction will possible
delay other features depending on shared EM patches since as
I'm told NPIV is waiting for shared EM instance feature in line.
This series is based on following commit on fcoe-features tree:
commit 9da17a6c18a4db817d7c7605f2a7a98dfe41e572
Author: Vasu Dev <[email protected]>
Date: Thu May 28 15:34:56 2009 -0700
fcoe: removes fcoe_watchdog
Signed-off-by: Vasu Dev <[email protected]>
---
drivers/scsi/libfc/fc_exch.c | 92 +++++++-----------------------------------
include/scsi/libfc.h | 5 --
2 files changed, 17 insertions(+), 80 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 2bc22be..bbabd2c 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -60,9 +60,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 */
@@ -461,64 +459,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);
@@ -528,16 +477,18 @@ 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_WARNING "libfc: Failed to allocate an
exhange\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)
goto err;
- }
}
+ mp->last_xid = xid;
fc_exch_hold(ep); /* hold for exch in mp */
spin_lock_init(&ep->ex_lock);
@@ -1730,7 +1681,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_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
min_xid, max_xid);
return NULL;
@@ -1739,7 +1690,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);
@@ -1754,17 +1704,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);
@@ -1799,7 +1739,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);
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index b92584a..dde73cf 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -1044,11 +1044,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.
*/
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel