• Petr Mladek's avatar
    kthread: allow to cancel kthread work · 37be45d4
    Petr Mladek authored
    We are going to use kthread workers more widely and sometimes we will need
    to make sure that the work is neither pending nor running.
    
    This patch implements cancel_*_sync() operations as inspired by
    workqueues.  Well, we are synchronized against the other operations via
    the worker lock, we use del_timer_sync() and a counter to count parallel
    cancel operations.  Therefore the implementation might be easier.
    
    First, we check if a worker is assigned.  If not, the work has newer been
    queued after it was initialized.
    
    Second, we take the worker lock.  It must be the right one.  The work must
    not be assigned to another worker unless it is initialized in between.
    
    Third, we try to cancel the timer when it exists.  The timer is deleted
    synchronously to make sure that the timer call back is not running.  We
    need to temporary release the worker->lock to avoid a possible deadlock
    with the callback.  In the meantime, we set work->canceling counter to
    avoid any queuing.
    
    Fourth, we try to remove the work from a worker list. It might be
    the list of either normal or delayed works.
    
    Fifth, if the work is running, we call kthread_flush_work().  It might
    take an arbitrary time.  We need to release the worker-lock again.  In the
    meantime, we again block any queuing by the canceling counter.
    
    As already mentioned, the check for a pending kthread work is done under a
    lock.  In compare with workqueues, we do not need to fight for a single
    PENDING bit to block other operations.  Therefore we do not suffer from
    the thundering storm problem and all parallel canceling jobs might use
    kthread_flush_work().  Any queuing is blocked until the counter gets zero.
    
    Link: http://lkml.kernel.org/r/1470754545-17632-10-git-send-email-pmladek@suse.comSigned-off-by: default avatarPetr Mladek <pmladek@suse.com>
    Acked-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
    Cc: Josh Triplett <josh@joshtriplett.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Jiri Kosina <jkosina@suse.cz>
    Cc: Borislav Petkov <bp@suse.de>
    Cc: Michal Hocko <mhocko@suse.cz>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    37be45d4
kthread.c 30 KB