Skip to content
  • Oleg Nesterov's avatar
    [WORKQUEUE]: cancel_delayed_work: use del_timer() instead of del_timer_sync() · 071b6386
    Oleg Nesterov authored
    
    
    del_timer_sync() buys nothing for cancel_delayed_work(), but it is less
    efficient since it locks the timer unconditionally, and may wait for the
    completion of the delayed_work_timer_fn().
    
    cancel_delayed_work() == 0 means:
    
    	before this patch:
    		work->func may still be running or queued
    
    	after this patch:
    		work->func may still be running or queued, or
    		delayed_work_timer_fn->__queue_work() in progress.
    
    		The latter doesn't differ from the caller's POV,
    		delayed_work_timer_fn() is called with _PENDING
    		bit set.
    
    cancel_delayed_work() == 1 with this patch adds a new possibility:
    
    	delayed_work->work was cancelled, but delayed_work_timer_fn
    	is still running (this is only possible for the re-arming
    	works on single-threaded workqueue).
    
    	In this case the timer was re-started by work->func(), nobody
    	else can do this. This in turn means that delayed_work_timer_fn
    	has already passed __queue_work() (and wont't touch delayed_work)
    	because nobody else can queue delayed_work->work.
    
    Signed-off-by: default avatarOleg Nesterov <oleg@tv-sign.ru>
    Signed-Off-By: default avatarDavid Howells <dhowells@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    071b6386