}
 EXPORT_SYMBOL_GPL(kthread_flush_work);
 
+/*
+ * Make sure that the timer is neither set nor running and could
+ * not manipulate the work list_head any longer.
+ *
+ * The function is called under worker->lock. The lock is temporary
+ * released but the timer can't be set again in the meantime.
+ */
+static void kthread_cancel_delayed_work_timer(struct kthread_work *work,
+                                             unsigned long *flags)
+{
+       struct kthread_delayed_work *dwork =
+               container_of(work, struct kthread_delayed_work, work);
+       struct kthread_worker *worker = work->worker;
+
+       /*
+        * del_timer_sync() must be called to make sure that the timer
+        * callback is not running. The lock must be temporary released
+        * to avoid a deadlock with the callback. In the meantime,
+        * any queuing is blocked by setting the canceling counter.
+        */
+       work->canceling++;
+       raw_spin_unlock_irqrestore(&worker->lock, *flags);
+       del_timer_sync(&dwork->timer);
+       raw_spin_lock_irqsave(&worker->lock, *flags);
+       work->canceling--;
+}
+
 /*
  * This function removes the work from the worker queue. Also it makes sure
  * that it won't get queued later via the delayed work's timer.
                                  unsigned long *flags)
 {
        /* Try to cancel the timer if exists. */
-       if (is_dwork) {
-               struct kthread_delayed_work *dwork =
-                       container_of(work, struct kthread_delayed_work, work);
-               struct kthread_worker *worker = work->worker;
-
-               /*
-                * del_timer_sync() must be called to make sure that the timer
-                * callback is not running. The lock must be temporary released
-                * to avoid a deadlock with the callback. In the meantime,
-                * any queuing is blocked by setting the canceling counter.
-                */
-               work->canceling++;
-               raw_spin_unlock_irqrestore(&worker->lock, *flags);
-               del_timer_sync(&dwork->timer);
-               raw_spin_lock_irqsave(&worker->lock, *flags);
-               work->canceling--;
-       }
+       if (is_dwork)
+               kthread_cancel_delayed_work_timer(work, flags);
 
        /*
         * Try to remove the work from a worker list. It might either