Commit eff48dde authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 98477740 a27026e9
...@@ -373,6 +373,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num); ...@@ -373,6 +373,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
void kprobe_flush_task(struct task_struct *tk); void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); 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 disable_kprobe(struct kprobe *kp);
int enable_kprobe(struct kprobe *kp); int enable_kprobe(struct kprobe *kp);
...@@ -435,6 +437,9 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num) ...@@ -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_flush_task(struct task_struct *tk)
{ {
} }
static inline void kprobe_free_init_mem(void)
{
}
static inline int disable_kprobe(struct kprobe *kp) static inline int disable_kprobe(struct kprobe *kp)
{ {
return -ENOSYS; return -ENOSYS;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/nmi.h> #include <linux/nmi.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/kprobes.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/start_kernel.h> #include <linux/start_kernel.h>
...@@ -303,7 +304,7 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) ...@@ -303,7 +304,7 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
#ifdef CONFIG_BOOT_CONFIG #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) #define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
...@@ -1402,6 +1403,7 @@ static int __ref kernel_init(void *unused) ...@@ -1402,6 +1403,7 @@ static int __ref kernel_init(void *unused)
kernel_init_freeable(); kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */ /* need to finish all async __init code before freeing the memory */
async_synchronize_full(); async_synchronize_full();
kprobe_free_init_mem();
ftrace_free_init_mem(); ftrace_free_init_mem();
free_initmem(); free_initmem();
mark_readonly(); mark_readonly();
......
...@@ -2162,9 +2162,10 @@ static void kill_kprobe(struct kprobe *p) ...@@ -2162,9 +2162,10 @@ static void kill_kprobe(struct kprobe *p)
/* /*
* The module is going away. We should disarm the kprobe which * 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); disarm_kprobe_ftrace(p);
} }
...@@ -2459,6 +2460,28 @@ static struct notifier_block kprobe_module_nb = { ...@@ -2459,6 +2460,28 @@ static struct notifier_block kprobe_module_nb = {
extern unsigned long __start_kprobe_blacklist[]; extern unsigned long __start_kprobe_blacklist[];
extern unsigned long __stop_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) static int __init init_kprobes(void)
{ {
int i, err = 0; int i, err = 0;
......
...@@ -2782,6 +2782,7 @@ static void ftrace_remove_trampoline_from_kallsyms(struct ftrace_ops *ops) ...@@ -2782,6 +2782,7 @@ static void ftrace_remove_trampoline_from_kallsyms(struct ftrace_ops *ops)
{ {
lockdep_assert_held(&ftrace_lock); lockdep_assert_held(&ftrace_lock);
list_del_rcu(&ops->list); list_del_rcu(&ops->list);
synchronize_rcu();
} }
/* /*
...@@ -2862,6 +2863,8 @@ int ftrace_startup(struct ftrace_ops *ops, int command) ...@@ -2862,6 +2863,8 @@ int ftrace_startup(struct ftrace_ops *ops, int command)
__unregister_ftrace_function(ops); __unregister_ftrace_function(ops);
ftrace_start_up--; ftrace_start_up--;
ops->flags &= ~FTRACE_OPS_FL_ENABLED; ops->flags &= ~FTRACE_OPS_FL_ENABLED;
if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
ftrace_trampoline_free(ops);
return ret; return ret;
} }
......
...@@ -3810,7 +3810,7 @@ static void print_func_help_header(struct array_buffer *buf, struct seq_file *m, ...@@ -3810,7 +3810,7 @@ static void print_func_help_header(struct array_buffer *buf, struct seq_file *m,
print_event_info(buf, m); print_event_info(buf, m);
seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? "TGID " : ""); seq_printf(m, "# TASK-PID %s CPU# TIMESTAMP FUNCTION\n", tgid ? " TGID " : "");
seq_printf(m, "# | | %s | | |\n", tgid ? " | " : ""); seq_printf(m, "# | | %s | | |\n", tgid ? " | " : "");
} }
...@@ -3819,7 +3819,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file ...@@ -3819,7 +3819,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file
{ {
bool tgid = flags & TRACE_ITER_RECORD_TGID; bool tgid = flags & TRACE_ITER_RECORD_TGID;
const char *space = " "; const char *space = " ";
int prec = tgid ? 10 : 2; int prec = tgid ? 12 : 2;
print_event_info(buf, m); print_event_info(buf, m);
...@@ -3828,7 +3828,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file ...@@ -3828,7 +3828,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file
seq_printf(m, "# %.*s| / _---=> hardirq/softirq\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|| / _--=> preempt-depth\n", prec, space);
seq_printf(m, "# %.*s||| / delay\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, "# TASK-PID %.*s CPU# |||| TIMESTAMP FUNCTION\n", prec, " TGID ");
seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | "); seq_printf(m, "# | | %.*s | |||| | |\n", prec, " | ");
} }
......
...@@ -3865,7 +3865,6 @@ static int parse_var_defs(struct hist_trigger_data *hist_data) ...@@ -3865,7 +3865,6 @@ static int parse_var_defs(struct hist_trigger_data *hist_data)
s = kstrdup(field_str, GFP_KERNEL); s = kstrdup(field_str, GFP_KERNEL);
if (!s) { if (!s) {
kfree(hist_data->attrs->var_defs.name[n_vars]);
ret = -ENOMEM; ret = -ENOMEM;
goto free; goto free;
} }
......
...@@ -497,7 +497,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) ...@@ -497,7 +497,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
trace_find_cmdline(entry->pid, comm); 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); comm, entry->pid, cpu);
return trace_print_lat_fmt(s, entry); return trace_print_lat_fmt(s, entry);
...@@ -588,15 +588,15 @@ int trace_print_context(struct trace_iterator *iter) ...@@ -588,15 +588,15 @@ int trace_print_context(struct trace_iterator *iter)
trace_find_cmdline(entry->pid, comm); 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) { if (tr->trace_flags & TRACE_ITER_RECORD_TGID) {
unsigned int tgid = trace_find_tgid(entry->pid); unsigned int tgid = trace_find_tgid(entry->pid);
if (!tgid) if (!tgid)
trace_seq_printf(s, "(-----) "); trace_seq_printf(s, "(-------) ");
else else
trace_seq_printf(s, "(%5d) ", tgid); trace_seq_printf(s, "(%7d) ", tgid);
} }
trace_seq_printf(s, "[%03d] ", iter->cpu); trace_seq_printf(s, "[%03d] ", iter->cpu);
...@@ -636,7 +636,7 @@ int trace_print_lat_context(struct trace_iterator *iter) ...@@ -636,7 +636,7 @@ int trace_print_lat_context(struct trace_iterator *iter)
trace_find_cmdline(entry->pid, comm); trace_find_cmdline(entry->pid, comm);
trace_seq_printf( trace_seq_printf(
s, "%16s %5d %3d %d %08x %08lx ", s, "%16s %7d %3d %d %08x %08lx ",
comm, entry->pid, iter->cpu, entry->flags, comm, entry->pid, iter->cpu, entry->flags,
entry->preempt_count, iter->idx); entry->preempt_count, iter->idx);
} else { } else {
...@@ -917,7 +917,7 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, ...@@ -917,7 +917,7 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
S = task_index_to_char(field->prev_state); S = task_index_to_char(field->prev_state);
trace_find_cmdline(field->next_pid, comm); trace_find_cmdline(field->next_pid, comm);
trace_seq_printf(&iter->seq, 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_pid,
field->prev_prio, field->prev_prio,
S, delim, S, delim,
......
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