diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-03-14 16:00:56 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-08-28 19:15:20 -0800 |
commit | bd1f4c3b60629c957f03b7f94db1bced11801106 (patch) | |
tree | 432253558f1cf3b5d3a373798f8dd3a4dfb66d48 | |
parent | 0dd77eed2b36a0145bd8a6a4e73935e8b533cc28 (diff) |
workqueue: system_unbound_freezable_wq
-rw-r--r-- | fs/bcachefs/journal.c | 2 | ||||
-rw-r--r-- | include/linux/workqueue.h | 1 | ||||
-rw-r--r-- | kernel/async.c | 2 | ||||
-rw-r--r-- | kernel/workqueue.c | 38 |
4 files changed, 39 insertions, 4 deletions
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index ae8c213c638f..c0ea77524792 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -807,7 +807,7 @@ const char *bch_journal_read(struct cache_set *c, struct list_head *list) for_each_cache(ca, c, iter) closure_call(&ca->journal.read, bch_journal_read_device, - system_unbound_wq, + system_unbound_freezable_wq, &jlist.cl); closure_sync(&jlist.cl); diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index b853f6d1a458..d4bc4482eebe 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -355,6 +355,7 @@ extern struct workqueue_struct *system_highpri_wq; extern struct workqueue_struct *system_long_wq; extern struct workqueue_struct *system_unbound_wq; extern struct workqueue_struct *system_freezable_wq; +extern struct workqueue_struct *system_unbound_freezable_wq; extern struct workqueue_struct *system_power_efficient_wq; extern struct workqueue_struct *system_freezable_power_efficient_wq; diff --git a/kernel/async.c b/kernel/async.c index d2edd6efec56..7b3d7dc1f2cf 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -191,7 +191,7 @@ static async_cookie_t __async_schedule(async_func_t func, void *data, struct asy current->flags |= PF_USED_ASYNC; /* schedule for execution */ - queue_work(system_unbound_wq, &entry->work); + queue_work(system_unbound_freezable_wq, &entry->work); return newcookie; } diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 8e6a3a44d088..1e29ea444b24 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -343,6 +343,8 @@ struct workqueue_struct *system_unbound_wq __read_mostly; EXPORT_SYMBOL_GPL(system_unbound_wq); struct workqueue_struct *system_freezable_wq __read_mostly; EXPORT_SYMBOL_GPL(system_freezable_wq); +struct workqueue_struct *system_unbound_freezable_wq __read_mostly; +EXPORT_SYMBOL_GPL(system_unbound_freezable_wq); struct workqueue_struct *system_power_efficient_wq __read_mostly; EXPORT_SYMBOL_GPL(system_power_efficient_wq); struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly; @@ -521,15 +523,43 @@ static inline void debug_work_activate(struct work_struct *work) { } static inline void debug_work_deactivate(struct work_struct *work) { } #endif +noinline +bool __context_is_freezable(struct task_struct *task) +{ + struct worker *worker = task->flags & PF_WQ_WORKER + ? kthread_data(task) + : NULL; + + if (worker) { + if (!(worker->current_pwq->wq->flags & WQ_FREEZABLE)) { + printk(KERN_ERR "context %s not freezable\n", context_name()); + } + + BUG_ON(!(worker->current_pwq->wq->flags & WQ_FREEZABLE)); + return worker->current_pwq->wq->flags & WQ_FREEZABLE; + } else + return !(task->flags & PF_NOFREEZE); + +} + bool context_is_freezable(void) { +#if 1 + return __context_is_freezable(current); +#else struct worker *worker; worker = current_wq_worker(); - if (worker) + if (worker) { + if (!(worker->current_pwq->wq->flags & WQ_FREEZABLE)) { + printk(KERN_ERR "context %s not freezable\n", context_name()); + } + + BUG_ON(!(worker->current_pwq->wq->flags & WQ_FREEZABLE)); return worker->current_pwq->wq->flags & WQ_FREEZABLE; - else + } else return !(current->flags & PF_NOFREEZE); +#endif } const char *context_name(void) @@ -5569,6 +5599,9 @@ static int __init init_workqueues(void) WQ_UNBOUND_MAX_ACTIVE); system_freezable_wq = alloc_workqueue("events_freezable", WQ_FREEZABLE, 0); + system_unbound_freezable_wq = alloc_workqueue("events_unbound_freezable", + WQ_UNBOUND|WQ_FREEZABLE, + WQ_UNBOUND_MAX_ACTIVE); system_power_efficient_wq = alloc_workqueue("events_power_efficient", WQ_POWER_EFFICIENT, 0); system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient", @@ -5576,6 +5609,7 @@ static int __init init_workqueues(void) 0); BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq || !system_unbound_wq || !system_freezable_wq || + !system_unbound_freezable_wq || !system_power_efficient_wq || !system_freezable_power_efficient_wq); |