typedef void (*kthread_work_func_t)(struct kthread_work *work);
 void kthread_delayed_work_timer_fn(unsigned long __data);
 
+enum {
+       KTW_FREEZABLE           = 1 << 0,       /* freeze during suspend */
+};
+
 struct kthread_worker {
+       unsigned int            flags;
        spinlock_t              lock;
        struct list_head        work_list;
        struct list_head        delayed_work_list;
 
 int kthread_worker_fn(void *worker_ptr);
 
-__printf(1, 2)
+__printf(2, 3)
 struct kthread_worker *
-kthread_create_worker(const char namefmt[], ...);
+kthread_create_worker(unsigned int flags, const char namefmt[], ...);
 
 struct kthread_worker *
-kthread_create_worker_on_cpu(int cpu, const char namefmt[], ...);
+kthread_create_worker_on_cpu(int cpu, unsigned int flags,
+                            const char namefmt[], ...);
 
 bool kthread_queue_work(struct kthread_worker *worker,
                        struct kthread_work *work);
 
                                const char *name,
                                struct lock_class_key *key)
 {
+       memset(worker, 0, sizeof(struct kthread_worker));
        spin_lock_init(&worker->lock);
        lockdep_set_class_and_name(&worker->lock, key, name);
        INIT_LIST_HEAD(&worker->work_list);
        INIT_LIST_HEAD(&worker->delayed_work_list);
-       worker->task = NULL;
 }
 EXPORT_SYMBOL_GPL(__kthread_init_worker);
 
         */
        WARN_ON(worker->task && worker->task != current);
        worker->task = current;
+
+       if (worker->flags & KTW_FREEZABLE)
+               set_freezable();
+
 repeat:
        set_current_state(TASK_INTERRUPTIBLE);  /* mb paired w/ kthread_stop */
 
 EXPORT_SYMBOL_GPL(kthread_worker_fn);
 
 static struct kthread_worker *
-__kthread_create_worker(int cpu, const char namefmt[], va_list args)
+__kthread_create_worker(int cpu, unsigned int flags,
+                       const char namefmt[], va_list args)
 {
        struct kthread_worker *worker;
        struct task_struct *task;
        if (IS_ERR(task))
                goto fail_task;
 
+       worker->flags = flags;
        worker->task = task;
        wake_up_process(task);
        return worker;
 
 /**
  * kthread_create_worker - create a kthread worker
+ * @flags: flags modifying the default behavior of the worker
  * @namefmt: printf-style name for the kthread worker (task).
  *
  * Returns a pointer to the allocated worker on success, ERR_PTR(-ENOMEM)
  * when the worker was SIGKILLed.
  */
 struct kthread_worker *
-kthread_create_worker(const char namefmt[], ...)
+kthread_create_worker(unsigned int flags, const char namefmt[], ...)
 {
        struct kthread_worker *worker;
        va_list args;
 
        va_start(args, namefmt);
-       worker = __kthread_create_worker(-1, namefmt, args);
+       worker = __kthread_create_worker(-1, flags, namefmt, args);
        va_end(args);
 
        return worker;
  * kthread_create_worker_on_cpu - create a kthread worker and bind it
  *     it to a given CPU and the associated NUMA node.
  * @cpu: CPU number
+ * @flags: flags modifying the default behavior of the worker
  * @namefmt: printf-style name for the kthread worker (task).
  *
  * Use a valid CPU number if you want to bind the kthread worker
  * when the worker was SIGKILLed.
  */
 struct kthread_worker *
-kthread_create_worker_on_cpu(int cpu, const char namefmt[], ...)
+kthread_create_worker_on_cpu(int cpu, unsigned int flags,
+                            const char namefmt[], ...)
 {
        struct kthread_worker *worker;
        va_list args;
 
        va_start(args, namefmt);
-       worker = __kthread_create_worker(cpu, namefmt, args);
+       worker = __kthread_create_worker(cpu, flags, namefmt, args);
        va_end(args);
 
        return worker;