diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-15 03:23:44 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-15 03:23:44 +0300 |
commit | 670ffccb2f9183eb6cb32fe92257aea52b3f8a7d (patch) | |
tree | 54962412913a69e17cc680c57f3e26f7305d99d2 /drivers/scsi/fcoe | |
parent | 47f521ba18190e4bfbb65ead3977af5756884427 (diff) | |
parent | 341b2aa83368e6f23bf0cc3d04604896337ad7cb (diff) | |
download | linux-670ffccb2f9183eb6cb32fe92257aea52b3f8a7d.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly updates of the usual suspects: lpfc, qla2xxx, hisi_sas,
megaraid_sas, pm80xx, mpt3sas, be2iscsi, hpsa. and a host of minor
updates.
There's no major behaviour change or additions to the core in all of
this, so the potential for regressions should be small (biggest
potential being in the scsi error handler changes)"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (203 commits)
scsi: lpfc: Fix hard lock up NMI in els timeout handling.
scsi: mpt3sas: remove a stray KERN_INFO
scsi: mpt3sas: cleanup _scsih_pcie_enumeration_event()
scsi: aacraid: use timespec64 instead of timeval
scsi: scsi_transport_fc: add 64GBIT and 128GBIT port speed definitions
scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair()
scsi: mpt3sas: fix dma_addr_t casts
scsi: be2iscsi: Use kasprintf
scsi: storvsc: Avoid excessive host scan on controller change
scsi: lpfc: fix kzalloc-simple.cocci warnings
scsi: mpt3sas: Update mpt3sas driver version.
scsi: mpt3sas: Fix sparse warnings
scsi: mpt3sas: Fix nvme drives checking for tlr.
scsi: mpt3sas: NVMe drive support for BTDHMAPPING ioctl command and log info
scsi: mpt3sas: Add-Task-management-debug-info-for-NVMe-drives.
scsi: mpt3sas: scan and add nvme device after controller reset
scsi: mpt3sas: Set NVMe device queue depth as 128
scsi: mpt3sas: Handle NVMe PCIe device related events generated from firmware.
scsi: mpt3sas: API's to remove nvme drive from sml
scsi: mpt3sas: API 's to support NVMe drive addition to SML
...
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 81 |
1 files changed, 51 insertions, 30 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 5cc09dce4d25..f46b312d04bc 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -155,7 +155,7 @@ static int fcoe_vport_disable(struct fc_vport *, bool disable); static void fcoe_set_vport_symbolic_name(struct fc_vport *); static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); - +static void fcoe_vport_remove(struct fc_lport *); static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { .set_fcoe_ctlr_mode = fcoe_ctlr_mode, @@ -501,11 +501,6 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) struct net_device *netdev = fcoe->netdev; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); - rtnl_lock(); - if (!fcoe->removed) - fcoe_interface_remove(fcoe); - rtnl_unlock(); - /* Release the self-reference taken during fcoe_interface_create() */ /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); @@ -1014,6 +1009,8 @@ skip_oem: * fcoe_if_destroy() - Tear down a SW FCoE instance * @lport: The local port to be destroyed * + * Locking: Must be called with the RTNL mutex held. + * */ static void fcoe_if_destroy(struct fc_lport *lport) { @@ -1035,14 +1032,12 @@ static void fcoe_if_destroy(struct fc_lport *lport) /* Free existing transmit skbs */ fcoe_clean_pending_queue(lport); - rtnl_lock(); if (!is_zero_ether_addr(port->data_src_addr)) dev_uc_del(netdev, port->data_src_addr); if (lport->vport) synchronize_net(); else fcoe_interface_remove(fcoe); - rtnl_unlock(); /* Free queued packets for the per-CPU receive threads */ fcoe_percpu_clean(lport); @@ -1903,7 +1898,14 @@ static int fcoe_device_notification(struct notifier_block *notifier, case NETDEV_UNREGISTER: list_del(&fcoe->list); port = lport_priv(ctlr->lp); - queue_work(fcoe_wq, &port->destroy_work); + fcoe_vport_remove(lport); + mutex_lock(&fcoe_config_mutex); + fcoe_if_destroy(lport); + if (!fcoe->removed) + fcoe_interface_remove(fcoe); + fcoe_interface_cleanup(fcoe); + mutex_unlock(&fcoe_config_mutex); + fcoe_ctlr_device_delete(fcoe_ctlr_to_ctlr_dev(ctlr)); goto out; break; case NETDEV_FEAT_CHANGE: @@ -2108,30 +2110,10 @@ static void fcoe_destroy_work(struct work_struct *work) struct fcoe_ctlr *ctlr; struct fcoe_port *port; struct fcoe_interface *fcoe; - struct Scsi_Host *shost; - struct fc_host_attrs *fc_host; - unsigned long flags; - struct fc_vport *vport; - struct fc_vport *next_vport; port = container_of(work, struct fcoe_port, destroy_work); - shost = port->lport->host; - fc_host = shost_to_fc_host(shost); - - /* Loop through all the vports and mark them for deletion */ - spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) { - if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { - continue; - } else { - vport->flags |= FC_VPORT_DELETING; - queue_work(fc_host_work_q(shost), - &vport->vport_delete_work); - } - } - spin_unlock_irqrestore(shost->host_lock, flags); - flush_workqueue(fc_host_work_q(shost)); + fcoe_vport_remove(port->lport); mutex_lock(&fcoe_config_mutex); @@ -2139,7 +2121,11 @@ static void fcoe_destroy_work(struct work_struct *work) ctlr = fcoe_to_ctlr(fcoe); cdev = fcoe_ctlr_to_ctlr_dev(ctlr); + rtnl_lock(); fcoe_if_destroy(port->lport); + if (!fcoe->removed) + fcoe_interface_remove(fcoe); + rtnl_unlock(); fcoe_interface_cleanup(fcoe); mutex_unlock(&fcoe_config_mutex); @@ -2254,6 +2240,8 @@ static int _fcoe_create(struct net_device *netdev, enum fip_mode fip_mode, printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", netdev->name); rc = -EIO; + if (!fcoe->removed) + fcoe_interface_remove(fcoe); rtnl_unlock(); fcoe_interface_cleanup(fcoe); mutex_unlock(&fcoe_config_mutex); @@ -2738,13 +2726,46 @@ static int fcoe_vport_destroy(struct fc_vport *vport) mutex_unlock(&n_port->lp_mutex); mutex_lock(&fcoe_config_mutex); + rtnl_lock(); fcoe_if_destroy(vn_port); + rtnl_unlock(); mutex_unlock(&fcoe_config_mutex); return 0; } /** + * fcoe_vport_remove() - remove attached vports + * @lport: lport for which the vports should be removed + */ +static void fcoe_vport_remove(struct fc_lport *lport) +{ + struct Scsi_Host *shost; + struct fc_host_attrs *fc_host; + unsigned long flags; + struct fc_vport *vport; + struct fc_vport *next_vport; + + shost = lport->host; + fc_host = shost_to_fc_host(shost); + + /* Loop through all the vports and mark them for deletion */ + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) { + if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { + continue; + } else { + vport->flags |= FC_VPORT_DELETING; + queue_work(fc_host_work_q(shost), + &vport->vport_delete_work); + } + } + spin_unlock_irqrestore(shost->host_lock, flags); + + flush_workqueue(fc_host_work_q(shost)); +} + +/** * fcoe_vport_disable() - change vport state * @vport: vport to bring online/offline * @disable: should the vport be disabled? |