mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
[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>
This commit is contained in:
parent
54b649f88e
commit
dfc1d0fe3a
1 changed files with 39 additions and 1 deletions
|
@ -55,6 +55,8 @@ module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR);
|
||||||
MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \
|
MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \
|
||||||
"Direct Data Placement (DDP).");
|
"Direct Data Placement (DDP).");
|
||||||
|
|
||||||
|
DEFINE_MUTEX(fcoe_config_mutex);
|
||||||
|
|
||||||
/* fcoe host list */
|
/* fcoe host list */
|
||||||
LIST_HEAD(fcoe_hostlist);
|
LIST_HEAD(fcoe_hostlist);
|
||||||
DEFINE_RWLOCK(fcoe_hostlist_lock);
|
DEFINE_RWLOCK(fcoe_hostlist_lock);
|
||||||
|
@ -811,6 +813,7 @@ static int __init fcoe_if_init(void)
|
||||||
int __exit fcoe_if_exit(void)
|
int __exit fcoe_if_exit(void)
|
||||||
{
|
{
|
||||||
fc_release_transport(scsi_transport_fcoe_sw);
|
fc_release_transport(scsi_transport_fcoe_sw);
|
||||||
|
scsi_transport_fcoe_sw = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1686,6 +1689,19 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
|
||||||
struct fc_lport *lport;
|
struct fc_lport *lport;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
mutex_lock(&fcoe_config_mutex);
|
||||||
|
#ifdef CONFIG_FCOE_MODULE
|
||||||
|
/*
|
||||||
|
* Make sure the module has been initialized, and is not about to be
|
||||||
|
* removed. Module paramter sysfs files are writable before the
|
||||||
|
* module_init function is called and after module_exit.
|
||||||
|
*/
|
||||||
|
if (THIS_MODULE->state != MODULE_STATE_LIVE) {
|
||||||
|
rc = -ENODEV;
|
||||||
|
goto out_nodev;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
netdev = fcoe_if_to_netdev(buffer);
|
netdev = fcoe_if_to_netdev(buffer);
|
||||||
if (!netdev) {
|
if (!netdev) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
@ -1705,6 +1721,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
|
||||||
out_putdev:
|
out_putdev:
|
||||||
dev_put(netdev);
|
dev_put(netdev);
|
||||||
out_nodev:
|
out_nodev:
|
||||||
|
mutex_unlock(&fcoe_config_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1722,6 +1739,19 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
|
||||||
struct fc_lport *lport;
|
struct fc_lport *lport;
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
|
|
||||||
|
mutex_lock(&fcoe_config_mutex);
|
||||||
|
#ifdef CONFIG_FCOE_MODULE
|
||||||
|
/*
|
||||||
|
* Make sure the module has been initialized, and is not about to be
|
||||||
|
* removed. Module paramter sysfs files are writable before the
|
||||||
|
* module_init function is called and after module_exit.
|
||||||
|
*/
|
||||||
|
if (THIS_MODULE->state != MODULE_STATE_LIVE) {
|
||||||
|
rc = -ENODEV;
|
||||||
|
goto out_nodev;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
netdev = fcoe_if_to_netdev(buffer);
|
netdev = fcoe_if_to_netdev(buffer);
|
||||||
if (!netdev) {
|
if (!netdev) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
@ -1768,6 +1798,7 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
|
||||||
out_putdev:
|
out_putdev:
|
||||||
dev_put(netdev);
|
dev_put(netdev);
|
||||||
out_nodev:
|
out_nodev:
|
||||||
|
mutex_unlock(&fcoe_config_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,6 +2002,8 @@ static int __init fcoe_init(void)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct fcoe_percpu_s *p;
|
struct fcoe_percpu_s *p;
|
||||||
|
|
||||||
|
mutex_lock(&fcoe_config_mutex);
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
p = &per_cpu(fcoe_percpu, cpu);
|
p = &per_cpu(fcoe_percpu, cpu);
|
||||||
skb_queue_head_init(&p->fcoe_rx_list);
|
skb_queue_head_init(&p->fcoe_rx_list);
|
||||||
|
@ -1991,13 +2024,14 @@ static int __init fcoe_init(void)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
mutex_unlock(&fcoe_config_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
fcoe_percpu_thread_destroy(cpu);
|
fcoe_percpu_thread_destroy(cpu);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&fcoe_config_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
module_init(fcoe_init);
|
module_init(fcoe_init);
|
||||||
|
@ -2012,6 +2046,8 @@ static void __exit fcoe_exit(void)
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
struct fcoe_interface *fcoe, *tmp;
|
struct fcoe_interface *fcoe, *tmp;
|
||||||
|
|
||||||
|
mutex_lock(&fcoe_config_mutex);
|
||||||
|
|
||||||
fcoe_dev_cleanup();
|
fcoe_dev_cleanup();
|
||||||
|
|
||||||
/* releases the associated fcoe hosts */
|
/* releases the associated fcoe hosts */
|
||||||
|
@ -2025,5 +2061,7 @@ static void __exit fcoe_exit(void)
|
||||||
|
|
||||||
/* detach from scsi transport */
|
/* detach from scsi transport */
|
||||||
fcoe_if_exit();
|
fcoe_if_exit();
|
||||||
|
|
||||||
|
mutex_unlock(&fcoe_config_mutex);
|
||||||
}
|
}
|
||||||
module_exit(fcoe_exit);
|
module_exit(fcoe_exit);
|
||||||
|
|
Loading…
Reference in a new issue