workqueue: fix zero @delay handling of queue_delayed_work_on()
authorTejun Heo <tj@kernel.org>
Fri, 3 Aug 2012 17:30:46 +0000 (10:30 -0700)
committerTejun Heo <tj@kernel.org>
Fri, 3 Aug 2012 17:30:46 +0000 (10:30 -0700)
If @delay is zero and the dealyed_work is idle, queue_delayed_work()
queues it for immediate execution; however, queue_delayed_work_on()
lacks this logic and always goes through timer regardless of @delay.

This patch moves 0 @delay handling logic from queue_delayed_work() to
queue_delayed_work_on() so that both functions behave the same.

Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/workqueue.c

index ce60bb5d12fb27966a63d3494d637c6bef105f14..6cbdc22f8ec7cbf2e5e0ec0814b2852e14f160ef 100644 (file)
@@ -1125,7 +1125,9 @@ EXPORT_SYMBOL_GPL(delayed_work_timer_fn);
  * @dwork: work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns %false if @work was already on a queue, %true otherwise.
+ * Returns %false if @work was already on a queue, %true otherwise.  If
+ * @delay is zero and @dwork is idle, it will be scheduled for immediate
+ * execution.
  */
 bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
                           struct delayed_work *dwork, unsigned long delay)
@@ -1135,6 +1137,9 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
        bool ret = false;
        unsigned long flags;
 
+       if (!delay)
+               return queue_work_on(cpu, wq, &dwork->work);
+
        /* read the comment in __queue_work() */
        local_irq_save(flags);
 
@@ -1185,14 +1190,11 @@ EXPORT_SYMBOL_GPL(queue_delayed_work_on);
  * @dwork: delayable work to queue
  * @delay: number of jiffies to wait before queueing
  *
- * Returns %false if @work was already on a queue, %true otherwise.
+ * Equivalent to queue_delayed_work_on() but tries to use the local CPU.
  */
 bool queue_delayed_work(struct workqueue_struct *wq,
                        struct delayed_work *dwork, unsigned long delay)
 {
-       if (delay == 0)
-               return queue_work(wq, &dwork->work);
-
        return queue_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay);
 }
 EXPORT_SYMBOL_GPL(queue_delayed_work);