[SCSI] fcoe: modifies fcoe_hostlist_lock uses as prep work to add shared offload EM
Modifies fcoe_hostlist_lock uses such that a new EM allocation in fcoe_em_config and adding new fcoe_softc using fcoe_hostlist_add are atomic, this is to ensure that a shared offload EM gets allocated only once per eth device for its all lports. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
Родитель
52ff878c91
Коммит
e8af4d4380
|
@ -419,6 +419,8 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
|
|||
* fcoe_em_config() - allocates em for this lport
|
||||
* @lp: the port that em is to allocated for
|
||||
*
|
||||
* Called with write fcoe_hostlist_lock held.
|
||||
*
|
||||
* Returns : 0 on success
|
||||
*/
|
||||
static inline int fcoe_em_config(struct fc_lport *lp)
|
||||
|
@ -607,6 +609,13 @@ static int fcoe_if_create(struct net_device *netdev)
|
|||
goto out_lp_destroy;
|
||||
}
|
||||
|
||||
/*
|
||||
* fcoe_em_alloc() and fcoe_hostlist_add() both
|
||||
* need to be atomic under fcoe_hostlist_lock
|
||||
* since fcoe_em_alloc() looks for an existing EM
|
||||
* instance on host list updated by fcoe_hostlist_add().
|
||||
*/
|
||||
write_lock(&fcoe_hostlist_lock);
|
||||
/* lport exch manager allocation */
|
||||
rc = fcoe_em_config(lp);
|
||||
if (rc) {
|
||||
|
@ -617,6 +626,7 @@ static int fcoe_if_create(struct net_device *netdev)
|
|||
|
||||
/* add to lports list */
|
||||
fcoe_hostlist_add(lp);
|
||||
write_unlock(&fcoe_hostlist_lock);
|
||||
|
||||
lp->boot_time = jiffies;
|
||||
|
||||
|
@ -1720,6 +1730,8 @@ int fcoe_reset(struct Scsi_Host *shost)
|
|||
* fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
|
||||
* @dev: this is currently ptr to net_device
|
||||
*
|
||||
* Called with fcoe_hostlist_lock held.
|
||||
*
|
||||
* Returns: NULL or the located fcoe_softc
|
||||
*/
|
||||
static struct fcoe_softc *
|
||||
|
@ -1727,14 +1739,10 @@ fcoe_hostlist_lookup_softc(const struct net_device *dev)
|
|||
{
|
||||
struct fcoe_softc *fc;
|
||||
|
||||
read_lock(&fcoe_hostlist_lock);
|
||||
list_for_each_entry(fc, &fcoe_hostlist, list) {
|
||||
if (fc->real_dev == dev) {
|
||||
read_unlock(&fcoe_hostlist_lock);
|
||||
if (fc->real_dev == dev)
|
||||
return fc;
|
||||
}
|
||||
}
|
||||
read_unlock(&fcoe_hostlist_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1748,7 +1756,9 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
|
|||
{
|
||||
struct fcoe_softc *fc;
|
||||
|
||||
read_lock(&fcoe_hostlist_lock);
|
||||
fc = fcoe_hostlist_lookup_softc(netdev);
|
||||
read_unlock(&fcoe_hostlist_lock);
|
||||
|
||||
return (fc) ? fc->ctlr.lp : NULL;
|
||||
}
|
||||
|
@ -1757,6 +1767,8 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
|
|||
* fcoe_hostlist_add() - Add a lport to lports list
|
||||
* @lp: ptr to the fc_lport to be added
|
||||
*
|
||||
* Called with write fcoe_hostlist_lock held.
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_hostlist_add(const struct fc_lport *lp)
|
||||
|
@ -1766,9 +1778,7 @@ int fcoe_hostlist_add(const struct fc_lport *lp)
|
|||
fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
|
||||
if (!fc) {
|
||||
fc = lport_priv(lp);
|
||||
write_lock_bh(&fcoe_hostlist_lock);
|
||||
list_add_tail(&fc->list, &fcoe_hostlist);
|
||||
write_unlock_bh(&fcoe_hostlist_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1783,9 +1793,9 @@ int fcoe_hostlist_remove(const struct fc_lport *lp)
|
|||
{
|
||||
struct fcoe_softc *fc;
|
||||
|
||||
write_lock_bh(&fcoe_hostlist_lock);
|
||||
fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
|
||||
BUG_ON(!fc);
|
||||
write_lock_bh(&fcoe_hostlist_lock);
|
||||
list_del(&fc->list);
|
||||
write_unlock_bh(&fcoe_hostlist_lock);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче