aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorIvo van Doorn <IvDoorn@gmail.com>2011-01-30 07:24:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-31 15:06:25 -0500
commit0439f5367c8d8bb2ebaca8d7329f51f3148b2fb2 (patch)
treedee1b60792da49cd903266ec8daf90516c604c49 /drivers/net
parente1f4e808bb7a884d6563553c2c94cbdd901a16c7 (diff)
rt2x00: Move TX/RX work into dedicated workqueue
The TX/RX work structures must be able to run independently of other workqueues. This is because mac80211 might use the flush() callback function from various context, which depends on the TX/RX work to complete while the main thread is blocked (until the the TX queues are empty). This should reduce the number of 'Queue %d failed to flush' warnings. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c8
4 files changed, 25 insertions, 7 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7661e4f60ddc..39bc2faf1793 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -860,6 +860,13 @@ struct rt2x00_dev {
860 */ 860 */
861 struct ieee80211_low_level_stats low_level_stats; 861 struct ieee80211_low_level_stats low_level_stats;
862 862
863 /**
864 * Work queue for all work which should not be placed
865 * on the mac80211 workqueue (because of dependencies
866 * between various work structures).
867 */
868 struct workqueue_struct *workqueue;
869
863 /* 870 /*
864 * Scheduled work. 871 * Scheduled work.
865 * NOTE: intf_work will use ieee80211_iterate_active_interfaces() 872 * NOTE: intf_work will use ieee80211_iterate_active_interfaces()
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e7162852ec34..9de9dbe94399 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -997,8 +997,15 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
997 BIT(NL80211_IFTYPE_WDS); 997 BIT(NL80211_IFTYPE_WDS);
998 998
999 /* 999 /*
1000 * Initialize configuration work. 1000 * Initialize work.
1001 */ 1001 */
1002 rt2x00dev->workqueue =
1003 alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0);
1004 if (!rt2x00dev->workqueue) {
1005 retval = -ENOMEM;
1006 goto exit;
1007 }
1008
1002 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); 1009 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
1003 1010
1004 /* 1011 /*
@@ -1057,6 +1064,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1057 cancel_work_sync(&rt2x00dev->intf_work); 1064 cancel_work_sync(&rt2x00dev->intf_work);
1058 cancel_work_sync(&rt2x00dev->rxdone_work); 1065 cancel_work_sync(&rt2x00dev->rxdone_work);
1059 cancel_work_sync(&rt2x00dev->txdone_work); 1066 cancel_work_sync(&rt2x00dev->txdone_work);
1067 destroy_workqueue(rt2x00dev->workqueue);
1060 1068
1061 /* 1069 /*
1062 * Free the tx status fifo. 1070 * Free the tx status fifo.
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index bfda60eaf4ef..c975b0a12e95 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -417,7 +417,8 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) 417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
418 return; 418 return;
419 419
420 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); 420 ieee80211_queue_delayed_work(rt2x00dev->hw,
421 &link->watchdog_work, WATCHDOG_INTERVAL);
421} 422}
422 423
423void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) 424void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -441,7 +442,9 @@ static void rt2x00link_watchdog(struct work_struct *work)
441 rt2x00dev->ops->lib->watchdog(rt2x00dev); 442 rt2x00dev->ops->lib->watchdog(rt2x00dev);
442 443
443 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 444 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
444 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); 445 ieee80211_queue_delayed_work(rt2x00dev->hw,
446 &link->watchdog_work,
447 WATCHDOG_INTERVAL);
445} 448}
446 449
447void rt2x00link_register(struct rt2x00_dev *rt2x00dev) 450void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 1a9937d5aff6..fbe735f5b352 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -227,7 +227,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
227 * Schedule the delayed work for reading the TX status 227 * Schedule the delayed work for reading the TX status
228 * from the device. 228 * from the device.
229 */ 229 */
230 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); 230 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
231} 231}
232 232
233static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 233static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -320,7 +320,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
320 * Schedule the delayed work for reading the RX status 320 * Schedule the delayed work for reading the RX status
321 * from the device. 321 * from the device.
322 */ 322 */
323 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); 323 queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
324} 324}
325 325
326static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) 326static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
@@ -429,7 +429,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
429 * Schedule the completion handler manually, when this 429 * Schedule the completion handler manually, when this
430 * worker function runs, it should cleanup the queue. 430 * worker function runs, it should cleanup the queue.
431 */ 431 */
432 ieee80211_queue_work(queue->rt2x00dev->hw, completion); 432 queue_work(queue->rt2x00dev->workqueue, completion);
433 433
434 /* 434 /*
435 * Wait for a little while to give the driver 435 * Wait for a little while to give the driver
@@ -453,7 +453,7 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
453 WARNING(queue->rt2x00dev, "TX queue %d status timed out," 453 WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
454 " invoke forced tx handler\n", queue->qid); 454 " invoke forced tx handler\n", queue->qid);
455 455
456 ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); 456 queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work);
457} 457}
458 458
459void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) 459void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)