aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/fcoe.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 8a1005d117b7..46c57e5755ae 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -31,6 +31,7 @@
31#include <linux/fs.h> 31#include <linux/fs.h>
32#include <linux/sysfs.h> 32#include <linux/sysfs.h>
33#include <linux/ctype.h> 33#include <linux/ctype.h>
34#include <linux/workqueue.h>
34#include <scsi/scsi_tcq.h> 35#include <scsi/scsi_tcq.h>
35#include <scsi/scsicam.h> 36#include <scsi/scsicam.h>
36#include <scsi/scsi_transport.h> 37#include <scsi/scsi_transport.h>
@@ -58,6 +59,8 @@ MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \
58 59
59DEFINE_MUTEX(fcoe_config_mutex); 60DEFINE_MUTEX(fcoe_config_mutex);
60 61
62static struct workqueue_struct *fcoe_wq;
63
61/* fcoe_percpu_clean completion. Waiter protected by fcoe_create_mutex */ 64/* fcoe_percpu_clean completion. Waiter protected by fcoe_create_mutex */
62static DECLARE_COMPLETION(fcoe_flush_completion); 65static DECLARE_COMPLETION(fcoe_flush_completion);
63 66
@@ -1896,7 +1899,7 @@ static int fcoe_device_notification(struct notifier_block *notifier,
1896 list_del(&fcoe->list); 1899 list_del(&fcoe->list);
1897 port = lport_priv(fcoe->ctlr.lp); 1900 port = lport_priv(fcoe->ctlr.lp);
1898 fcoe_interface_cleanup(fcoe); 1901 fcoe_interface_cleanup(fcoe);
1899 schedule_work(&port->destroy_work); 1902 queue_work(fcoe_wq, &port->destroy_work);
1900 goto out; 1903 goto out;
1901 break; 1904 break;
1902 case NETDEV_FEAT_CHANGE: 1905 case NETDEV_FEAT_CHANGE:
@@ -2387,6 +2390,10 @@ static int __init fcoe_init(void)
2387 unsigned int cpu; 2390 unsigned int cpu;
2388 int rc = 0; 2391 int rc = 0;
2389 2392
2393 fcoe_wq = alloc_workqueue("fcoe", 0, 0);
2394 if (!fcoe_wq)
2395 return -ENOMEM;
2396
2390 /* register as a fcoe transport */ 2397 /* register as a fcoe transport */
2391 rc = fcoe_transport_attach(&fcoe_sw_transport); 2398 rc = fcoe_transport_attach(&fcoe_sw_transport);
2392 if (rc) { 2399 if (rc) {
@@ -2425,6 +2432,7 @@ out_free:
2425 fcoe_percpu_thread_destroy(cpu); 2432 fcoe_percpu_thread_destroy(cpu);
2426 } 2433 }
2427 mutex_unlock(&fcoe_config_mutex); 2434 mutex_unlock(&fcoe_config_mutex);
2435 destroy_workqueue(fcoe_wq);
2428 return rc; 2436 return rc;
2429} 2437}
2430module_init(fcoe_init); 2438module_init(fcoe_init);
@@ -2450,7 +2458,7 @@ static void __exit fcoe_exit(void)
2450 list_del(&fcoe->list); 2458 list_del(&fcoe->list);
2451 port = lport_priv(fcoe->ctlr.lp); 2459 port = lport_priv(fcoe->ctlr.lp);
2452 fcoe_interface_cleanup(fcoe); 2460 fcoe_interface_cleanup(fcoe);
2453 schedule_work(&port->destroy_work); 2461 queue_work(fcoe_wq, &port->destroy_work);
2454 } 2462 }
2455 rtnl_unlock(); 2463 rtnl_unlock();
2456 2464
@@ -2461,15 +2469,17 @@ static void __exit fcoe_exit(void)
2461 2469
2462 mutex_unlock(&fcoe_config_mutex); 2470 mutex_unlock(&fcoe_config_mutex);
2463 2471
2464 /* flush any asyncronous interface destroys, 2472 /*
2465 * this should happen after the netdev notifier is unregistered */ 2473 * destroy_work's may be chained but destroy_workqueue()
2466 flush_scheduled_work(); 2474 * can take care of them. Just kill the fcoe_wq.
2467 /* That will flush out all the N_Ports on the hostlist, but now we 2475 */
2468 * may have NPIV VN_Ports scheduled for destruction */ 2476 destroy_workqueue(fcoe_wq);
2469 flush_scheduled_work();
2470 2477
2471 /* detach from scsi transport 2478 /*
2472 * must happen after all destroys are done, therefor after the flush */ 2479 * Detaching from the scsi transport must happen after all
2480 * destroys are done on the fcoe_wq. destroy_workqueue will
2481 * enusre the fcoe_wq is flushed.
2482 */
2473 fcoe_if_exit(); 2483 fcoe_if_exit();
2474 2484
2475 /* detach from fcoe transport */ 2485 /* detach from fcoe transport */
@@ -2618,7 +2628,7 @@ static int fcoe_vport_destroy(struct fc_vport *vport)
2618 mutex_lock(&n_port->lp_mutex); 2628 mutex_lock(&n_port->lp_mutex);
2619 list_del(&vn_port->list); 2629 list_del(&vn_port->list);
2620 mutex_unlock(&n_port->lp_mutex); 2630 mutex_unlock(&n_port->lp_mutex);
2621 schedule_work(&port->destroy_work); 2631 queue_work(fcoe_wq, &port->destroy_work);
2622 return 0; 2632 return 0;
2623} 2633}
2624 2634