The patch titled Subject: kthread: allow to modify delayed kthread work has been added to the -mm tree. Its filename is kthread-allow-to-modify-delayed-kthread-work.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/kthread-allow-to-modify-delayed-kthread-work.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/kthread-allow-to-modify-delayed-kthread-work.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Petr Mladek <pmladek@xxxxxxxx> Subject: kthread: allow to modify delayed kthread work There are situations when we need to modify the delay of a delayed kthread work. For example, when the work depends on an event and the initial delay means a timeout. Then we want to queue the work immediately when the event happens. This patch implements kthread_mod_delayed_work() as inspired workqueues. It cancels the timer, removes the work from any worker list and queues it again with the given timeout. A very special case is when the work is being canceled at the same time. It might happen because of the regular kthread_cancel_delayed_work_sync() or by another kthread_mod_delayed_work(). In this case, we do nothing and let the other operation win. This should not normally happen as the caller is supposed to synchronize these operations a reasonable way. Link: http://lkml.kernel.org/r/1470754545-17632-11-git-send-email-pmladek@xxxxxxxx Signed-off-by: Petr Mladek <pmladek@xxxxxxxx> Acked-by: Tejun Heo <tj@xxxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxxxxxxxxxx> Cc: Josh Triplett <josh@xxxxxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Jiri Kosina <jkosina@xxxxxxx> Cc: Borislav Petkov <bp@xxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/kthread.h | 4 ++ kernel/kthread.c | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff -puN include/linux/kthread.h~kthread-allow-to-modify-delayed-kthread-work include/linux/kthread.h --- a/include/linux/kthread.h~kthread-allow-to-modify-delayed-kthread-work +++ a/include/linux/kthread.h @@ -168,6 +168,10 @@ bool kthread_queue_delayed_work(struct k struct kthread_delayed_work *dwork, unsigned long delay); +bool kthread_mod_delayed_work(struct kthread_worker *worker, + struct kthread_delayed_work *dwork, + unsigned long delay); + void kthread_flush_work(struct kthread_work *work); void kthread_flush_worker(struct kthread_worker *worker); diff -puN kernel/kthread.c~kthread-allow-to-modify-delayed-kthread-work kernel/kthread.c --- a/kernel/kthread.c~kthread-allow-to-modify-delayed-kthread-work +++ a/kernel/kthread.c @@ -972,6 +972,59 @@ static bool __kthread_cancel_work(struct return false; } +/** + * kthread_mod_delayed_work - modify delay of or queue a kthread delayed work + * @worker: kthread worker to use + * @dwork: kthread delayed work to queue + * @delay: number of jiffies to wait before queuing + * + * If @dwork is idle, equivalent to kthread_queue_delayed_work(). Otherwise, + * modify @dwork's timer so that it expires after @delay. If @delay is zero, + * @work is guaranteed to be queued immediately. + * + * Return: %true if @dwork was pending and its timer was modified, + * %false otherwise. + * + * A special case is when the work is being canceled in parallel. + * It might be caused either by the real kthread_cancel_delayed_work_sync() + * or yet another kthread_mod_delayed_work() call. We let the other command + * win and return %false here. The caller is supposed to synchronize these + * operations a reasonable way. + * + * This function is safe to call from any context including IRQ handler. + * See __kthread_cancel_work() and kthread_delayed_work_timer_fn() + * for details. + */ +bool kthread_mod_delayed_work(struct kthread_worker *worker, + struct kthread_delayed_work *dwork, + unsigned long delay) +{ + struct kthread_work *work = &dwork->work; + unsigned long flags; + int ret = false; + + spin_lock_irqsave(&worker->lock, flags); + + /* Do not bother with canceling when never queued. */ + if (!work->worker) + goto fast_queue; + + /* Work must not be used with >1 worker, see kthread_queue_work() */ + WARN_ON_ONCE(work->worker != worker); + + /* Do not fight with another command that is canceling this work. */ + if (work->canceling) + goto out; + + ret = __kthread_cancel_work(work, true, &flags); +fast_queue: + __kthread_queue_delayed_work(worker, dwork, delay); +out: + spin_unlock_irqrestore(&worker->lock, flags); + return ret; +} +EXPORT_SYMBOL_GPL(kthread_mod_delayed_work); + static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) { struct kthread_worker *worker = work->worker; _ Patches currently in -mm which might be from pmladek@xxxxxxxx are kthread-rename-probe_kthread_data-to-kthread_probe_data.patch kthread-kthread-worker-api-cleanup.patch kthread-smpboot-do-not-park-in-kthread_create_on_cpu.patch kthread-allow-to-call-__kthread_create_on_node-with-va_list-args.patch kthread-add-kthread_create_worker.patch kthread-add-kthread_destroy_worker.patch kthread-detect-when-a-kthread-work-is-used-by-more-workers.patch kthread-initial-support-for-delayed-kthread-work.patch kthread-allow-to-cancel-kthread-work.patch kthread-allow-to-modify-delayed-kthread-work.patch kthread-better-support-freezable-kthread-workers.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html