diff options
-rw-r--r-- | kernel/workqueue.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 43d18cb46308..5baac7c8a5f9 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -3939,6 +3939,37 @@ static int wq_clamp_max_active(int max_active, unsigned int flags, | |||
3939 | return clamp_val(max_active, 1, lim); | 3939 | return clamp_val(max_active, 1, lim); |
3940 | } | 3940 | } |
3941 | 3941 | ||
3942 | /* | ||
3943 | * Workqueues which may be used during memory reclaim should have a rescuer | ||
3944 | * to guarantee forward progress. | ||
3945 | */ | ||
3946 | static int init_rescuer(struct workqueue_struct *wq) | ||
3947 | { | ||
3948 | struct worker *rescuer; | ||
3949 | int ret; | ||
3950 | |||
3951 | if (!(wq->flags & WQ_MEM_RECLAIM)) | ||
3952 | return 0; | ||
3953 | |||
3954 | rescuer = alloc_worker(NUMA_NO_NODE); | ||
3955 | if (!rescuer) | ||
3956 | return -ENOMEM; | ||
3957 | |||
3958 | rescuer->rescue_wq = wq; | ||
3959 | rescuer->task = kthread_create(rescuer_thread, rescuer, "%s", wq->name); | ||
3960 | ret = PTR_ERR_OR_ZERO(rescuer->task); | ||
3961 | if (ret) { | ||
3962 | kfree(rescuer); | ||
3963 | return ret; | ||
3964 | } | ||
3965 | |||
3966 | wq->rescuer = rescuer; | ||
3967 | kthread_bind_mask(rescuer->task, cpu_possible_mask); | ||
3968 | wake_up_process(rescuer->task); | ||
3969 | |||
3970 | return 0; | ||
3971 | } | ||
3972 | |||
3942 | struct workqueue_struct *__alloc_workqueue_key(const char *fmt, | 3973 | struct workqueue_struct *__alloc_workqueue_key(const char *fmt, |
3943 | unsigned int flags, | 3974 | unsigned int flags, |
3944 | int max_active, | 3975 | int max_active, |
@@ -4001,29 +4032,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, | |||
4001 | if (alloc_and_link_pwqs(wq) < 0) | 4032 | if (alloc_and_link_pwqs(wq) < 0) |
4002 | goto err_free_wq; | 4033 | goto err_free_wq; |
4003 | 4034 | ||
4004 | /* | 4035 | if (init_rescuer(wq) < 0) |
4005 | * Workqueues which may be used during memory reclaim should | 4036 | goto err_destroy; |
4006 | * have a rescuer to guarantee forward progress. | ||
4007 | */ | ||
4008 | if (flags & WQ_MEM_RECLAIM) { | ||
4009 | struct worker *rescuer; | ||
4010 | |||
4011 | rescuer = alloc_worker(NUMA_NO_NODE); | ||
4012 | if (!rescuer) | ||
4013 | goto err_destroy; | ||
4014 | |||
4015 | rescuer->rescue_wq = wq; | ||
4016 | rescuer->task = kthread_create(rescuer_thread, rescuer, "%s", | ||
4017 | wq->name); | ||
4018 | if (IS_ERR(rescuer->task)) { | ||
4019 | kfree(rescuer); | ||
4020 | goto err_destroy; | ||
4021 | } | ||
4022 | |||
4023 | wq->rescuer = rescuer; | ||
4024 | kthread_bind_mask(rescuer->task, cpu_possible_mask); | ||
4025 | wake_up_process(rescuer->task); | ||
4026 | } | ||
4027 | 4037 | ||
4028 | if ((wq->flags & WQ_SYSFS) && workqueue_sysfs_register(wq)) | 4038 | if ((wq->flags & WQ_SYSFS) && workqueue_sysfs_register(wq)) |
4029 | goto err_destroy; | 4039 | goto err_destroy; |