diff options
| -rw-r--r-- | kernel/workqueue.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b4a39a15c931..60d6fd2636f3 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -2213,6 +2213,16 @@ static void process_scheduled_works(struct worker *worker) | |||
| 2213 | } | 2213 | } |
| 2214 | } | 2214 | } |
| 2215 | 2215 | ||
| 2216 | static void set_pf_worker(bool val) | ||
| 2217 | { | ||
| 2218 | mutex_lock(&wq_pool_attach_mutex); | ||
| 2219 | if (val) | ||
| 2220 | current->flags |= PF_WQ_WORKER; | ||
| 2221 | else | ||
| 2222 | current->flags &= ~PF_WQ_WORKER; | ||
| 2223 | mutex_unlock(&wq_pool_attach_mutex); | ||
| 2224 | } | ||
| 2225 | |||
| 2216 | /** | 2226 | /** |
| 2217 | * worker_thread - the worker thread function | 2227 | * worker_thread - the worker thread function |
| 2218 | * @__worker: self | 2228 | * @__worker: self |
| @@ -2231,7 +2241,7 @@ static int worker_thread(void *__worker) | |||
| 2231 | struct worker_pool *pool = worker->pool; | 2241 | struct worker_pool *pool = worker->pool; |
| 2232 | 2242 | ||
| 2233 | /* tell the scheduler that this is a workqueue worker */ | 2243 | /* tell the scheduler that this is a workqueue worker */ |
| 2234 | worker->task->flags |= PF_WQ_WORKER; | 2244 | set_pf_worker(true); |
| 2235 | woke_up: | 2245 | woke_up: |
| 2236 | spin_lock_irq(&pool->lock); | 2246 | spin_lock_irq(&pool->lock); |
| 2237 | 2247 | ||
| @@ -2239,7 +2249,7 @@ woke_up: | |||
| 2239 | if (unlikely(worker->flags & WORKER_DIE)) { | 2249 | if (unlikely(worker->flags & WORKER_DIE)) { |
| 2240 | spin_unlock_irq(&pool->lock); | 2250 | spin_unlock_irq(&pool->lock); |
| 2241 | WARN_ON_ONCE(!list_empty(&worker->entry)); | 2251 | WARN_ON_ONCE(!list_empty(&worker->entry)); |
| 2242 | worker->task->flags &= ~PF_WQ_WORKER; | 2252 | set_pf_worker(false); |
| 2243 | 2253 | ||
| 2244 | set_task_comm(worker->task, "kworker/dying"); | 2254 | set_task_comm(worker->task, "kworker/dying"); |
| 2245 | ida_simple_remove(&pool->worker_ida, worker->id); | 2255 | ida_simple_remove(&pool->worker_ida, worker->id); |
| @@ -2342,7 +2352,7 @@ static int rescuer_thread(void *__rescuer) | |||
| 2342 | * Mark rescuer as worker too. As WORKER_PREP is never cleared, it | 2352 | * Mark rescuer as worker too. As WORKER_PREP is never cleared, it |
| 2343 | * doesn't participate in concurrency management. | 2353 | * doesn't participate in concurrency management. |
| 2344 | */ | 2354 | */ |
| 2345 | rescuer->task->flags |= PF_WQ_WORKER; | 2355 | set_pf_worker(true); |
| 2346 | repeat: | 2356 | repeat: |
| 2347 | set_current_state(TASK_IDLE); | 2357 | set_current_state(TASK_IDLE); |
| 2348 | 2358 | ||
| @@ -2434,7 +2444,7 @@ repeat: | |||
| 2434 | 2444 | ||
| 2435 | if (should_stop) { | 2445 | if (should_stop) { |
| 2436 | __set_current_state(TASK_RUNNING); | 2446 | __set_current_state(TASK_RUNNING); |
| 2437 | rescuer->task->flags &= ~PF_WQ_WORKER; | 2447 | set_pf_worker(false); |
| 2438 | return 0; | 2448 | return 0; |
| 2439 | } | 2449 | } |
| 2440 | 2450 | ||
| @@ -4580,8 +4590,6 @@ void show_workqueue_state(void) | |||
| 4580 | /* used to show worker information through /proc/PID/{comm,stat,status} */ | 4590 | /* used to show worker information through /proc/PID/{comm,stat,status} */ |
| 4581 | void wq_worker_comm(char *buf, size_t size, struct task_struct *task) | 4591 | void wq_worker_comm(char *buf, size_t size, struct task_struct *task) |
| 4582 | { | 4592 | { |
| 4583 | struct worker *worker; | ||
| 4584 | struct worker_pool *pool; | ||
| 4585 | int off; | 4593 | int off; |
| 4586 | 4594 | ||
| 4587 | /* always show the actual comm */ | 4595 | /* always show the actual comm */ |
| @@ -4589,28 +4597,30 @@ void wq_worker_comm(char *buf, size_t size, struct task_struct *task) | |||
| 4589 | if (off < 0) | 4597 | if (off < 0) |
| 4590 | return; | 4598 | return; |
| 4591 | 4599 | ||
| 4592 | /* stabilize worker pool association */ | 4600 | /* stabilize PF_WQ_WORKER and worker pool association */ |
| 4593 | mutex_lock(&wq_pool_attach_mutex); | 4601 | mutex_lock(&wq_pool_attach_mutex); |
| 4594 | 4602 | ||
| 4595 | worker = kthread_data(task); | 4603 | if (task->flags & PF_WQ_WORKER) { |
| 4596 | pool = worker->pool; | 4604 | struct worker *worker = kthread_data(task); |
| 4605 | struct worker_pool *pool = worker->pool; | ||
| 4597 | 4606 | ||
| 4598 | if (pool) { | 4607 | if (pool) { |
| 4599 | spin_lock_irq(&pool->lock); | 4608 | spin_lock_irq(&pool->lock); |
| 4600 | /* | 4609 | /* |
| 4601 | * ->desc tracks information (wq name or set_worker_desc()) | 4610 | * ->desc tracks information (wq name or |
| 4602 | * for the latest execution. If current, prepend '+', | 4611 | * set_worker_desc()) for the latest execution. If |
| 4603 | * otherwise '-'. | 4612 | * current, prepend '+', otherwise '-'. |
| 4604 | */ | 4613 | */ |
| 4605 | if (worker->desc[0] != '\0') { | 4614 | if (worker->desc[0] != '\0') { |
| 4606 | if (worker->current_work) | 4615 | if (worker->current_work) |
| 4607 | scnprintf(buf + off, size - off, "+%s", | 4616 | scnprintf(buf + off, size - off, "+%s", |
| 4608 | worker->desc); | 4617 | worker->desc); |
| 4609 | else | 4618 | else |
| 4610 | scnprintf(buf + off, size - off, "-%s", | 4619 | scnprintf(buf + off, size - off, "-%s", |
| 4611 | worker->desc); | 4620 | worker->desc); |
| 4621 | } | ||
| 4622 | spin_unlock_irq(&pool->lock); | ||
| 4612 | } | 4623 | } |
| 4613 | spin_unlock_irq(&pool->lock); | ||
| 4614 | } | 4624 | } |
| 4615 | 4625 | ||
| 4616 | mutex_unlock(&wq_pool_attach_mutex); | 4626 | mutex_unlock(&wq_pool_attach_mutex); |
