aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 17:45:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 17:45:39 -0500
commitf8cc87b6c1e333ce7adc9fb2cb698d93b16eabe3 (patch)
tree3930a111959740f2ff2a1881f7ae627b38e477b4
parent2afe738fc070bf681227c0c9d95b9cd0c4782b0f (diff)
parent40c17f75dfa9ec163478efd3f7443fd6af9992c9 (diff)
Merge branch 'for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
Pull workqueue updates from Tejun Heo: "Workqueue has an early init trick where workqueues can be created and work items queued on them before the workqueue subsystem is online. This helps simplifying early init and operation of low level subsystems which use workqueues for managerial things which aren't depended upon early during boot. Out of laziness, the early init didn't cover workqueues with WQ_MEM_RECLAIM, which is inconsistent and confusing because adding the flag simply makes the system fail to boot. Cover WQ_MEM_RECLAIM too. This was originally brought up for RCU but RCU didn't actually need this. I still think it's a good idea to cover it" * 'for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: workqueue: allow WQ_MEM_RECLAIM on early init workqueues workqueue: separate out init_rescuer()
-rw-r--r--kernel/workqueue.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 8c34981d90ad..8dd2e66e8383 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3940,6 +3940,37 @@ static int wq_clamp_max_active(int max_active, unsigned int flags,
3940 return clamp_val(max_active, 1, lim); 3940 return clamp_val(max_active, 1, lim);
3941} 3941}
3942 3942
3943/*
3944 * Workqueues which may be used during memory reclaim should have a rescuer
3945 * to guarantee forward progress.
3946 */
3947static int init_rescuer(struct workqueue_struct *wq)
3948{
3949 struct worker *rescuer;
3950 int ret;
3951
3952 if (!(wq->flags & WQ_MEM_RECLAIM))
3953 return 0;
3954
3955 rescuer = alloc_worker(NUMA_NO_NODE);
3956 if (!rescuer)
3957 return -ENOMEM;
3958
3959 rescuer->rescue_wq = wq;
3960 rescuer->task = kthread_create(rescuer_thread, rescuer, "%s", wq->name);
3961 ret = PTR_ERR_OR_ZERO(rescuer->task);
3962 if (ret) {
3963 kfree(rescuer);
3964 return ret;
3965 }
3966
3967 wq->rescuer = rescuer;
3968 kthread_bind_mask(rescuer->task, cpu_possible_mask);
3969 wake_up_process(rescuer->task);
3970
3971 return 0;
3972}
3973
3943struct workqueue_struct *__alloc_workqueue_key(const char *fmt, 3974struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
3944 unsigned int flags, 3975 unsigned int flags,
3945 int max_active, 3976 int max_active,
@@ -4002,29 +4033,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
4002 if (alloc_and_link_pwqs(wq) < 0) 4033 if (alloc_and_link_pwqs(wq) < 0)
4003 goto err_free_wq; 4034 goto err_free_wq;
4004 4035
4005 /* 4036 if (wq_online && init_rescuer(wq) < 0)
4006 * Workqueues which may be used during memory reclaim should 4037 goto err_destroy;
4007 * have a rescuer to guarantee forward progress.
4008 */
4009 if (flags & WQ_MEM_RECLAIM) {
4010 struct worker *rescuer;
4011
4012 rescuer = alloc_worker(NUMA_NO_NODE);
4013 if (!rescuer)
4014 goto err_destroy;
4015
4016 rescuer->rescue_wq = wq;
4017 rescuer->task = kthread_create(rescuer_thread, rescuer, "%s",
4018 wq->name);
4019 if (IS_ERR(rescuer->task)) {
4020 kfree(rescuer);
4021 goto err_destroy;
4022 }
4023
4024 wq->rescuer = rescuer;
4025 kthread_bind_mask(rescuer->task, cpu_possible_mask);
4026 wake_up_process(rescuer->task);
4027 }
4028 4038
4029 if ((wq->flags & WQ_SYSFS) && workqueue_sysfs_register(wq)) 4039 if ((wq->flags & WQ_SYSFS) && workqueue_sysfs_register(wq))
4030 goto err_destroy; 4040 goto err_destroy;
@@ -5642,6 +5652,8 @@ int __init workqueue_init(void)
5642 * archs such as power and arm64. As per-cpu pools created 5652 * archs such as power and arm64. As per-cpu pools created
5643 * previously could be missing node hint and unbound pools NUMA 5653 * previously could be missing node hint and unbound pools NUMA
5644 * affinity, fix them up. 5654 * affinity, fix them up.
5655 *
5656 * Also, while iterating workqueues, create rescuers if requested.
5645 */ 5657 */
5646 wq_numa_init(); 5658 wq_numa_init();
5647 5659
@@ -5653,8 +5665,12 @@ int __init workqueue_init(void)
5653 } 5665 }
5654 } 5666 }
5655 5667
5656 list_for_each_entry(wq, &workqueues, list) 5668 list_for_each_entry(wq, &workqueues, list) {
5657 wq_update_unbound_numa(wq, smp_processor_id(), true); 5669 wq_update_unbound_numa(wq, smp_processor_id(), true);
5670 WARN(init_rescuer(wq),
5671 "workqueue: failed to create early rescuer for %s",
5672 wq->name);
5673 }
5658 5674
5659 mutex_unlock(&wq_pool_mutex); 5675 mutex_unlock(&wq_pool_mutex);
5660 5676