aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/fcoe.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 617348fa4e86..77adced58ebf 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1009,6 +1009,8 @@ skip_oem:
1009 * fcoe_if_destroy() - Tear down a SW FCoE instance 1009 * fcoe_if_destroy() - Tear down a SW FCoE instance
1010 * @lport: The local port to be destroyed 1010 * @lport: The local port to be destroyed
1011 * 1011 *
1012 * Locking: Must be called with the RTNL mutex held.
1013 *
1012 */ 1014 */
1013static void fcoe_if_destroy(struct fc_lport *lport) 1015static void fcoe_if_destroy(struct fc_lport *lport)
1014{ 1016{
@@ -1030,14 +1032,12 @@ static void fcoe_if_destroy(struct fc_lport *lport)
1030 /* Free existing transmit skbs */ 1032 /* Free existing transmit skbs */
1031 fcoe_clean_pending_queue(lport); 1033 fcoe_clean_pending_queue(lport);
1032 1034
1033 rtnl_lock();
1034 if (!is_zero_ether_addr(port->data_src_addr)) 1035 if (!is_zero_ether_addr(port->data_src_addr))
1035 dev_uc_del(netdev, port->data_src_addr); 1036 dev_uc_del(netdev, port->data_src_addr);
1036 if (lport->vport) 1037 if (lport->vport)
1037 synchronize_net(); 1038 synchronize_net();
1038 else 1039 else
1039 fcoe_interface_remove(fcoe); 1040 fcoe_interface_remove(fcoe);
1040 rtnl_unlock();
1041 1041
1042 /* Free queued packets for the per-CPU receive threads */ 1042 /* Free queued packets for the per-CPU receive threads */
1043 fcoe_percpu_clean(lport); 1043 fcoe_percpu_clean(lport);
@@ -1898,7 +1898,14 @@ static int fcoe_device_notification(struct notifier_block *notifier,
1898 case NETDEV_UNREGISTER: 1898 case NETDEV_UNREGISTER:
1899 list_del(&fcoe->list); 1899 list_del(&fcoe->list);
1900 port = lport_priv(ctlr->lp); 1900 port = lport_priv(ctlr->lp);
1901 queue_work(fcoe_wq, &port->destroy_work); 1901 fcoe_vport_remove(lport);
1902 mutex_lock(&fcoe_config_mutex);
1903 fcoe_if_destroy(lport);
1904 if (!fcoe->removed)
1905 fcoe_interface_remove(fcoe);
1906 fcoe_interface_cleanup(fcoe);
1907 mutex_unlock(&fcoe_config_mutex);
1908 fcoe_ctlr_device_delete(fcoe_ctlr_to_ctlr_dev(ctlr));
1902 goto out; 1909 goto out;
1903 break; 1910 break;
1904 case NETDEV_FEAT_CHANGE: 1911 case NETDEV_FEAT_CHANGE:
@@ -2114,9 +2121,8 @@ static void fcoe_destroy_work(struct work_struct *work)
2114 ctlr = fcoe_to_ctlr(fcoe); 2121 ctlr = fcoe_to_ctlr(fcoe);
2115 cdev = fcoe_ctlr_to_ctlr_dev(ctlr); 2122 cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
2116 2123
2117 fcoe_if_destroy(port->lport);
2118
2119 rtnl_lock(); 2124 rtnl_lock();
2125 fcoe_if_destroy(port->lport);
2120 if (!fcoe->removed) 2126 if (!fcoe->removed)
2121 fcoe_interface_remove(fcoe); 2127 fcoe_interface_remove(fcoe);
2122 rtnl_unlock(); 2128 rtnl_unlock();
@@ -2720,7 +2726,9 @@ static int fcoe_vport_destroy(struct fc_vport *vport)
2720 mutex_unlock(&n_port->lp_mutex); 2726 mutex_unlock(&n_port->lp_mutex);
2721 2727
2722 mutex_lock(&fcoe_config_mutex); 2728 mutex_lock(&fcoe_config_mutex);
2729 rtnl_lock();
2723 fcoe_if_destroy(vn_port); 2730 fcoe_if_destroy(vn_port);
2731 rtnl_unlock();
2724 mutex_unlock(&fcoe_config_mutex); 2732 mutex_unlock(&fcoe_config_mutex);
2725 2733
2726 return 0; 2734 return 0;