diff options
| -rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 18 |
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 | */ |
| 1013 | static void fcoe_if_destroy(struct fc_lport *lport) | 1015 | static 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; |
