Commit 4c27e756 authored by Steven Rostedt (Red Hat)'s avatar Steven Rostedt (Red Hat) Committed by Steven Rostedt

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: 42584c81 tracing: Have saved_cmdlines use the seq_read infrastructure
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 379cfdac
...@@ -1484,7 +1484,7 @@ static int trace_save_cmdline(struct task_struct *tsk) ...@@ -1484,7 +1484,7 @@ static int trace_save_cmdline(struct task_struct *tsk)
return 1; return 1;
} }
void trace_find_cmdline(int pid, char comm[]) static void __trace_find_cmdline(int pid, char comm[])
{ {
unsigned map; unsigned map;
...@@ -1503,13 +1503,19 @@ void trace_find_cmdline(int pid, char comm[]) ...@@ -1503,13 +1503,19 @@ void trace_find_cmdline(int pid, char comm[])
return; return;
} }
preempt_disable();
arch_spin_lock(&trace_cmdline_lock);
map = map_pid_to_cmdline[pid]; map = map_pid_to_cmdline[pid];
if (map != NO_CMDLINE_MAP) if (map != NO_CMDLINE_MAP)
strcpy(comm, saved_cmdlines[map]); strcpy(comm, saved_cmdlines[map]);
else else
strcpy(comm, "<...>"); strcpy(comm, "<...>");
}
void trace_find_cmdline(int pid, char comm[])
{
preempt_disable();
arch_spin_lock(&trace_cmdline_lock);
__trace_find_cmdline(pid, comm);
arch_spin_unlock(&trace_cmdline_lock); arch_spin_unlock(&trace_cmdline_lock);
preempt_enable(); preempt_enable();
...@@ -3724,6 +3730,9 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos) ...@@ -3724,6 +3730,9 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos)
void *v; void *v;
loff_t l = 0; loff_t l = 0;
preempt_disable();
arch_spin_lock(&trace_cmdline_lock);
v = &map_cmdline_to_pid[0]; v = &map_cmdline_to_pid[0];
while (l <= *pos) { while (l <= *pos) {
v = saved_cmdlines_next(m, v, &l); v = saved_cmdlines_next(m, v, &l);
...@@ -3736,6 +3745,8 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos) ...@@ -3736,6 +3745,8 @@ static void *saved_cmdlines_start(struct seq_file *m, loff_t *pos)
static void saved_cmdlines_stop(struct seq_file *m, void *v) static void saved_cmdlines_stop(struct seq_file *m, void *v)
{ {
arch_spin_unlock(&trace_cmdline_lock);
preempt_enable();
} }
static int saved_cmdlines_show(struct seq_file *m, void *v) static 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,7 +3754,7 @@ static int saved_cmdlines_show(struct seq_file *m, void *v)
char buf[TASK_COMM_LEN]; char buf[TASK_COMM_LEN];
unsigned int *pid = v; unsigned int *pid = v;
trace_find_cmdline(*pid, buf); __trace_find_cmdline(*pid, buf);
seq_printf(m, "%d %s\n", *pid, buf); seq_printf(m, "%d %s\n", *pid, buf);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment