diff options
| -rw-r--r-- | kernel/trace/trace.c | 104 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_output.c | 18 | 
3 files changed, 117 insertions, 7 deletions
| diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e71a8be4a6e..28f007ac993 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -636,6 +636,7 @@ static const char *trace_options[] = {  	"irq-info",  	"markers",  	"function-trace", +	"print-tgid",  	NULL  }; @@ -1151,6 +1152,7 @@ void tracing_reset_all_online_cpus(void)  static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];  static unsigned map_cmdline_to_pid[SAVED_CMDLINES];  static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; +static unsigned saved_tgids[SAVED_CMDLINES];  static int cmdline_idx;  static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; @@ -1354,6 +1356,7 @@ static void trace_save_cmdline(struct task_struct *tsk)  	}  	memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); +	saved_tgids[idx] = tsk->tgid;  	arch_spin_unlock(&trace_cmdline_lock);  } @@ -1389,6 +1392,25 @@ void trace_find_cmdline(int pid, char comm[])  	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)  {  	if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) @@ -2345,6 +2367,13 @@ static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m)  	seq_puts(m, "#              | |       |          |         |\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)  {  	print_event_info(buf, m); @@ -2357,6 +2386,18 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file  	seq_puts(m, "#              | |       |   ||||       |         |\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  print_trace_header(struct seq_file *m, struct trace_iterator *iter)  { @@ -2657,9 +2698,15 @@ void trace_default_header(struct seq_file *m)  	} else {  		if (!(trace_flags & TRACE_ITER_VERBOSE)) {  			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 -				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);  		}  	}  } @@ -3449,9 +3496,53 @@ tracing_saved_cmdlines_read(struct file *file, char __user *ubuf,  }  static const struct file_operations tracing_saved_cmdlines_fops = { -    .open       = tracing_open_generic, -    .read       = tracing_saved_cmdlines_read, -    .llseek	= generic_file_llseek, +	.open	= tracing_open_generic, +	.read	= tracing_saved_cmdlines_read, +	.llseek	= generic_file_llseek, +}; + +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 @@ -5939,6 +6030,9 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)  	trace_create_file("trace_marker", 0220, d_tracer,  			  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_clock_fops); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 20572ed88c5..6c42f187592 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -648,6 +648,7 @@ static inline void __trace_stack(struct trace_array *tr, unsigned long flags,  extern cycle_t ftrace_now(int cpu);  extern void trace_find_cmdline(int pid, char comm[]); +extern int trace_find_tgid(int pid);  #ifdef CONFIG_DYNAMIC_FTRACE  extern unsigned long ftrace_update_tot_cnt; @@ -861,6 +862,7 @@ enum trace_iterator_flags {  	TRACE_ITER_IRQ_INFO		= 0x800000,  	TRACE_ITER_MARKERS		= 0x1000000,  	TRACE_ITER_FUNCTION		= 0x2000000, +	TRACE_ITER_TGID 		= 0x4000000,  };  /* diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index bb922d9ee51..31994d2845e 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -702,11 +702,25 @@ int trace_print_context(struct trace_iterator *iter)  	unsigned long secs, usec_rem;  	char comm[TASK_COMM_LEN];  	int ret; +	int tgid;  	trace_find_cmdline(entry->pid, comm); -	ret = trace_seq_printf(s, "%16s-%-5d [%03d] ", -			       comm, entry->pid, iter->cpu); +	ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); +	if (!ret) +		return 0; + +	if (trace_flags & TRACE_ITER_TGID) { +		tgid = trace_find_tgid(entry->pid); +		if (tgid < 0) +			ret = trace_seq_puts(s, "(-----) "); +		else +			ret = trace_seq_printf(s, "(%5d) ", tgid); +		if (!ret) +			return 0; +	} + +	ret = trace_seq_printf(s, "[%03d] ", iter->cpu);  	if (!ret)  		return 0; |