Tracing fixes:
- Check kprobe is enabled before unregistering from ftrace as it isn't registered when disabled. - Remove kprobes enabled via command-line that is on init text when freed. - Add missing RCU synchronization for ftrace trampoline symbols removed from kallsyms. - Free trampoline on error path if ftrace_startup() fails. - Give more space for the longer PID numbers in trace output. - Fix a possible double free in the histogram code. - A couple of fixes that were discovered by sparse. -----BEGIN PGP SIGNATURE----- iIkEABYIADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCX2lEchQccm9zdGVkdEBn b29kbWlzLm9yZwAKCRAp5XQQmuv6qokAAQDphHFTOlgjKi7lF7bc5V1bl/MT1bVo bJRHV8w2agtXMgD49ElFOl6znXqid3X++0dYZ5/AQgOZXf1rsYS05Pj0Dw== =+cVX -----END PGP SIGNATURE----- Merge tag 'trace-v5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace Pull tracing fixes from Steven Rostedt: - Check kprobe is enabled before unregistering from ftrace as it isn't registered when disabled. - Remove kprobes enabled via command-line that is on init text when freed. - Add missing RCU synchronization for ftrace trampoline symbols removed from kallsyms. - Free trampoline on error path if ftrace_startup() fails. - Give more space for the longer PID numbers in trace output. - Fix a possible double free in the histogram code. - A couple of fixes that were discovered by sparse. * tag 'trace-v5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: bootconfig: init: make xbc_namebuf static kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot tracing: fix double free ftrace: Let ftrace_enable_sysctl take a kernel pointer buffer tracing: Make the space reserved for the pid wider ftrace: Fix missing synchronize_rcu() removing trampoline from kallsyms ftrace: Free the trampoline when ftrace_startup() fails kprobes: Fix to check probe enabled before disarm_kprobe_ftrace()
This commit is contained in:
commit
eff48ddeab
|
@ -373,6 +373,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
|
|||
void kprobe_flush_task(struct task_struct *tk);
|
||||
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
|
||||
|
||||
void kprobe_free_init_mem(void);
|
||||
|
||||
int disable_kprobe(struct kprobe *kp);
|
||||
int enable_kprobe(struct kprobe *kp);
|
||||
|
||||
|
@ -435,6 +437,9 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num)
|
|||
static inline void kprobe_flush_task(struct task_struct *tk)
|
||||
{
|
||||
}
|
||||
static inline void kprobe_free_init_mem(void)
|
||||
{
|
||||
}
|
||||
static inline int disable_kprobe(struct kprobe *kp)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/nmi.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/start_kernel.h>
|
||||
|
@ -303,7 +304,7 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
|
|||
|
||||
#ifdef CONFIG_BOOT_CONFIG
|
||||
|
||||
char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
|
||||
static char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
|
||||
|
||||
#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
|
||||
|
||||
|
@ -1402,6 +1403,7 @@ static int __ref kernel_init(void *unused)
|
|||
kernel_init_freeable();
|
||||
/* need to finish all async __init code before freeing the memory */
|
||||
async_synchronize_full();
|
||||
kprobe_free_init_mem();
|
||||
ftrace_free_init_mem();
|
||||
free_initmem();
|
||||
mark_readonly();
|
||||
|
|
|
@ -2162,9 +2162,10 @@ static void kill_kprobe(struct kprobe *p)
|
|||
|
||||
/*
|
||||
* The module is going away. We should disarm the kprobe which
|
||||
* is using ftrace.
|
||||
* is using ftrace, because ftrace framework is still available at
|
||||
* MODULE_STATE_GOING notification.
|
||||
*/
|
||||
if (kprobe_ftrace(p))
|
||||
if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
|
||||
disarm_kprobe_ftrace(p);
|
||||
}
|
||||
|
||||
|
@ -2459,6 +2460,28 @@ static struct notifier_block kprobe_module_nb = {
|
|||
extern unsigned long __start_kprobe_blacklist[];
|
||||
extern unsigned long __stop_kprobe_blacklist[];
|
||||
|
||||
void kprobe_free_init_mem(void)
|
||||
{
|
||||
void *start = (void *)(&__init_begin);
|
||||
void *end = (void *)(&__init_end);
|
||||
struct hlist_head *head;
|
||||
struct kprobe *p;
|
||||
int i;
|
||||
|
||||
mutex_lock(&kprobe_mutex);
|
||||
|
||||
/* Kill all kprobes on initmem */
|
||||
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
|
||||
head = &kprobe_table[i];
|
||||
hlist_for_each_entry(p, head, hlist) {
|
||||
if (start <= (void *)p->addr && (void *)p->addr < end)
|
||||
kill_kprobe(p);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&kprobe_mutex);
|
||||
}
|
||||
|
||||
static int __init init_kprobes(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
|
|
@ -2782,6 +2782,7 @@ static void ftrace_remove_trampoline_from_kallsyms(struct ftrace_ops *ops)
|
|||
{
|
||||
lockdep_assert_held(&ftrace_lock);
|
||||
list_del_rcu(&ops->list);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2862,6 +2863,8 @@ int ftrace_startup(struct ftrace_ops *ops, int command)
|
|||
__unregister_ftrace_function(ops);
|
||||
ftrace_start_up--;
|
||||
ops->flags &= ~FTRACE_OPS_FL_ENABLED;
|
||||
if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
|
||||
ftrace_trampoline_free(ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -3782,14 +3782,14 @@ unsigned long trace_total_entries(struct trace_array *tr)
|
|||
|
||||
static void print_lat_help_header(struct seq_file *m)
|
||||
{
|
||||
seq_puts(m, "# _------=> CPU# \n"
|
||||
"# / _-----=> irqs-off \n"
|
||||
"# | / _----=> need-resched \n"
|
||||
"# || / _---=> hardirq/softirq \n"
|
||||
"# ||| / _--=> preempt-depth \n"
|
||||
"# |||| / delay \n"
|
||||
"# cmd pid ||||| time | caller \n"
|
||||
"# \\ / ||||| \\ | / \n");
|
||||
seq_puts(m, "# _------=> CPU# \n"
|
||||
"# / _-----=> irqs-off \n"
|
||||
"# | / _----=> need-resched \n"
|
||||
"# || / _---=> hardirq/softirq \n"
|
||||
"# ||| / _--=> preempt-depth \n"
|
||||
"# |||| / delay \n"
|
||||
"# cmd pid ||||| time | caller \n"
|
||||
"# \\ / ||||| \\ | / \n");
|
||||
}
|
||||
|
||||
static void print_event_info(struct array_buffer *buf, struct seq_file *m)
|
||||
|
@ -3810,26 +3810,26 @@ static void print_func_help_header(struct array_buffer *buf, struct seq_file *m,
|
|||
|
||||
print_event_info(buf, m);
|
||||
|
||||
seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? "TGID " : "");
|
||||
seq_printf(m, "# | | %s | | |\n", tgid ? " | " : "");
|
||||
seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? " TGID " : "");
|
||||
seq_printf(m, "# | | %s | | |\n", tgid ? " | " : "");
|
||||
}
|
||||
|
||||
static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file *m,
|
||||
unsigned int flags)
|
||||
{
|
||||
bool tgid = flags & TRACE_ITER_RECORD_TGID;
|
||||
const char *space = " ";
|
||||
int prec = tgid ? 10 : 2;
|
||||
const char *space = " ";
|
||||
int prec = tgid ? 12 : 2;
|
||||
|
||||
print_event_info(buf, m);
|
||||
|
||||
seq_printf(m, "# %.*s _-----=> irqs-off\n", prec, space);
|
||||
seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space);
|
||||
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space);
|
||||
seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space);
|
||||
seq_printf(m, "# %.*s||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*sCPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
|
||||
seq_printf(m, "# %.*s _-----=> irqs-off\n", prec, space);
|
||||
seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space);
|
||||
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space);
|
||||
seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space);
|
||||
seq_printf(m, "# %.*s||| / delay\n", prec, space);
|
||||
seq_printf(m, "# TASK-PID %.*s CPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
|
||||
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -3865,7 +3865,6 @@ static int parse_var_defs(struct hist_trigger_data *hist_data)
|
|||
|
||||
s = kstrdup(field_str, GFP_KERNEL);
|
||||
if (!s) {
|
||||
kfree(hist_data->attrs->var_defs.name[n_vars]);
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
|
|
|
@ -497,7 +497,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
|
|||
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(s, "%8.8s-%-5d %3d",
|
||||
trace_seq_printf(s, "%8.8s-%-7d %3d",
|
||||
comm, entry->pid, cpu);
|
||||
|
||||
return trace_print_lat_fmt(s, entry);
|
||||
|
@ -588,15 +588,15 @@ int trace_print_context(struct trace_iterator *iter)
|
|||
|
||||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
|
||||
trace_seq_printf(s, "%16s-%-7d ", comm, entry->pid);
|
||||
|
||||
if (tr->trace_flags & TRACE_ITER_RECORD_TGID) {
|
||||
unsigned int tgid = trace_find_tgid(entry->pid);
|
||||
|
||||
if (!tgid)
|
||||
trace_seq_printf(s, "(-----) ");
|
||||
trace_seq_printf(s, "(-------) ");
|
||||
else
|
||||
trace_seq_printf(s, "(%5d) ", tgid);
|
||||
trace_seq_printf(s, "(%7d) ", tgid);
|
||||
}
|
||||
|
||||
trace_seq_printf(s, "[%03d] ", iter->cpu);
|
||||
|
@ -636,7 +636,7 @@ int trace_print_lat_context(struct trace_iterator *iter)
|
|||
trace_find_cmdline(entry->pid, comm);
|
||||
|
||||
trace_seq_printf(
|
||||
s, "%16s %5d %3d %d %08x %08lx ",
|
||||
s, "%16s %7d %3d %d %08x %08lx ",
|
||||
comm, entry->pid, iter->cpu, entry->flags,
|
||||
entry->preempt_count, iter->idx);
|
||||
} else {
|
||||
|
@ -917,7 +917,7 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
|
|||
S = task_index_to_char(field->prev_state);
|
||||
trace_find_cmdline(field->next_pid, comm);
|
||||
trace_seq_printf(&iter->seq,
|
||||
" %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
|
||||
" %7d:%3d:%c %s [%03d] %7d:%3d:%c %s\n",
|
||||
field->prev_pid,
|
||||
field->prev_prio,
|
||||
S, delim,
|
||||
|
|
Loading…
Reference in New Issue