aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorNeerav Parikh <neerav.parikh@intel.com>2011-06-20 19:59:51 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:33:25 -0400
commitb2085a4efc1a00375b77d5cbfe73a549c9d7d65b (patch)
tree822cc056b3240e00fd485dd349081a9d8758202c /drivers/scsi/fcoe
parent9b7d1613a9060b7c82ac7e8e7cbee8c2392925c2 (diff)
[SCSI] fcoe: Rearrange fcoe port and NPIV port cleanup
When NPIV port destroy handler is called it does not do all the cleanup required for the given NPIV port. This was happening as some of the lport cleanup moved to fcoe_interface_cleanup() routine, which is not called as part of the vport delete process. This patch rearranges the sequence in which the fcoe_if_destory() and fcoe_interface_cleanup() functions are being called from various places in the code. It now matches the sequence they are constructed during the create process for both N_Port as well as NPIV port. Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Neerav Parikh <Neerav.Parikh@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/fcoe.c86
1 files changed, 49 insertions, 37 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 522fbaaf9782..204fa8d4b4ab 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -431,21 +431,6 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
431 struct fcoe_ctlr *fip = &fcoe->ctlr; 431 struct fcoe_ctlr *fip = &fcoe->ctlr;
432 u8 flogi_maddr[ETH_ALEN]; 432 u8 flogi_maddr[ETH_ALEN];
433 const struct net_device_ops *ops; 433 const struct net_device_ops *ops;
434 struct fcoe_port *port = lport_priv(fcoe->ctlr.lp);
435
436 FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
437
438 /* Logout of the fabric */
439 fc_fabric_logoff(fcoe->ctlr.lp);
440
441 /* Cleanup the fc_lport */
442 fc_lport_destroy(fcoe->ctlr.lp);
443
444 /* Stop the transmit retry timer */
445 del_timer_sync(&port->timer);
446
447 /* Free existing transmit skbs */
448 fcoe_clean_pending_queue(fcoe->ctlr.lp);
449 434
450 /* 435 /*
451 * Don't listen for Ethernet packets anymore. 436 * Don't listen for Ethernet packets anymore.
@@ -468,9 +453,6 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
468 } else 453 } else
469 dev_mc_del(netdev, FIP_ALL_ENODE_MACS); 454 dev_mc_del(netdev, FIP_ALL_ENODE_MACS);
470 455
471 if (!is_zero_ether_addr(port->data_src_addr))
472 dev_uc_del(netdev, port->data_src_addr);
473
474 /* Tell the LLD we are done w/ FCoE */ 456 /* Tell the LLD we are done w/ FCoE */
475 ops = netdev->netdev_ops; 457 ops = netdev->netdev_ops;
476 if (ops->ndo_fcoe_disable) { 458 if (ops->ndo_fcoe_disable) {
@@ -478,6 +460,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
478 FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" 460 FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
479 " specific feature for LLD.\n"); 461 " specific feature for LLD.\n");
480 } 462 }
463
464 /* Release the self-reference taken during fcoe_interface_create() */
481 fcoe_interface_put(fcoe); 465 fcoe_interface_put(fcoe);
482} 466}
483 467
@@ -861,6 +845,32 @@ skip_oem:
861 */ 845 */
862static void fcoe_if_destroy(struct fc_lport *lport) 846static void fcoe_if_destroy(struct fc_lport *lport)
863{ 847{
848 struct fcoe_port *port = lport_priv(lport);
849 struct fcoe_interface *fcoe = port->priv;
850 struct net_device *netdev = fcoe->netdev;
851
852 FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
853
854 /* Logout of the fabric */
855 fc_fabric_logoff(lport);
856
857 /* Cleanup the fc_lport */
858 fc_lport_destroy(lport);
859
860 /* Stop the transmit retry timer */
861 del_timer_sync(&port->timer);
862
863 /* Free existing transmit skbs */
864 fcoe_clean_pending_queue(lport);
865
866 rtnl_lock();
867 if (!is_zero_ether_addr(port->data_src_addr))
868 dev_uc_del(netdev, port->data_src_addr);
869 rtnl_unlock();
870
871 /* Release reference held in fcoe_if_create() */
872 fcoe_interface_put(fcoe);
873
864 /* Free queued packets for the per-CPU receive threads */ 874 /* Free queued packets for the per-CPU receive threads */
865 fcoe_percpu_clean(lport); 875 fcoe_percpu_clean(lport);
866 876
@@ -1813,7 +1823,6 @@ static int fcoe_device_notification(struct notifier_block *notifier,
1813 case NETDEV_UNREGISTER: 1823 case NETDEV_UNREGISTER:
1814 list_del(&fcoe->list); 1824 list_del(&fcoe->list);
1815 port = lport_priv(fcoe->ctlr.lp); 1825 port = lport_priv(fcoe->ctlr.lp);
1816 fcoe_interface_cleanup(fcoe);
1817 queue_work(fcoe_wq, &port->destroy_work); 1826 queue_work(fcoe_wq, &port->destroy_work);
1818 goto out; 1827 goto out;
1819 break; 1828 break;
@@ -1907,22 +1916,22 @@ static int fcoe_destroy(struct net_device *netdev)
1907{ 1916{
1908 struct fcoe_interface *fcoe; 1917 struct fcoe_interface *fcoe;
1909 struct fc_lport *lport; 1918 struct fc_lport *lport;
1919 struct fcoe_port *port;
1910 int rc = 0; 1920 int rc = 0;
1911 1921
1912 mutex_lock(&fcoe_config_mutex); 1922 mutex_lock(&fcoe_config_mutex);
1913 rtnl_lock(); 1923 rtnl_lock();
1914 fcoe = fcoe_hostlist_lookup_port(netdev); 1924 fcoe = fcoe_hostlist_lookup_port(netdev);
1915 if (!fcoe) { 1925 if (!fcoe) {
1916 rtnl_unlock();
1917 rc = -ENODEV; 1926 rc = -ENODEV;
1918 goto out_nodev; 1927 goto out_nodev;
1919 } 1928 }
1920 lport = fcoe->ctlr.lp; 1929 lport = fcoe->ctlr.lp;
1930 port = lport_priv(lport);
1921 list_del(&fcoe->list); 1931 list_del(&fcoe->list);
1922 fcoe_interface_cleanup(fcoe); 1932 queue_work(fcoe_wq, &port->destroy_work);
1923 rtnl_unlock();
1924 fcoe_if_destroy(lport);
1925out_nodev: 1933out_nodev:
1934 rtnl_unlock();
1926 mutex_unlock(&fcoe_config_mutex); 1935 mutex_unlock(&fcoe_config_mutex);
1927 return rc; 1936 return rc;
1928} 1937}
@@ -1934,10 +1943,25 @@ out_nodev:
1934static void fcoe_destroy_work(struct work_struct *work) 1943static void fcoe_destroy_work(struct work_struct *work)
1935{ 1944{
1936 struct fcoe_port *port; 1945 struct fcoe_port *port;
1946 struct fcoe_interface *fcoe;
1947 int npiv = 0;
1937 1948
1938 port = container_of(work, struct fcoe_port, destroy_work); 1949 port = container_of(work, struct fcoe_port, destroy_work);
1939 mutex_lock(&fcoe_config_mutex); 1950 mutex_lock(&fcoe_config_mutex);
1951
1952 /* set if this is an NPIV port */
1953 npiv = port->lport->vport ? 1 : 0;
1954
1955 fcoe = port->priv;
1940 fcoe_if_destroy(port->lport); 1956 fcoe_if_destroy(port->lport);
1957
1958 /* Do not tear down the fcoe interface for NPIV port */
1959 if (!npiv) {
1960 rtnl_lock();
1961 fcoe_interface_cleanup(fcoe);
1962 rtnl_unlock();
1963 }
1964
1941 mutex_unlock(&fcoe_config_mutex); 1965 mutex_unlock(&fcoe_config_mutex);
1942} 1966}
1943 1967
@@ -1966,7 +1990,7 @@ static bool fcoe_match(struct net_device *netdev)
1966 */ 1990 */
1967static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 1991static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
1968{ 1992{
1969 int rc; 1993 int rc = 0;
1970 struct fcoe_interface *fcoe; 1994 struct fcoe_interface *fcoe;
1971 struct fc_lport *lport; 1995 struct fc_lport *lport;
1972 1996
@@ -1991,7 +2015,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
1991 netdev->name); 2015 netdev->name);
1992 rc = -EIO; 2016 rc = -EIO;
1993 fcoe_interface_cleanup(fcoe); 2017 fcoe_interface_cleanup(fcoe);
1994 goto out_free; 2018 goto out_nodev;
1995 } 2019 }
1996 2020
1997 /* Make this the "master" N_Port */ 2021 /* Make this the "master" N_Port */
@@ -2006,17 +2030,6 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2006 if (!fcoe_link_ok(lport)) 2030 if (!fcoe_link_ok(lport))
2007 fcoe_ctlr_link_up(&fcoe->ctlr); 2031 fcoe_ctlr_link_up(&fcoe->ctlr);
2008 2032
2009 /*
2010 * Release from init in fcoe_interface_create(), on success lport
2011 * should be holding a reference taken in fcoe_if_create().
2012 */
2013 fcoe_interface_put(fcoe);
2014 rtnl_unlock();
2015 mutex_unlock(&fcoe_config_mutex);
2016
2017 return 0;
2018out_free:
2019 fcoe_interface_put(fcoe);
2020out_nodev: 2033out_nodev:
2021 rtnl_unlock(); 2034 rtnl_unlock();
2022 mutex_unlock(&fcoe_config_mutex); 2035 mutex_unlock(&fcoe_config_mutex);
@@ -2298,7 +2311,6 @@ static void __exit fcoe_exit(void)
2298 list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { 2311 list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
2299 list_del(&fcoe->list); 2312 list_del(&fcoe->list);
2300 port = lport_priv(fcoe->ctlr.lp); 2313 port = lport_priv(fcoe->ctlr.lp);
2301 fcoe_interface_cleanup(fcoe);
2302 queue_work(fcoe_wq, &port->destroy_work); 2314 queue_work(fcoe_wq, &port->destroy_work);
2303 } 2315 }
2304 rtnl_unlock(); 2316 rtnl_unlock();