aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-05-30 10:49:46 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-05-30 13:03:40 -0400
commit4c27e756bc019ec1c11232893af036fdae720a97 (patch)
tree799c598208d828e343422d73cb70b74e22f64608 /kernel/trace
parent379cfdac37923653c9d4242d10052378b7563005 (diff)
tracing: Move locking of trace_cmdline_lock into start/stop seq calls
With the conversion of the saved_cmdlines output to use seq_read, there is now a race between accessing the values of the saved_cmdlines and the writing to them. The trace_cmdline_lock needs to be taken at the start and stop of the seq calls. A new __trace_find_cmdline() call is created to allow for the look up to happen without taking the lock. Fixes: 42584c81c5ad tracing: Have saved_cmdlines use the seq_read infrastructure Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 22a902e2ded9..626dbfde5d56 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1484,7 +1484,7 @@ static int trace_save_cmdline(struct task_struct *tsk)
1484 return 1; 1484 return 1;
1485} 1485}
1486 1486
1487void trace_find_cmdline(int pid, char comm[]) 1487static void __trace_find_cmdline(int pid, char comm[])
1488{ 1488{
1489 unsigned map; 1489 unsigned map;
1490 1490
@@ -1503,13 +1503,19 @@ void trace_find_cmdline(int pid, char comm[])
1503 return; 1503 return;
1504 } 1504 }
1505 1505
1506 preempt_disable();
1507 arch_spin_lock(&trace_cmdline_lock);
1508 map = map_pid_to_cmdline[pid]; 1506 map = map_pid_to_cmdline[pid];
1509 if (map != NO_CMDLINE_MAP) 1507 if (map != NO_CMDLINE_MAP)
1510 strcpy(comm, saved_cmdlines[map]); 1508 strcpy(comm, saved_cmdlines[map]);
1511 else 1509 else
1512 strcpy(comm, "<...>"); 1510 strcpy(comm, "<...>");
1511}
1512
1513void trace_find_cmdline(int pid, char comm[])
1514{
1515 preempt_disable();
1516 arch_spin_lock(&trace_cmdline_lock);
1517
1518 __trace_find_cmdline(pid, comm);
1513 1519
1514 arch_spin_unlock(&trace_cmdline_lock); 1520 arch_spin_unlock(&trace_cmdline_lock);
1515 preempt_enable(); 1521 preempt_enable();
@@ -3724,6 +3730,9 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos)
3724 void *v; 3730 void *v;
3725 loff_t l = 0; 3731 loff_t l = 0;
3726 3732
3733 preempt_disable();
3734 arch_spin_lock(&trace_cmdline_lock);
3735
3727 v = &map_cmdline_to_pid[0]; 3736 v = &map_cmdline_to_pid[0];
3728 while (l <= *pos) { 3737 while (l <= *pos) {
3729 v = saved_cmdlines_next(m, v, &l); 3738 v = saved_cmdlines_next(m, v, &l);
@@ -3736,6 +3745,8 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos)
3736 3745
3737static void saved_cmdlines_stop(struct seq_file *m, void *v) 3746static void saved_cmdlines_stop(struct seq_file *m, void *v)
3738{ 3747{
3748 arch_spin_unlock(&trace_cmdline_lock);
3749 preempt_enable();
3739} 3750}
3740 3751
3741static int saved_cmdlines_show(struct seq_file *m, void *v) 3752static int saved_cmdlines_show(struct seq_file *m, void *v)
@@ -3743,7 +3754,7 @@ static int saved_cmdlines_show(struct seq_file *m, void *v)
3743 char buf[TASK_COMM_LEN]; 3754 char buf[TASK_COMM_LEN];
3744 unsigned int *pid = v; 3755 unsigned int *pid = v;
3745 3756
3746 trace_find_cmdline(*pid, buf); 3757 __trace_find_cmdline(*pid, buf);
3747 seq_printf(m, "%d %s\n", *pid, buf); 3758 seq_printf(m, "%d %s\n", *pid, buf);
3748 return 0; 3759 return 0;
3749} 3760}