aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2011-04-01 19:06:45 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 11:20:59 -0400
commitf04ca1b65480df9ecbaaa797e62b063387429410 (patch)
tree31f3c58011bf0447c0a93698d3e7bba4a746c48d /drivers/scsi
parentf2817ec2e0faece03959888050730ed35e5f2bd2 (diff)
[SCSI] fcoe: have fcoe log off and lport destroy before ndo_fcoe_disable
Currently fcoe interface cleanup is done after ndo_fcoe_disable and that prevents logoff going out to the peer, so this patch moves all netdev cleanup and its releasing inside fcoe_interface_cleanup to have log off before ndo_fcoe_disable disables the fcoe. This patch also fixes asymmetric rtnl locking around fcoe_if_destroy, as currently this function requires rtnl held by its caller and then have this func drops the lock, instead now don't have any processing under rtnl inside fcoe_if_destroy, this required moving few func to get build working again. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/fcoe/fcoe.c131
1 files changed, 60 insertions, 71 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 34408d945175..5d3700dc6f8c 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -381,6 +381,42 @@ out:
381} 381}
382 382
383/** 383/**
384 * fcoe_interface_release() - fcoe_port kref release function
385 * @kref: Embedded reference count in an fcoe_interface struct
386 */
387static void fcoe_interface_release(struct kref *kref)
388{
389 struct fcoe_interface *fcoe;
390 struct net_device *netdev;
391
392 fcoe = container_of(kref, struct fcoe_interface, kref);
393 netdev = fcoe->netdev;
394 /* tear-down the FCoE controller */
395 fcoe_ctlr_destroy(&fcoe->ctlr);
396 kfree(fcoe);
397 dev_put(netdev);
398 module_put(THIS_MODULE);
399}
400
401/**
402 * fcoe_interface_get() - Get a reference to a FCoE interface
403 * @fcoe: The FCoE interface to be held
404 */
405static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
406{
407 kref_get(&fcoe->kref);
408}
409
410/**
411 * fcoe_interface_put() - Put a reference to a FCoE interface
412 * @fcoe: The FCoE interface to be released
413 */
414static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
415{
416 kref_put(&fcoe->kref, fcoe_interface_release);
417}
418
419/**
384 * fcoe_interface_cleanup() - Clean up a FCoE interface 420 * fcoe_interface_cleanup() - Clean up a FCoE interface
385 * @fcoe: The FCoE interface to be cleaned up 421 * @fcoe: The FCoE interface to be cleaned up
386 * 422 *
@@ -392,6 +428,21 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
392 struct fcoe_ctlr *fip = &fcoe->ctlr; 428 struct fcoe_ctlr *fip = &fcoe->ctlr;
393 u8 flogi_maddr[ETH_ALEN]; 429 u8 flogi_maddr[ETH_ALEN];
394 const struct net_device_ops *ops; 430 const struct net_device_ops *ops;
431 struct fcoe_port *port = lport_priv(fcoe->ctlr.lp);
432
433 FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
434
435 /* Logout of the fabric */
436 fc_fabric_logoff(fcoe->ctlr.lp);
437
438 /* Cleanup the fc_lport */
439 fc_lport_destroy(fcoe->ctlr.lp);
440
441 /* Stop the transmit retry timer */
442 del_timer_sync(&port->timer);
443
444 /* Free existing transmit skbs */
445 fcoe_clean_pending_queue(fcoe->ctlr.lp);
395 446
396 /* 447 /*
397 * Don't listen for Ethernet packets anymore. 448 * Don't listen for Ethernet packets anymore.
@@ -414,6 +465,9 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
414 } else 465 } else
415 dev_mc_del(netdev, FIP_ALL_ENODE_MACS); 466 dev_mc_del(netdev, FIP_ALL_ENODE_MACS);
416 467
468 if (!is_zero_ether_addr(port->data_src_addr))
469 dev_uc_del(netdev, port->data_src_addr);
470
417 /* Tell the LLD we are done w/ FCoE */ 471 /* Tell the LLD we are done w/ FCoE */
418 ops = netdev->netdev_ops; 472 ops = netdev->netdev_ops;
419 if (ops->ndo_fcoe_disable) { 473 if (ops->ndo_fcoe_disable) {
@@ -421,42 +475,7 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
421 FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" 475 FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
422 " specific feature for LLD.\n"); 476 " specific feature for LLD.\n");
423 } 477 }
424} 478 fcoe_interface_put(fcoe);
425
426/**
427 * fcoe_interface_release() - fcoe_port kref release function
428 * @kref: Embedded reference count in an fcoe_interface struct
429 */
430static void fcoe_interface_release(struct kref *kref)
431{
432 struct fcoe_interface *fcoe;
433 struct net_device *netdev;
434
435 fcoe = container_of(kref, struct fcoe_interface, kref);
436 netdev = fcoe->netdev;
437 /* tear-down the FCoE controller */
438 fcoe_ctlr_destroy(&fcoe->ctlr);
439 kfree(fcoe);
440 dev_put(netdev);
441 module_put(THIS_MODULE);
442}
443
444/**
445 * fcoe_interface_get() - Get a reference to a FCoE interface
446 * @fcoe: The FCoE interface to be held
447 */
448static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
449{
450 kref_get(&fcoe->kref);
451}
452
453/**
454 * fcoe_interface_put() - Put a reference to a FCoE interface
455 * @fcoe: The FCoE interface to be released
456 */
457static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
458{
459 kref_put(&fcoe->kref, fcoe_interface_release);
460} 479}
461 480
462/** 481/**
@@ -821,39 +840,9 @@ skip_oem:
821 * fcoe_if_destroy() - Tear down a SW FCoE instance 840 * fcoe_if_destroy() - Tear down a SW FCoE instance
822 * @lport: The local port to be destroyed 841 * @lport: The local port to be destroyed
823 * 842 *
824 * Locking: must be called with the RTNL mutex held and RTNL mutex
825 * needed to be dropped by this function since not dropping RTNL
826 * would cause circular locking warning on synchronous fip worker
827 * cancelling thru fcoe_interface_put invoked by this function.
828 *
829 */ 843 */
830static void fcoe_if_destroy(struct fc_lport *lport) 844static void fcoe_if_destroy(struct fc_lport *lport)
831{ 845{
832 struct fcoe_port *port = lport_priv(lport);
833 struct fcoe_interface *fcoe = port->priv;
834 struct net_device *netdev = fcoe->netdev;
835
836 FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
837
838 /* Logout of the fabric */
839 fc_fabric_logoff(lport);
840
841 /* Cleanup the fc_lport */
842 fc_lport_destroy(lport);
843
844 /* Stop the transmit retry timer */
845 del_timer_sync(&port->timer);
846
847 /* Free existing transmit skbs */
848 fcoe_clean_pending_queue(lport);
849
850 if (!is_zero_ether_addr(port->data_src_addr))
851 dev_uc_del(netdev, port->data_src_addr);
852 rtnl_unlock();
853
854 /* receives may not be stopped until after this */
855 fcoe_interface_put(fcoe);
856
857 /* Free queued packets for the per-CPU receive threads */ 846 /* Free queued packets for the per-CPU receive threads */
858 fcoe_percpu_clean(lport); 847 fcoe_percpu_clean(lport);
859 848
@@ -1836,6 +1825,7 @@ static int fcoe_enable(struct net_device *netdev)
1836static int fcoe_destroy(struct net_device *netdev) 1825static int fcoe_destroy(struct net_device *netdev)
1837{ 1826{
1838 struct fcoe_interface *fcoe; 1827 struct fcoe_interface *fcoe;
1828 struct fc_lport *lport;
1839 int rc = 0; 1829 int rc = 0;
1840 1830
1841 mutex_lock(&fcoe_config_mutex); 1831 mutex_lock(&fcoe_config_mutex);
@@ -1846,10 +1836,11 @@ static int fcoe_destroy(struct net_device *netdev)
1846 rc = -ENODEV; 1836 rc = -ENODEV;
1847 goto out_nodev; 1837 goto out_nodev;
1848 } 1838 }
1849 fcoe_interface_cleanup(fcoe); 1839 lport = fcoe->ctlr.lp;
1850 list_del(&fcoe->list); 1840 list_del(&fcoe->list);
1851 /* RTNL mutex is dropped by fcoe_if_destroy */ 1841 fcoe_interface_cleanup(fcoe);
1852 fcoe_if_destroy(fcoe->ctlr.lp); 1842 rtnl_unlock();
1843 fcoe_if_destroy(lport);
1853out_nodev: 1844out_nodev:
1854 mutex_unlock(&fcoe_config_mutex); 1845 mutex_unlock(&fcoe_config_mutex);
1855 return rc; 1846 return rc;
@@ -1865,8 +1856,6 @@ static void fcoe_destroy_work(struct work_struct *work)
1865 1856
1866 port = container_of(work, struct fcoe_port, destroy_work); 1857 port = container_of(work, struct fcoe_port, destroy_work);
1867 mutex_lock(&fcoe_config_mutex); 1858 mutex_lock(&fcoe_config_mutex);
1868 rtnl_lock();
1869 /* RTNL mutex is dropped by fcoe_if_destroy */
1870 fcoe_if_destroy(port->lport); 1859 fcoe_if_destroy(port->lport);
1871 mutex_unlock(&fcoe_config_mutex); 1860 mutex_unlock(&fcoe_config_mutex);
1872} 1861}