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.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -1125,7 +1125,9 @@ EXPORT_SYMBOL_GPL(delayed_work_timer_fn); · 1124 unmodified lines | ||
| 1125 | 1125 | * @dwork: work to queue |
| 1126 | 1126 | * @delay: number of jiffies to wait before queueing |
| 1127 | 1127 | * |
| 1128 | − * Returns %false if @work was already on a queue, %true otherwise. | |
| 1128 | + * Returns %false if @work was already on a queue, %true otherwise. If | |
| 1129 | + * @delay is zero and @dwork is idle, it will be scheduled for immediate | |
| 1130 | + * execution. | |
| 1129 | 1131 | */ |
| 1130 | 1132 | bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, |
| 1131 | 1133 | struct delayed_work *dwork, unsigned long delay) |
| @@ -1135,6 +1137,9 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, · 3 unmodified lines | ||
| 1135 | 1137 | bool ret = false; |
| 1136 | 1138 | unsigned long flags; |
| 1137 | 1139 | |
| 1140 | + if (!delay) | |
| 1141 | + return queue_work_on(cpu, wq, &dwork->work); | |
| 1142 | + | |
| 1138 | 1143 | /* read the comment in __queue_work() */ |
| 1139 | 1144 | local_irq_save(flags); |
| 1140 | 1145 | |
| @@ -1185,14 +1190,11 @@ EXPORT_SYMBOL_GPL(queue_delayed_work_on); · 44 unmodified lines | ||
| 1185 | 1190 | * @dwork: delayable work to queue |
| 1186 | 1191 | * @delay: number of jiffies to wait before queueing |
| 1187 | 1192 | * |
| 1188 | − * Returns %false if @work was already on a queue, %true otherwise. | |
| 1193 | + * Equivalent to queue_delayed_work_on() but tries to use the local CPU. | |
| 1189 | 1194 | */ |
| 1190 | 1195 | bool queue_delayed_work(struct workqueue_struct *wq, |
| 1191 | 1196 | struct delayed_work *dwork, unsigned long delay) |
| 1192 | 1197 | { |
| 1193 | − if (delay == 0) | |
| 1194 | − return queue_work(wq, &dwork->work); | |
| 1195 | − | |
| 1196 | 1198 | return queue_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay); |
| 1197 | 1199 | } |
| 1198 | 1200 | EXPORT_SYMBOL_GPL(queue_delayed_work); |