diff options
author | Tejun Heo <tj@kernel.org> | 2018-05-18 11:47:13 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2018-05-18 11:47:13 -0400 |
commit | 8bf895931ee3b635888b5a302055f97362c92d79 (patch) | |
tree | bed103e09e7329b5c16c43012b97c69900e3bd69 | |
parent | a2d812a27a4530b999a92f245d0d8291663e8c38 (diff) |
workqueue: Set worker->desc to workqueue name by default
Work functions can use set_worker_desc() to improve the visibility of
what the worker task is doing. Currently, the desc field is unset at
the beginning of each execution and there is a separate field to track
the field is set during the current execution.
Instead of leaving empty till desc is set, worker->desc can be used to
remember the last workqueue the worker worked on by default and users
that use set_worker_desc() can override it to something more
informative as necessary.
This simplifies desc handling and helps tracking the last workqueue
that the worker exected on to improve visibility.
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | kernel/workqueue.c | 21 | ||||
-rw-r--r-- | kernel/workqueue_internal.h | 1 |
2 files changed, 10 insertions, 12 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2fde50f8221b..3fbe0076492c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -2088,6 +2088,12 @@ __acquires(&pool->lock) | |||
2088 | worker->current_pwq = pwq; | 2088 | worker->current_pwq = pwq; |
2089 | work_color = get_work_color(work); | 2089 | work_color = get_work_color(work); |
2090 | 2090 | ||
2091 | /* | ||
2092 | * Record wq name for cmdline and debug reporting, may get | ||
2093 | * overridden through set_worker_desc(). | ||
2094 | */ | ||
2095 | strscpy(worker->desc, pwq->wq->name, WORKER_DESC_LEN); | ||
2096 | |||
2091 | list_del_init(&work->entry); | 2097 | list_del_init(&work->entry); |
2092 | 2098 | ||
2093 | /* | 2099 | /* |
@@ -2183,7 +2189,6 @@ __acquires(&pool->lock) | |||
2183 | worker->current_work = NULL; | 2189 | worker->current_work = NULL; |
2184 | worker->current_func = NULL; | 2190 | worker->current_func = NULL; |
2185 | worker->current_pwq = NULL; | 2191 | worker->current_pwq = NULL; |
2186 | worker->desc_valid = false; | ||
2187 | pwq_dec_nr_in_flight(pwq, work_color); | 2192 | pwq_dec_nr_in_flight(pwq, work_color); |
2188 | } | 2193 | } |
2189 | 2194 | ||
@@ -4346,7 +4351,6 @@ void set_worker_desc(const char *fmt, ...) | |||
4346 | va_start(args, fmt); | 4351 | va_start(args, fmt); |
4347 | vsnprintf(worker->desc, sizeof(worker->desc), fmt, args); | 4352 | vsnprintf(worker->desc, sizeof(worker->desc), fmt, args); |
4348 | va_end(args); | 4353 | va_end(args); |
4349 | worker->desc_valid = true; | ||
4350 | } | 4354 | } |
4351 | } | 4355 | } |
4352 | 4356 | ||
@@ -4370,7 +4374,6 @@ void print_worker_info(const char *log_lvl, struct task_struct *task) | |||
4370 | char desc[WORKER_DESC_LEN] = { }; | 4374 | char desc[WORKER_DESC_LEN] = { }; |
4371 | struct pool_workqueue *pwq = NULL; | 4375 | struct pool_workqueue *pwq = NULL; |
4372 | struct workqueue_struct *wq = NULL; | 4376 | struct workqueue_struct *wq = NULL; |
4373 | bool desc_valid = false; | ||
4374 | struct worker *worker; | 4377 | struct worker *worker; |
4375 | 4378 | ||
4376 | if (!(task->flags & PF_WQ_WORKER)) | 4379 | if (!(task->flags & PF_WQ_WORKER)) |
@@ -4383,22 +4386,18 @@ void print_worker_info(const char *log_lvl, struct task_struct *task) | |||
4383 | worker = kthread_probe_data(task); | 4386 | worker = kthread_probe_data(task); |
4384 | 4387 | ||
4385 | /* | 4388 | /* |
4386 | * Carefully copy the associated workqueue's workfn and name. Keep | 4389 | * Carefully copy the associated workqueue's workfn, name and desc. |
4387 | * the original last '\0' in case the original contains garbage. | 4390 | * Keep the original last '\0' in case the original is garbage. |
4388 | */ | 4391 | */ |
4389 | probe_kernel_read(&fn, &worker->current_func, sizeof(fn)); | 4392 | probe_kernel_read(&fn, &worker->current_func, sizeof(fn)); |
4390 | probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq)); | 4393 | probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq)); |
4391 | probe_kernel_read(&wq, &pwq->wq, sizeof(wq)); | 4394 | probe_kernel_read(&wq, &pwq->wq, sizeof(wq)); |
4392 | probe_kernel_read(name, wq->name, sizeof(name) - 1); | 4395 | probe_kernel_read(name, wq->name, sizeof(name) - 1); |
4393 | 4396 | probe_kernel_read(desc, worker->desc, sizeof(desc) - 1); | |
4394 | /* copy worker description */ | ||
4395 | probe_kernel_read(&desc_valid, &worker->desc_valid, sizeof(desc_valid)); | ||
4396 | if (desc_valid) | ||
4397 | probe_kernel_read(desc, worker->desc, sizeof(desc) - 1); | ||
4398 | 4397 | ||
4399 | if (fn || name[0] || desc[0]) { | 4398 | if (fn || name[0] || desc[0]) { |
4400 | printk("%sWorkqueue: %s %pf", log_lvl, name, fn); | 4399 | printk("%sWorkqueue: %s %pf", log_lvl, name, fn); |
4401 | if (desc[0]) | 4400 | if (strcmp(name, desc)) |
4402 | pr_cont(" (%s)", desc); | 4401 | pr_cont(" (%s)", desc); |
4403 | pr_cont("\n"); | 4402 | pr_cont("\n"); |
4404 | } | 4403 | } |
diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h index 4a182e027207..66fbb5a9e633 100644 --- a/kernel/workqueue_internal.h +++ b/kernel/workqueue_internal.h | |||
@@ -31,7 +31,6 @@ struct worker { | |||
31 | struct work_struct *current_work; /* L: work being processed */ | 31 | struct work_struct *current_work; /* L: work being processed */ |
32 | work_func_t current_func; /* L: current_work's fn */ | 32 | work_func_t current_func; /* L: current_work's fn */ |
33 | struct pool_workqueue *current_pwq; /* L: current_work's pwq */ | 33 | struct pool_workqueue *current_pwq; /* L: current_work's pwq */ |
34 | bool desc_valid; /* ->desc is valid */ | ||
35 | struct list_head scheduled; /* L: scheduled works */ | 34 | struct list_head scheduled; /* L: scheduled works */ |
36 | 35 | ||
37 | /* 64 bytes boundary on 64bit, 32 on 32bit */ | 36 | /* 64 bytes boundary on 64bit, 32 on 32bit */ |