workqueue: Show the latest workqueue name in /proc/PID/{comm,stat,status}
There can be a lot of workqueue workers and they all show up with the cryptic kworker/* names making it difficult to understand which is doing what and how they came to be. # ps -ef | grep kworker root 4 2 0 Feb25 ? 00:00:00 [kworker/0:0H] root 6 2 0 Feb25 ? 00:00:00 [kworker/u112:0] root 19 2 0 Feb25 ? 00:00:00 [kworker/1:0H] root 25 2 0 Feb25 ? 00:00:00 [kworker/2:0H] root 31 2 0 Feb25 ? 00:00:00 [kworker/3:0H] ... This patch makes workqueue workers report the latest workqueue it was executing for through /proc/PID/{comm,stat,status}. The extra information is appended to the kthread name with intervening '+' if currently executing, otherwise '-'. # cat /proc/25/comm kworker/2:0-events_power_efficient # cat /proc/25/stat 25 (kworker/2:0-events_power_efficient) I 2 0 0 0 -1 69238880 0 0... # grep Name /proc/25/status Name: kworker/2:0-events_power_efficient Unfortunately, ps(1) truncates comm to 15 characters, # ps 25 PID TTY STAT TIME COMMAND 25 ? I 0:00 [kworker/2:0-eve] making it a lot less useful; however, this should be an easy fix from ps(1) side. Signed-off-by: Tejun Heo <tj@kernel.org> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Craig Small <csmall@enc.com.au>
This commit is contained in:
parent
88b72b31e1
commit
6b59808bfe
@ -99,10 +99,13 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
|
|||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
char tcomm[sizeof(p->comm)];
|
char tcomm[64];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
get_task_comm(tcomm, p);
|
if (p->flags & PF_WQ_WORKER)
|
||||||
|
wq_worker_comm(tcomm, sizeof(tcomm), p);
|
||||||
|
else
|
||||||
|
__get_task_comm(tcomm, sizeof(tcomm), p);
|
||||||
|
|
||||||
size = seq_get_buf(m, &buf);
|
size = seq_get_buf(m, &buf);
|
||||||
if (escape) {
|
if (escape) {
|
||||||
|
@ -494,6 +494,7 @@ extern unsigned int work_busy(struct work_struct *work);
|
|||||||
extern __printf(1, 2) void set_worker_desc(const char *fmt, ...);
|
extern __printf(1, 2) void set_worker_desc(const char *fmt, ...);
|
||||||
extern void print_worker_info(const char *log_lvl, struct task_struct *task);
|
extern void print_worker_info(const char *log_lvl, struct task_struct *task);
|
||||||
extern void show_workqueue_state(void);
|
extern void show_workqueue_state(void);
|
||||||
|
extern void wq_worker_comm(char *buf, size_t size, struct task_struct *task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* queue_work - queue work on a workqueue
|
* queue_work - queue work on a workqueue
|
||||||
|
@ -4577,6 +4577,45 @@ void show_workqueue_state(void)
|
|||||||
rcu_read_unlock_sched();
|
rcu_read_unlock_sched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* used to show worker information through /proc/PID/{comm,stat,status} */
|
||||||
|
void wq_worker_comm(char *buf, size_t size, struct task_struct *task)
|
||||||
|
{
|
||||||
|
struct worker *worker;
|
||||||
|
struct worker_pool *pool;
|
||||||
|
int off;
|
||||||
|
|
||||||
|
/* always show the actual comm */
|
||||||
|
off = strscpy(buf, task->comm, size);
|
||||||
|
if (off < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* stabilize worker pool association */
|
||||||
|
mutex_lock(&wq_pool_attach_mutex);
|
||||||
|
|
||||||
|
worker = kthread_data(task);
|
||||||
|
pool = worker->pool;
|
||||||
|
|
||||||
|
if (pool) {
|
||||||
|
spin_lock_irq(&pool->lock);
|
||||||
|
/*
|
||||||
|
* ->desc tracks information (wq name or set_worker_desc())
|
||||||
|
* for the latest execution. If current, prepend '+',
|
||||||
|
* otherwise '-'.
|
||||||
|
*/
|
||||||
|
if (worker->desc[0] != '\0') {
|
||||||
|
if (worker->current_work)
|
||||||
|
scnprintf(buf + off, size - off, "+%s",
|
||||||
|
worker->desc);
|
||||||
|
else
|
||||||
|
scnprintf(buf + off, size - off, "-%s",
|
||||||
|
worker->desc);
|
||||||
|
}
|
||||||
|
spin_unlock_irq(&pool->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&wq_pool_attach_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU hotplug.
|
* CPU hotplug.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user