We saw a call to fcoe_destroy fail to find the interface in the list and hit a BUG_ON().
Recode so that the lock is held through the lookup and list_del(). Also fix a missing unlock in an error case of fcoe_if_create(). Signed-off-by: Joe Eykholt <[email protected]> --- drivers/scsi/fcoe/fcoe.c | 38 +++++++++++--------------------------- 1 files changed, 11 insertions(+), 27 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index e2f9d0c..598a0c6 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -64,9 +64,9 @@ static void fcoe_clean_pending_queue(struct fc_lport *lp); static void fcoe_percpu_clean(struct fc_lport *lp); static int fcoe_link_ok(struct fc_lport *lp); +static struct fcoe_softc *fcoe_hostlist_lookup_softc(const struct net_device *); static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); static int fcoe_hostlist_add(const struct fc_lport *); -static int fcoe_hostlist_remove(const struct fc_lport *); static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *); static int fcoe_device_notification(struct notifier_block *, ulong, void *); @@ -511,18 +511,20 @@ static int fcoe_if_destroy(struct net_device *netdev) FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); - lp = fcoe_hostlist_lookup(netdev); - if (!lp) + write_lock_bh(&fcoe_hostlist_lock); + fc = fcoe_hostlist_lookup_softc(netdev); + if (!fc) { + write_unlock_bh(&fcoe_hostlist_lock); return -ENODEV; - - fc = lport_priv(lp); + } + /* Remove the instance from fcoe's list */ + list_del(&fc->list); + write_unlock_bh(&fcoe_hostlist_lock); + lp = fc->ctlr.lp; /* Logout of the fabric */ fc_fabric_logoff(lp); - /* Remove the instance from fcoe's list */ - fcoe_hostlist_remove(lp); - /* clean up netdev configurations */ fcoe_netdev_cleanup(fc); @@ -683,6 +685,7 @@ static int fcoe_if_create(struct net_device *netdev) /* lport exch manager allocation */ rc = fcoe_em_config(lp); if (rc) { + write_unlock(&fcoe_hostlist_lock); FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " "interface\n"); goto out_lp_destroy; @@ -1848,25 +1851,6 @@ int fcoe_hostlist_add(const struct fc_lport *lp) } /** - * fcoe_hostlist_remove() - remove a lport from lports list - * @lp: ptr to the fc_lport to be removed - * - * Returns: 0 for success - */ -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); - list_del(&fc->list); - write_unlock_bh(&fcoe_hostlist_lock); - - return 0; -} - -/** * fcoe_init() - fcoe module loading initialization * * Returns 0 on success, negative on failure _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
