Hello, Because IRQs can happen between delayed_work->timer being dispatched and delayed_work_timer_fn() actually queueing delayed_work->work, try_to_grab_pending() couldn't be used from IRQ handlers. If it hits the window, it will return -EAGAIN perpetually. This makes it impossible to steal PENDING from IRQ handlers using try_to_grab_pending() leading to the following issues.
* mod_delayed_work() can't be used from IRQ handlers. * __cancel_delayed_work() can't use the usual try_to_grab_pending() which handles all three states but instead only deals with the first state using a separate implementation. There's no way to make a delayed_work not pending from IRQ handlers. * The context / behavior differences among cancel_delayed_work(), __cancel_delayed_work(), cancel_delayed_work_sync() are subtle and confusing (the first two are mostly historical tho). This patchset makes delayed_work use the irqsafe timer added by the pending "timer: clean up initializers and implement irqsafe timers" patchset[1]. This enables try_to_grab_pending() to be used from any context which in turn makes mod_delayed_work() usable from IRQ handlers. cancel_delayed_work() is reimplemented using try_to_grab_pending() so that it also can be used from IRQ handlers and its behavior is consitent with other canceling operations. __cancel_delayed_work() is no longer necessary and deprecated. 0001-workqueue-cosmetic-whitespace-updates-for-macro-defi.patch 0002-workqueue-make-deferrable-delayed_work-initializer-n.patch 0003-workqueue-clean-up-delayed_work-initializers-and-add.patch 0004-workqueue-use-irqsafe-timer-for-delayed_work.patch 0005-workqueue-use-mod_delayed_work-instead-of-__cancel-q.patch 0006-workqueue-reimplement-cancel_delayed_work-using-try_.patch 0007-workqueue-deprecate-__cancel_delayed_work.patch 0001-0003 are prep patches. 0004 makes delayed_work use irqsafe timers. This makes try_to_grab_pending() and mod_delayed_work() safe to use from any context. 0005 converts all __cancel_delayed_work() + queue_delayed_work() sequences to mod_delayed_work(). The link_watch conversion needs David's ack. 0006 reimplements cancel_delayed_work() using try_to_grab_pending(). 0007 replaces __cancel_delayed_work() calls with cancel_delayed_work() and deprecates the underscored one. This patchset is on top of [2] wq/for-3.7 (8fcd63664f "workqueue: fix CPU binding of flush_delayed...") + [1] timer: clean up initializers and implement irqsafe timers and available in the following git branch. git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git review-delayed_work-irqsafe diffstat follows. arch/powerpc/platforms/cell/cpufreq_spudemand.c | 2 block/blk-core.c | 8 - block/blk-throttle.c | 7 - drivers/block/floppy.c | 5 drivers/cpufreq/cpufreq_conservative.c | 2 drivers/cpufreq/cpufreq_ondemand.c | 2 drivers/devfreq/devfreq.c | 2 drivers/infiniband/core/mad.c | 16 -- drivers/input/keyboard/qt2160.c | 3 drivers/input/mouse/synaptics_i2c.c | 7 - drivers/net/ethernet/mellanox/mlx4/sense.c | 2 drivers/power/ab8500_btemp.c | 2 drivers/power/ab8500_charger.c | 8 - drivers/power/ab8500_fg.c | 8 - drivers/power/abx500_chargalg.c | 4 drivers/power/max17040_battery.c | 2 drivers/video/omap2/displays/panel-taal.c | 6 drivers/video/omap2/dss/dsi.c | 6 include/linux/workqueue.h | 155 ++++++++++-------------- kernel/workqueue.c | 50 ++++++- mm/slab.c | 2 mm/vmstat.c | 2 net/core/link_watch.c | 21 --- net/core/neighbour.c | 2 net/ipv4/inetpeer.c | 2 net/sunrpc/cache.c | 2 26 files changed, 159 insertions(+), 169 deletions(-) -- tejun [1] http://thread.gmane.org/gmane.linux.kernel/1340224 [2] git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git for-3.7 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/