diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 076fa6f..d583ba5 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "trace.h" #include "trace_output.h" @@ -649,24 +650,15 @@ void tracing_reset_current_online_cpus(void) tracing_reset_online_cpus(&global_trace); } -#define SAVED_CMDLINES 128 -#define NO_CMDLINE_MAP UINT_MAX -static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; +#define SAVED_CMDLINE_SHIFT 8 +#define SAVED_CMDLINES (1 << SAVED_CMDLINE_SHIFT) static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; -static int cmdline_idx; static raw_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; -static void trace_init_cmdlines(void) -{ - memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); - cmdline_idx = 0; -} - static int trace_stop_count; static DEFINE_SPINLOCK(tracing_start_lock); @@ -755,11 +747,13 @@ void trace_stop_cmdline_recording(void); static void trace_save_cmdline(struct task_struct *tsk) { - unsigned pid, idx; + unsigned idx; - if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT)) + if (!tsk->pid) return; + idx = hash_32((u32)tsk->pid, SAVED_CMDLINE_SHIFT); + /* * It's not the end of the world if we don't get * the lock, but we also don't want to spin @@ -769,27 +763,8 @@ static void trace_save_cmdline(struct task_struct *tsk) if (!__raw_spin_trylock(&trace_cmdline_lock)) return; - idx = map_pid_to_cmdline[tsk->pid]; - if (idx == NO_CMDLINE_MAP) { - idx = (cmdline_idx + 1) % SAVED_CMDLINES; - - /* - * Check whether the cmdline buffer at idx has a pid - * mapped. We are going to overwrite that entry so we - * need to clear the map_pid_to_cmdline. Otherwise we - * would read the new comm for the old pid. - */ - pid = map_cmdline_to_pid[idx]; - if (pid != NO_CMDLINE_MAP) - map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; - - map_cmdline_to_pid[idx] = tsk->pid; - map_pid_to_cmdline[tsk->pid] = idx; - - cmdline_idx = idx; - } - - memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); + map_cmdline_to_pid[idx] = tsk->pid; + memcpy(saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); __raw_spin_unlock(&trace_cmdline_lock); } @@ -803,15 +778,17 @@ void trace_find_cmdline(int pid, char comm[]) return; } - if (pid > PID_MAX_DEFAULT) { + map = hash_32((u32)pid, SAVED_CMDLINE_SHIFT); + + if (map_cmdline_to_pid[map] != pid) { strcpy(comm, "<...>"); return; } preempt_disable(); __raw_spin_lock(&trace_cmdline_lock); - map = map_pid_to_cmdline[pid]; - if (map != NO_CMDLINE_MAP) + + if (map_cmdline_to_pid[map] == pid) strcpy(comm, saved_cmdlines[map]); else strcpy(comm, "<...>"); @@ -2470,7 +2447,7 @@ tracing_saved_cmdlines_read(struct file *file, char __user *ubuf, int r; pid = map_cmdline_to_pid[i]; - if (pid == -1 || pid == NO_CMDLINE_MAP) + if (!pid) continue; trace_find_cmdline(pid, buf_comm); @@ -4332,8 +4309,6 @@ __init static int tracer_alloc_buffers(void) max_tr.data[i] = &per_cpu(max_data, i); } - trace_init_cmdlines(); - register_tracer(&nop_trace); current_trace = &nop_trace; #ifdef CONFIG_BOOT_TRACER