tracing: Don't use tracing_record_cmdline() in workqueue tracer
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Mon, 9 Mar 2009 09:15:34 +0000 (18:15 +0900)
committerIngo Molnar <mingo@elte.hu>
Mon, 9 Mar 2009 09:26:13 +0000 (10:26 +0100)
Impact: improve workqueue tracer output

Currently, /sys/kernel/debug/tracing/trace_stat/workqueues can display
wrong and strange thread names.

Why?

Currently, ftrace has tracing_record_cmdline()/trace_find_cmdline()
convenience function that implements a task->comm string cache.

This can avoid unnecessary memcpy overhead and the workqueue tracer
uses it.

However, in general, any trace statistics feature shouldn't use
tracing_record_cmdline() because trace statistics can display
very old process. Then comm cache can return wrong string because
recent process overrides the cache.

Fortunately, workqueue trace guarantees that displayed processes
are live. Thus we can search comm string from PID at display time.

<before>

% cat workqueues
 # CPU  INSERTED  EXECUTED   NAME
 # |      |         |          |

   7 431913     431913       kondemand/7
   7      0          0       tail
   7     21         21       git
   7      0          0       ls
   7      9          9       cat
   7 832632     832632       unix_chkpwd
   7 236292     236292       ls

Note: tail, git, ls, cat unix_chkpwd are obiously not workqueue thread.

<after>

% cat workqueues
 # CPU  INSERTED  EXECUTED   NAME
 # |      |         |          |

   7    510        510       kondemand/7
   7      0          0       kmpathd/7
   7     15         15       ata/7
   7      0          0       aio/7
   7     11         11       kblockd/7
   7   1063       1063       work_on_cpu/7
   7    167        167       events/7

Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Steven Rostedt <srostedt@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
kernel/trace/trace_workqueue.c

index 4664990..46c8dc8 100644 (file)
@@ -99,8 +99,6 @@ static void probe_workqueue_creation(struct task_struct *wq_thread, int cpu)
                pr_warning("trace_workqueue: not enough memory\n");
                return;
        }
-       tracing_record_cmdline(wq_thread);
-
        INIT_LIST_HEAD(&cws->list);
        cws->cpu = cpu;
 
@@ -195,11 +193,12 @@ static int workqueue_stat_show(struct seq_file *s, void *p)
        struct cpu_workqueue_stats *cws = p;
        unsigned long flags;
        int cpu = cws->cpu;
+       struct task_struct *tsk = find_task_by_vpid(cws->pid);
 
        seq_printf(s, "%3d %6d     %6u       %s\n", cws->cpu,
                   atomic_read(&cws->inserted),
                   cws->executed,
-                  trace_find_cmdline(cws->pid));
+                  tsk ? tsk->comm : "<...>");
 
        spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
        if (&cws->list == workqueue_cpu_stat(cpu)->list.next)