diff options
author | Chris Leech <christopher.leech@intel.com> | 2009-08-25 17:00:13 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:36 -0400 |
commit | dfc1d0fe3a8b2139295600ab519f24059493e6f6 (patch) | |
tree | a26f1913bfe754700cf3ef38096d4c17bbbc321c /drivers/scsi/fcoe | |
parent | 54b649f88eb17a29687bece4b8ad7d72d99e2d95 (diff) |
[SCSI] fcoe: add mutex to protect create and destroy
Rather than rely on the hostlist_lock to be held while creating exchange
managers, serialize fcoe instance creation and destruction with a mutex.
This will allow the hostlist addition to be moved out of fcoe_if_create(),
which will simplify NPIV support.
Signed-off-by: Chris Leech <christopher.leech@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/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 63aeeca384ba..43added0a17c 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -55,6 +55,8 @@ module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR); | |||
55 | MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \ | 55 | MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \ |
56 | "Direct Data Placement (DDP)."); | 56 | "Direct Data Placement (DDP)."); |
57 | 57 | ||
58 | DEFINE_MUTEX(fcoe_config_mutex); | ||
59 | |||
58 | /* fcoe host list */ | 60 | /* fcoe host list */ |
59 | LIST_HEAD(fcoe_hostlist); | 61 | LIST_HEAD(fcoe_hostlist); |
60 | DEFINE_RWLOCK(fcoe_hostlist_lock); | 62 | DEFINE_RWLOCK(fcoe_hostlist_lock); |
@@ -811,6 +813,7 @@ static int __init fcoe_if_init(void) | |||
811 | int __exit fcoe_if_exit(void) | 813 | int __exit fcoe_if_exit(void) |
812 | { | 814 | { |
813 | fc_release_transport(scsi_transport_fcoe_sw); | 815 | fc_release_transport(scsi_transport_fcoe_sw); |
816 | scsi_transport_fcoe_sw = NULL; | ||
814 | return 0; | 817 | return 0; |
815 | } | 818 | } |
816 | 819 | ||
@@ -1686,6 +1689,19 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
1686 | struct fc_lport *lport; | 1689 | struct fc_lport *lport; |
1687 | int rc; | 1690 | int rc; |
1688 | 1691 | ||
1692 | mutex_lock(&fcoe_config_mutex); | ||
1693 | #ifdef CONFIG_FCOE_MODULE | ||
1694 | /* | ||
1695 | * Make sure the module has been initialized, and is not about to be | ||
1696 | * removed. Module paramter sysfs files are writable before the | ||
1697 | * module_init function is called and after module_exit. | ||
1698 | */ | ||
1699 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1700 | rc = -ENODEV; | ||
1701 | goto out_nodev; | ||
1702 | } | ||
1703 | #endif | ||
1704 | |||
1689 | netdev = fcoe_if_to_netdev(buffer); | 1705 | netdev = fcoe_if_to_netdev(buffer); |
1690 | if (!netdev) { | 1706 | if (!netdev) { |
1691 | rc = -ENODEV; | 1707 | rc = -ENODEV; |
@@ -1705,6 +1721,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
1705 | out_putdev: | 1721 | out_putdev: |
1706 | dev_put(netdev); | 1722 | dev_put(netdev); |
1707 | out_nodev: | 1723 | out_nodev: |
1724 | mutex_unlock(&fcoe_config_mutex); | ||
1708 | return rc; | 1725 | return rc; |
1709 | } | 1726 | } |
1710 | 1727 | ||
@@ -1722,6 +1739,19 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
1722 | struct fc_lport *lport; | 1739 | struct fc_lport *lport; |
1723 | struct net_device *netdev; | 1740 | struct net_device *netdev; |
1724 | 1741 | ||
1742 | mutex_lock(&fcoe_config_mutex); | ||
1743 | #ifdef CONFIG_FCOE_MODULE | ||
1744 | /* | ||
1745 | * Make sure the module has been initialized, and is not about to be | ||
1746 | * removed. Module paramter sysfs files are writable before the | ||
1747 | * module_init function is called and after module_exit. | ||
1748 | */ | ||
1749 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1750 | rc = -ENODEV; | ||
1751 | goto out_nodev; | ||
1752 | } | ||
1753 | #endif | ||
1754 | |||
1725 | netdev = fcoe_if_to_netdev(buffer); | 1755 | netdev = fcoe_if_to_netdev(buffer); |
1726 | if (!netdev) { | 1756 | if (!netdev) { |
1727 | rc = -ENODEV; | 1757 | rc = -ENODEV; |
@@ -1768,6 +1798,7 @@ out_free: | |||
1768 | out_putdev: | 1798 | out_putdev: |
1769 | dev_put(netdev); | 1799 | dev_put(netdev); |
1770 | out_nodev: | 1800 | out_nodev: |
1801 | mutex_unlock(&fcoe_config_mutex); | ||
1771 | return rc; | 1802 | return rc; |
1772 | } | 1803 | } |
1773 | 1804 | ||
@@ -1971,6 +2002,8 @@ static int __init fcoe_init(void) | |||
1971 | int rc = 0; | 2002 | int rc = 0; |
1972 | struct fcoe_percpu_s *p; | 2003 | struct fcoe_percpu_s *p; |
1973 | 2004 | ||
2005 | mutex_lock(&fcoe_config_mutex); | ||
2006 | |||
1974 | for_each_possible_cpu(cpu) { | 2007 | for_each_possible_cpu(cpu) { |
1975 | p = &per_cpu(fcoe_percpu, cpu); | 2008 | p = &per_cpu(fcoe_percpu, cpu); |
1976 | skb_queue_head_init(&p->fcoe_rx_list); | 2009 | skb_queue_head_init(&p->fcoe_rx_list); |
@@ -1991,13 +2024,14 @@ static int __init fcoe_init(void) | |||
1991 | if (rc) | 2024 | if (rc) |
1992 | goto out_free; | 2025 | goto out_free; |
1993 | 2026 | ||
2027 | mutex_unlock(&fcoe_config_mutex); | ||
1994 | return 0; | 2028 | return 0; |
1995 | 2029 | ||
1996 | out_free: | 2030 | out_free: |
1997 | for_each_online_cpu(cpu) { | 2031 | for_each_online_cpu(cpu) { |
1998 | fcoe_percpu_thread_destroy(cpu); | 2032 | fcoe_percpu_thread_destroy(cpu); |
1999 | } | 2033 | } |
2000 | 2034 | mutex_unlock(&fcoe_config_mutex); | |
2001 | return rc; | 2035 | return rc; |
2002 | } | 2036 | } |
2003 | module_init(fcoe_init); | 2037 | module_init(fcoe_init); |
@@ -2012,6 +2046,8 @@ static void __exit fcoe_exit(void) | |||
2012 | unsigned int cpu; | 2046 | unsigned int cpu; |
2013 | struct fcoe_interface *fcoe, *tmp; | 2047 | struct fcoe_interface *fcoe, *tmp; |
2014 | 2048 | ||
2049 | mutex_lock(&fcoe_config_mutex); | ||
2050 | |||
2015 | fcoe_dev_cleanup(); | 2051 | fcoe_dev_cleanup(); |
2016 | 2052 | ||
2017 | /* releases the associated fcoe hosts */ | 2053 | /* releases the associated fcoe hosts */ |
@@ -2025,5 +2061,7 @@ static void __exit fcoe_exit(void) | |||
2025 | 2061 | ||
2026 | /* detach from scsi transport */ | 2062 | /* detach from scsi transport */ |
2027 | fcoe_if_exit(); | 2063 | fcoe_if_exit(); |
2064 | |||
2065 | mutex_unlock(&fcoe_config_mutex); | ||
2028 | } | 2066 | } |
2029 | module_exit(fcoe_exit); | 2067 | module_exit(fcoe_exit); |