Commit 090eb6c4 authored by Chris Leech's avatar Chris Leech Committed by James Bottomley

[SCSI] fcoe: use rtnl mutex in place of hostlist lock

This just cuts down on the number of locks we're dealing with, and
eliminates the need to take another lock in the netdev notifier.
Signed-off-by: default avatarChris Leech <christopher.leech@intel.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 2e70e241
...@@ -58,8 +58,8 @@ MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \ ...@@ -58,8 +58,8 @@ MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \
DEFINE_MUTEX(fcoe_config_mutex); DEFINE_MUTEX(fcoe_config_mutex);
/* fcoe host list */ /* fcoe host list */
/* must only by accessed under the RTNL mutex */
LIST_HEAD(fcoe_hostlist); LIST_HEAD(fcoe_hostlist);
DEFINE_RWLOCK(fcoe_hostlist_lock);
DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
/* Function Prototypes */ /* Function Prototypes */
...@@ -527,8 +527,6 @@ bool fcoe_oem_match(struct fc_frame *fp) ...@@ -527,8 +527,6 @@ bool fcoe_oem_match(struct fc_frame *fp)
* fcoe_em_config() - allocates em for this lport * fcoe_em_config() - allocates em for this lport
* @lp: the fcoe that em is to allocated for * @lp: the fcoe that em is to allocated for
* *
* Called with write fcoe_hostlist_lock held.
*
* Returns : 0 on success * Returns : 0 on success
*/ */
static inline int fcoe_em_config(struct fc_lport *lp) static inline int fcoe_em_config(struct fc_lport *lp)
...@@ -1539,7 +1537,6 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1539,7 +1537,6 @@ static int fcoe_device_notification(struct notifier_block *notifier,
u32 mfs; u32 mfs;
int rc = NOTIFY_OK; int rc = NOTIFY_OK;
write_lock(&fcoe_hostlist_lock);
list_for_each_entry(fcoe, &fcoe_hostlist, list) { list_for_each_entry(fcoe, &fcoe_hostlist, list) {
if (fcoe->netdev == netdev) { if (fcoe->netdev == netdev) {
lp = fcoe->ctlr.lp; lp = fcoe->ctlr.lp;
...@@ -1586,7 +1583,6 @@ static int fcoe_device_notification(struct notifier_block *notifier, ...@@ -1586,7 +1583,6 @@ static int fcoe_device_notification(struct notifier_block *notifier,
fcoe_clean_pending_queue(lp); fcoe_clean_pending_queue(lp);
} }
out: out:
write_unlock(&fcoe_hostlist_lock);
return rc; return rc;
} }
...@@ -1643,16 +1639,14 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) ...@@ -1643,16 +1639,14 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
goto out_nodev; goto out_nodev;
} }
write_lock(&fcoe_hostlist_lock); rtnl_lock();
fcoe = fcoe_hostlist_lookup_port(netdev); fcoe = fcoe_hostlist_lookup_port(netdev);
if (!fcoe) { if (!fcoe) {
write_unlock(&fcoe_hostlist_lock); rtnl_unlock();
rc = -ENODEV; rc = -ENODEV;
goto out_putdev; goto out_putdev;
} }
list_del(&fcoe->list); list_del(&fcoe->list);
write_unlock(&fcoe_hostlist_lock);
rtnl_lock();
fcoe_interface_cleanup(fcoe); fcoe_interface_cleanup(fcoe);
rtnl_unlock(); rtnl_unlock();
fcoe_if_destroy(fcoe->ctlr.lp); fcoe_if_destroy(fcoe->ctlr.lp);
...@@ -1870,9 +1864,8 @@ int fcoe_reset(struct Scsi_Host *shost) ...@@ -1870,9 +1864,8 @@ int fcoe_reset(struct Scsi_Host *shost)
* fcoe_hostlist_lookup_port() - find the corresponding lport by a given device * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device
* @dev: this is currently ptr to net_device * @dev: this is currently ptr to net_device
* *
* Called with fcoe_hostlist_lock held.
*
* Returns: NULL or the located fcoe_port * Returns: NULL or the located fcoe_port
* Locking: must be called with the RNL mutex held
*/ */
static struct fcoe_interface * static struct fcoe_interface *
fcoe_hostlist_lookup_port(const struct net_device *dev) fcoe_hostlist_lookup_port(const struct net_device *dev)
...@@ -1891,15 +1884,13 @@ fcoe_hostlist_lookup_port(const struct net_device *dev) ...@@ -1891,15 +1884,13 @@ fcoe_hostlist_lookup_port(const struct net_device *dev)
* @netdev: ptr to net_device * @netdev: ptr to net_device
* *
* Returns: 0 for success * Returns: 0 for success
* Locking: must be called with the RTNL mutex held
*/ */
struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
{ {
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
read_lock(&fcoe_hostlist_lock);
fcoe = fcoe_hostlist_lookup_port(netdev); fcoe = fcoe_hostlist_lookup_port(netdev);
read_unlock(&fcoe_hostlist_lock);
return (fcoe) ? fcoe->ctlr.lp : NULL; return (fcoe) ? fcoe->ctlr.lp : NULL;
} }
...@@ -1908,20 +1899,19 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) ...@@ -1908,20 +1899,19 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
* @lp: ptr to the fc_lport to be added * @lp: ptr to the fc_lport to be added
* *
* Returns: 0 for success * Returns: 0 for success
* Locking: must be called with the RTNL mutex held
*/ */
int fcoe_hostlist_add(const struct fc_lport *lport) static int fcoe_hostlist_add(const struct fc_lport *lport)
{ {
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fcoe_port *port; struct fcoe_port *port;
write_lock_bh(&fcoe_hostlist_lock);
fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport));
if (!fcoe) { if (!fcoe) {
port = lport_priv(lport); port = lport_priv(lport);
fcoe = port->fcoe; fcoe = port->fcoe;
list_add_tail(&fcoe->list, &fcoe_hostlist); list_add_tail(&fcoe->list, &fcoe_hostlist);
} }
write_unlock_bh(&fcoe_hostlist_lock);
return 0; return 0;
} }
...@@ -1979,7 +1969,6 @@ static void __exit fcoe_exit(void) ...@@ -1979,7 +1969,6 @@ static void __exit fcoe_exit(void)
{ {
unsigned int cpu; unsigned int cpu;
struct fcoe_interface *fcoe, *tmp; struct fcoe_interface *fcoe, *tmp;
LIST_HEAD(local_list);
struct fcoe_port *port; struct fcoe_port *port;
mutex_lock(&fcoe_config_mutex); mutex_lock(&fcoe_config_mutex);
...@@ -1987,18 +1976,14 @@ static void __exit fcoe_exit(void) ...@@ -1987,18 +1976,14 @@ static void __exit fcoe_exit(void)
fcoe_dev_cleanup(); fcoe_dev_cleanup();
/* releases the associated fcoe hosts */ /* releases the associated fcoe hosts */
write_lock_bh(&fcoe_hostlist_lock); rtnl_lock();
list_splice_init(&fcoe_hostlist, &local_list); list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
write_unlock_bh(&fcoe_hostlist_lock);
list_for_each_entry_safe(fcoe, tmp, &local_list, list) {
list_del(&fcoe->list); list_del(&fcoe->list);
port = lport_priv(fcoe->ctlr.lp); port = lport_priv(fcoe->ctlr.lp);
rtnl_lock();
fcoe_interface_cleanup(fcoe); fcoe_interface_cleanup(fcoe);
rtnl_unlock();
schedule_work(&port->destroy_work); schedule_work(&port->destroy_work);
} }
rtnl_unlock();
unregister_hotcpu_notifier(&fcoe_cpu_notifier); unregister_hotcpu_notifier(&fcoe_cpu_notifier);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment