Adds pointer lp->oemp to lport to allow multiple lport to share offload em instance using this pointer.
Modifies fc_exch_mgr_reset to reset both lp->emp and lp->oemp. I used p suffix in naming to have new names aligned with existing names e.g. lp->emp, lp, mp etc. Adds APIs fc_exch_mgr_inc and fc_exch_mgr_dec to update added em usage counter em_user. The fc_exch_mgr_free decrements em_user counter and frees em when em_user counter reaches to zero. New em allocation increments em_user counter and this will be incremented for shared em instance use across lports on a eth a device in later patches of this series. Signed-off-by: Vasu Dev <[email protected]> --- drivers/scsi/fcoe/fcoe.c | 1 + drivers/scsi/libfc/fc_exch.c | 45 +++++++++++++++++++++++++++++++++++------- include/scsi/libfc.h | 12 +++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 8870948..ab238fb 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -427,6 +427,7 @@ static inline int fcoe_em_config(struct fc_lport *lp) { BUG_ON(lp->emp); + lp->oemp = NULL; lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, FCOE_MIN_XID, FCOE_MAX_XID); if (!lp->emp) diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index bbabd2c..bd6836b 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -57,6 +57,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 */ @@ -1404,21 +1405,17 @@ static void fc_exch_reset(struct fc_exch *ep) resp(sp, ERR_PTR(-FC_EX_CLOSED), arg); } -/* - * Reset an exchange manager, releasing all sequences and exchanges. - * If sid is non-zero, reset only exchanges we source from that FID. - * If did is non-zero, reset only exchanges destined to that FID. - */ -void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) +static void fc_exch_em_reset(struct fc_lport *lp, struct fc_exch_mgr *mp, + u32 sid, u32 did) { struct fc_exch *ep; struct fc_exch *next; - struct fc_exch_mgr *mp = lp->emp; spin_lock_bh(&mp->em_lock); restart: list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) { - if ((sid == 0 || sid == ep->sid) && + if ((lp == ep->lp) && + (sid == 0 || sid == ep->sid) && (did == 0 || did == ep->did)) { fc_exch_hold(ep); spin_unlock_bh(&mp->em_lock); @@ -1437,6 +1434,18 @@ restart: } spin_unlock_bh(&mp->em_lock); } + +/* + * Reset exchange managers, releasing all sequences and exchanges. + * If sid is non-zero, reset only exchanges we source from that FID. + * If did is non-zero, reset only exchanges destined to that FID. + */ +void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) +{ + fc_exch_em_reset(lp, lp->emp, sid, did); + if (lp->oemp) + fc_exch_em_reset(lp, lp->oemp, sid, did); +} EXPORT_SYMBOL(fc_exch_mgr_reset); /* @@ -1674,6 +1683,18 @@ reject: fc_frame_free(fp); } +void fc_exch_mgr_inc(struct fc_exch_mgr *mp) +{ + mp->em_user++; +} +EXPORT_SYMBOL(fc_exch_mgr_inc); + +int fc_exch_mgr_dec(struct fc_exch_mgr *mp) +{ + return --mp->em_user; +} +EXPORT_SYMBOL(fc_exch_mgr_dec); + struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, enum fc_class class, u16 min_xid, u16 max_xid) @@ -1713,6 +1734,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, if (!mp->ep_pool) goto free_mp; + fc_exch_mgr_inc(mp); return mp; free_mp: @@ -1724,6 +1746,13 @@ EXPORT_SYMBOL(fc_exch_mgr_alloc); void fc_exch_mgr_free(struct fc_exch_mgr *mp) { WARN_ON(!mp); + + /* + * if still in use then return + */ + if (fc_exch_mgr_dec(mp)) + return; + /* * The total exch count must be zero * before freeing exchange manager. diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index dde73cf..967f6f6 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -705,6 +705,8 @@ struct fc_lport { /* Associations */ struct Scsi_Host *host; struct fc_exch_mgr *emp; + struct fc_exch_mgr *oemp; + struct list_head em_list; struct fc_rport *dns_rp; struct fc_rport *ptp_rp; void *scsi_priv; @@ -960,6 +962,16 @@ int fc_elsct_init(struct fc_lport *lp); int fc_exch_init(struct fc_lport *lp); /* + * Increments usages count of an Exchange Manager. + */ +void fc_exch_mgr_inc(struct fc_exch_mgr *mp); + +/* + * Decrements usages count of an Exchange Manager. + */ +int fc_exch_mgr_dec(struct fc_exch_mgr *mp); + +/* * Allocates an Exchange Manager (EM). * * The EM manages exchanges for their allocation and _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
