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 <[email protected]> --- 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); _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
