aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 12:28:19 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 12:28:19 -0500
commit68380b581383c028830f79ec2670f4a193854aa6 (patch)
tree49ea33a67213702ff56ca5843435c75749ac0ab3 /drivers
parent2fd8507d14ef7af3ae05316b3277044cf6daa381 (diff)
Add "run_scheduled_work()" workqueue function
This allows workqueue users to run just their own pending work, rather than wait for the whole workqueue to finish running. This solves the deadlock with networking libphy that was due to other workqueue entries possibly needing a lock that was held by the routine that wanted to flush its own work. It's not wonderful: if you absolutely need to synchronize with the work function having been executed, any user strictly speaking should have its own completion tracking logic, since when we run things explicitly by hand, the generic workqueue layer can no longer help us synchronize. Also, this is strictly only usable for work that has been scheduled without any delayed timers. You can not mix the new interface with schedule_delayed_work(). But it's better than what we had currently. Acked-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/phy.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 4044bb1ada86..e175f3910b18 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -587,8 +587,7 @@ int phy_stop_interrupts(struct phy_device *phydev)
587 * Finish any pending work; we might have been scheduled 587 * Finish any pending work; we might have been scheduled
588 * to be called from keventd ourselves, though. 588 * to be called from keventd ourselves, though.
589 */ 589 */
590 if (!current_is_keventd()) 590 run_scheduled_work(&phydev->phy_queue);
591 flush_scheduled_work();
592 591
593 free_irq(phydev->irq, phydev); 592 free_irq(phydev->irq, phydev);
594 593