trace: Add an option to show tgids in trace output
The tgids are tracked along side the saved_cmdlines tracking, and can be included in trace output by enabling the 'print-tgid' trace option. This is useful when doing post-processing of the trace data, as it allows events to be grouped by tgid. Change-Id: I52ed04c3a8ca7fddbb868b792ce5d21ceb76250e Signed-off-by: Jamie Gennis <jgennis@google.com>
This commit is contained in:
parent
e2dba5ee5f
commit
6019e59489
3 changed files with 110 additions and 6 deletions
|
@ -1352,6 +1352,7 @@ void tracing_reset_all_online_cpus(void)
|
||||||
|
|
||||||
#define SAVED_CMDLINES_DEFAULT 128
|
#define SAVED_CMDLINES_DEFAULT 128
|
||||||
#define NO_CMDLINE_MAP UINT_MAX
|
#define NO_CMDLINE_MAP UINT_MAX
|
||||||
|
static unsigned saved_tgids[SAVED_CMDLINES];
|
||||||
static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
|
static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
|
||||||
struct saved_cmdlines_buffer {
|
struct saved_cmdlines_buffer {
|
||||||
unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
|
unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
|
||||||
|
@ -1590,7 +1591,7 @@ static int trace_save_cmdline(struct task_struct *tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_cmdline(idx, tsk->comm);
|
set_cmdline(idx, tsk->comm);
|
||||||
|
saved_tgids[idx] = tsk->tgid;
|
||||||
arch_spin_unlock(&trace_cmdline_lock);
|
arch_spin_unlock(&trace_cmdline_lock);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1633,6 +1634,25 @@ void trace_find_cmdline(int pid, char comm[])
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int trace_find_tgid(int pid)
|
||||||
|
{
|
||||||
|
unsigned map;
|
||||||
|
int tgid;
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
arch_spin_lock(&trace_cmdline_lock);
|
||||||
|
map = map_pid_to_cmdline[pid];
|
||||||
|
if (map != NO_CMDLINE_MAP)
|
||||||
|
tgid = saved_tgids[map];
|
||||||
|
else
|
||||||
|
tgid = -1;
|
||||||
|
|
||||||
|
arch_spin_unlock(&trace_cmdline_lock);
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
|
return tgid;
|
||||||
|
}
|
||||||
|
|
||||||
void tracing_record_cmdline(struct task_struct *tsk)
|
void tracing_record_cmdline(struct task_struct *tsk)
|
||||||
{
|
{
|
||||||
if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on())
|
if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on())
|
||||||
|
@ -2583,6 +2603,13 @@ static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m)
|
||||||
"# | | | | |\n");
|
"# | | | | |\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_func_help_header_tgid(struct trace_buffer *buf, struct seq_file *m)
|
||||||
|
{
|
||||||
|
print_event_info(buf, m);
|
||||||
|
seq_puts(m, "# TASK-PID TGID CPU# TIMESTAMP FUNCTION\n");
|
||||||
|
seq_puts(m, "# | | | | | |\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m)
|
static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m)
|
||||||
{
|
{
|
||||||
print_event_info(buf, m);
|
print_event_info(buf, m);
|
||||||
|
@ -2595,6 +2622,18 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file
|
||||||
"# | | | |||| | |\n");
|
"# | | | |||| | |\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_func_help_header_irq_tgid(struct trace_buffer *buf, struct seq_file *m)
|
||||||
|
{
|
||||||
|
print_event_info(buf, m);
|
||||||
|
seq_puts(m, "# _-----=> irqs-off\n");
|
||||||
|
seq_puts(m, "# / _----=> need-resched\n");
|
||||||
|
seq_puts(m, "# | / _---=> hardirq/softirq\n");
|
||||||
|
seq_puts(m, "# || / _--=> preempt-depth\n");
|
||||||
|
seq_puts(m, "# ||| / delay\n");
|
||||||
|
seq_puts(m, "# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION\n");
|
||||||
|
seq_puts(m, "# | | | | |||| | |\n");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_trace_header(struct seq_file *m, struct trace_iterator *iter)
|
print_trace_header(struct seq_file *m, struct trace_iterator *iter)
|
||||||
{
|
{
|
||||||
|
@ -2907,9 +2946,15 @@ void trace_default_header(struct seq_file *m)
|
||||||
} else {
|
} else {
|
||||||
if (!(trace_flags & TRACE_ITER_VERBOSE)) {
|
if (!(trace_flags & TRACE_ITER_VERBOSE)) {
|
||||||
if (trace_flags & TRACE_ITER_IRQ_INFO)
|
if (trace_flags & TRACE_ITER_IRQ_INFO)
|
||||||
print_func_help_header_irq(iter->trace_buffer, m);
|
if (trace_flags & TRACE_ITER_TGID)
|
||||||
|
print_func_help_header_irq_tgid(iter->trace_buffer, m);
|
||||||
|
else
|
||||||
|
print_func_help_header_irq(iter->trace_buffer, m);
|
||||||
else
|
else
|
||||||
print_func_help_header(iter->trace_buffer, m);
|
if (trace_flags & TRACE_ITER_TGID)
|
||||||
|
print_func_help_header_tgid(iter->trace_buffer, m);
|
||||||
|
else
|
||||||
|
print_func_help_header(iter->trace_buffer, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4160,6 +4205,50 @@ static void trace_insert_enum_map(struct module *mod,
|
||||||
trace_insert_enum_map_file(mod, start, len);
|
trace_insert_enum_map_file(mod, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tracing_saved_tgids_read(struct file *file, char __user *ubuf,
|
||||||
|
size_t cnt, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char *file_buf;
|
||||||
|
char *buf;
|
||||||
|
int len = 0;
|
||||||
|
int pid;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
file_buf = kmalloc(SAVED_CMDLINES*(16+1+16), GFP_KERNEL);
|
||||||
|
if (!file_buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
buf = file_buf;
|
||||||
|
|
||||||
|
for (i = 0; i < SAVED_CMDLINES; i++) {
|
||||||
|
int tgid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pid = map_cmdline_to_pid[i];
|
||||||
|
if (pid == -1 || pid == NO_CMDLINE_MAP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tgid = trace_find_tgid(pid);
|
||||||
|
r = sprintf(buf, "%d %d\n", pid, tgid);
|
||||||
|
buf += r;
|
||||||
|
len += r;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = simple_read_from_buffer(ubuf, cnt, ppos,
|
||||||
|
file_buf, len);
|
||||||
|
|
||||||
|
kfree(file_buf);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations tracing_saved_tgids_fops = {
|
||||||
|
.open = tracing_open_generic,
|
||||||
|
.read = tracing_saved_tgids_read,
|
||||||
|
.llseek = generic_file_llseek,
|
||||||
|
};
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
tracing_set_trace_read(struct file *filp, char __user *ubuf,
|
tracing_set_trace_read(struct file *filp, char __user *ubuf,
|
||||||
size_t cnt, loff_t *ppos)
|
size_t cnt, loff_t *ppos)
|
||||||
|
@ -6784,6 +6873,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
|
||||||
trace_create_file("trace_marker", 0220, d_tracer,
|
trace_create_file("trace_marker", 0220, d_tracer,
|
||||||
tr, &tracing_mark_fops);
|
tr, &tracing_mark_fops);
|
||||||
|
|
||||||
|
trace_create_file("saved_tgids", 0444, d_tracer,
|
||||||
|
tr, &tracing_saved_tgids_fops);
|
||||||
|
|
||||||
trace_create_file("trace_clock", 0644, d_tracer, tr,
|
trace_create_file("trace_clock", 0644, d_tracer, tr,
|
||||||
&trace_clock_fops);
|
&trace_clock_fops);
|
||||||
|
|
||||||
|
|
|
@ -656,6 +656,7 @@ static inline void __trace_stack(struct trace_array *tr, unsigned long flags,
|
||||||
extern cycle_t ftrace_now(int cpu);
|
extern cycle_t ftrace_now(int cpu);
|
||||||
|
|
||||||
extern void trace_find_cmdline(int pid, char comm[]);
|
extern void trace_find_cmdline(int pid, char comm[]);
|
||||||
|
extern int trace_find_tgid(int pid);
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||||
extern unsigned long ftrace_update_tot_cnt;
|
extern unsigned long ftrace_update_tot_cnt;
|
||||||
|
@ -970,7 +971,8 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
|
||||||
FUNCTION_FLAGS \
|
FUNCTION_FLAGS \
|
||||||
FGRAPH_FLAGS \
|
FGRAPH_FLAGS \
|
||||||
STACK_FLAGS \
|
STACK_FLAGS \
|
||||||
BRANCH_FLAGS
|
BRANCH_FLAGS \
|
||||||
|
C(TGID, "print-tgid"),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By defining C, we can make TRACE_FLAGS a list of bit names
|
* By defining C, we can make TRACE_FLAGS a list of bit names
|
||||||
|
|
|
@ -526,11 +526,21 @@ int trace_print_context(struct trace_iterator *iter)
|
||||||
unsigned long long t;
|
unsigned long long t;
|
||||||
unsigned long secs, usec_rem;
|
unsigned long secs, usec_rem;
|
||||||
char comm[TASK_COMM_LEN];
|
char comm[TASK_COMM_LEN];
|
||||||
|
int tgid;
|
||||||
|
|
||||||
trace_find_cmdline(entry->pid, comm);
|
trace_find_cmdline(entry->pid, comm);
|
||||||
|
|
||||||
trace_seq_printf(s, "%16s-%-5d [%03d] ",
|
trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
|
||||||
comm, entry->pid, iter->cpu);
|
|
||||||
|
if (tr->trace_flags & TRACE_ITER_TGID) {
|
||||||
|
tgid = trace_find_tgid(entry->pid);
|
||||||
|
if (tgid < 0)
|
||||||
|
trace_seq_puts(s, "(-----) ");
|
||||||
|
else
|
||||||
|
trace_seq_printf(s, "(%5d) ", tgid);
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_seq_printf(s, "[%03d] ", iter->cpu);
|
||||||
|
|
||||||
if (tr->trace_flags & TRACE_ITER_IRQ_INFO)
|
if (tr->trace_flags & TRACE_ITER_IRQ_INFO)
|
||||||
trace_print_lat_fmt(s, entry);
|
trace_print_lat_fmt(s, entry);
|
||||||
|
|
Loading…
Add table
Reference in a new issue