aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kthread.h12
-rw-r--r--kernel/kthread.c21
2 files changed, 24 insertions, 9 deletions
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 5c2ec2c4eb22..4f5235cb13bb 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -65,7 +65,12 @@ struct kthread_work;
65typedef void (*kthread_work_func_t)(struct kthread_work *work); 65typedef void (*kthread_work_func_t)(struct kthread_work *work);
66void kthread_delayed_work_timer_fn(unsigned long __data); 66void kthread_delayed_work_timer_fn(unsigned long __data);
67 67
68enum {
69 KTW_FREEZABLE = 1 << 0, /* freeze during suspend */
70};
71
68struct kthread_worker { 72struct kthread_worker {
73 unsigned int flags;
69 spinlock_t lock; 74 spinlock_t lock;
70 struct list_head work_list; 75 struct list_head work_list;
71 struct list_head delayed_work_list; 76 struct list_head delayed_work_list;
@@ -154,12 +159,13 @@ extern void __kthread_init_worker(struct kthread_worker *worker,
154 159
155int kthread_worker_fn(void *worker_ptr); 160int kthread_worker_fn(void *worker_ptr);
156 161
157__printf(1, 2) 162__printf(2, 3)
158struct kthread_worker * 163struct kthread_worker *
159kthread_create_worker(const char namefmt[], ...); 164kthread_create_worker(unsigned int flags, const char namefmt[], ...);
160 165
161struct kthread_worker * 166struct kthread_worker *
162kthread_create_worker_on_cpu(int cpu, const char namefmt[], ...); 167kthread_create_worker_on_cpu(int cpu, unsigned int flags,
168 const char namefmt[], ...);
163 169
164bool kthread_queue_work(struct kthread_worker *worker, 170bool kthread_queue_work(struct kthread_worker *worker,
165 struct kthread_work *work); 171 struct kthread_work *work);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index c1fcc63fa605..be2cc1f9dd57 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -560,11 +560,11 @@ void __kthread_init_worker(struct kthread_worker *worker,
560 const char *name, 560 const char *name,
561 struct lock_class_key *key) 561 struct lock_class_key *key)
562{ 562{
563 memset(worker, 0, sizeof(struct kthread_worker));
563 spin_lock_init(&worker->lock); 564 spin_lock_init(&worker->lock);
564 lockdep_set_class_and_name(&worker->lock, key, name); 565 lockdep_set_class_and_name(&worker->lock, key, name);
565 INIT_LIST_HEAD(&worker->work_list); 566 INIT_LIST_HEAD(&worker->work_list);
566 INIT_LIST_HEAD(&worker->delayed_work_list); 567 INIT_LIST_HEAD(&worker->delayed_work_list);
567 worker->task = NULL;
568} 568}
569EXPORT_SYMBOL_GPL(__kthread_init_worker); 569EXPORT_SYMBOL_GPL(__kthread_init_worker);
570 570
@@ -594,6 +594,10 @@ int kthread_worker_fn(void *worker_ptr)
594 */ 594 */
595 WARN_ON(worker->task && worker->task != current); 595 WARN_ON(worker->task && worker->task != current);
596 worker->task = current; 596 worker->task = current;
597
598 if (worker->flags & KTW_FREEZABLE)
599 set_freezable();
600
597repeat: 601repeat:
598 set_current_state(TASK_INTERRUPTIBLE); /* mb paired w/ kthread_stop */ 602 set_current_state(TASK_INTERRUPTIBLE); /* mb paired w/ kthread_stop */
599 603
@@ -627,7 +631,8 @@ repeat:
627EXPORT_SYMBOL_GPL(kthread_worker_fn); 631EXPORT_SYMBOL_GPL(kthread_worker_fn);
628 632
629static struct kthread_worker * 633static struct kthread_worker *
630__kthread_create_worker(int cpu, const char namefmt[], va_list args) 634__kthread_create_worker(int cpu, unsigned int flags,
635 const char namefmt[], va_list args)
631{ 636{
632 struct kthread_worker *worker; 637 struct kthread_worker *worker;
633 struct task_struct *task; 638 struct task_struct *task;
@@ -657,6 +662,7 @@ __kthread_create_worker(int cpu, const char namefmt[], va_list args)
657 if (IS_ERR(task)) 662 if (IS_ERR(task))
658 goto fail_task; 663 goto fail_task;
659 664
665 worker->flags = flags;
660 worker->task = task; 666 worker->task = task;
661 wake_up_process(task); 667 wake_up_process(task);
662 return worker; 668 return worker;
@@ -668,6 +674,7 @@ fail_task:
668 674
669/** 675/**
670 * kthread_create_worker - create a kthread worker 676 * kthread_create_worker - create a kthread worker
677 * @flags: flags modifying the default behavior of the worker
671 * @namefmt: printf-style name for the kthread worker (task). 678 * @namefmt: printf-style name for the kthread worker (task).
672 * 679 *
673 * Returns a pointer to the allocated worker on success, ERR_PTR(-ENOMEM) 680 * Returns a pointer to the allocated worker on success, ERR_PTR(-ENOMEM)
@@ -675,13 +682,13 @@ fail_task:
675 * when the worker was SIGKILLed. 682 * when the worker was SIGKILLed.
676 */ 683 */
677struct kthread_worker * 684struct kthread_worker *
678kthread_create_worker(const char namefmt[], ...) 685kthread_create_worker(unsigned int flags, const char namefmt[], ...)
679{ 686{
680 struct kthread_worker *worker; 687 struct kthread_worker *worker;
681 va_list args; 688 va_list args;
682 689
683 va_start(args, namefmt); 690 va_start(args, namefmt);
684 worker = __kthread_create_worker(-1, namefmt, args); 691 worker = __kthread_create_worker(-1, flags, namefmt, args);
685 va_end(args); 692 va_end(args);
686 693
687 return worker; 694 return worker;
@@ -692,6 +699,7 @@ EXPORT_SYMBOL(kthread_create_worker);
692 * kthread_create_worker_on_cpu - create a kthread worker and bind it 699 * kthread_create_worker_on_cpu - create a kthread worker and bind it
693 * it to a given CPU and the associated NUMA node. 700 * it to a given CPU and the associated NUMA node.
694 * @cpu: CPU number 701 * @cpu: CPU number
702 * @flags: flags modifying the default behavior of the worker
695 * @namefmt: printf-style name for the kthread worker (task). 703 * @namefmt: printf-style name for the kthread worker (task).
696 * 704 *
697 * Use a valid CPU number if you want to bind the kthread worker 705 * Use a valid CPU number if you want to bind the kthread worker
@@ -705,13 +713,14 @@ EXPORT_SYMBOL(kthread_create_worker);
705 * when the worker was SIGKILLed. 713 * when the worker was SIGKILLed.
706 */ 714 */
707struct kthread_worker * 715struct kthread_worker *
708kthread_create_worker_on_cpu(int cpu, const char namefmt[], ...) 716kthread_create_worker_on_cpu(int cpu, unsigned int flags,
717 const char namefmt[], ...)
709{ 718{
710 struct kthread_worker *worker; 719 struct kthread_worker *worker;
711 va_list args; 720 va_list args;
712 721
713 va_start(args, namefmt); 722 va_start(args, namefmt);
714 worker = __kthread_create_worker(cpu, namefmt, args); 723 worker = __kthread_create_worker(cpu, flags, namefmt, args);
715 va_end(args); 724 va_end(args);
716 725
717 return worker; 726 return worker;