Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56f410cf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tracing fixes from Steven Rostedt:

 - Fix a bug caused by not cleaning up the new instance unique triggers
   when deleting an instance. It also creates a selftest that triggers
   that bug.

 - Fix the delayed optimization happening after kprobes boot up self
   tests being removed by freeing of init memory.

 - Comment kprobes on why the delay optimization is not a problem for
   removal of modules, to keep other developers from searching that
   riddle.

 - Fix another case of rcu not watching in stack trace tracing.

* tag 'trace-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracing: Make sure RCU is watching before calling a stack trace
  kprobes: Document how optimized kprobes are removed from module unload
  selftests/ftrace: Add test to remove instance with active event triggers
  selftests/ftrace: Fix bashisms
  ftrace: Remove #ifdef from code and add clear_ftrace_function_probes() stub
  ftrace/instances: Clear function triggers when removing instances
  ftrace: Simplify glob handling in unregister_ftrace_function_probe_func()
  tracing/kprobes: Enforce kprobes teardown after testing
  tracing: Move postpone selftests to core from early_initcall
parents 894e2164 a33d7d94
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -349,6 +349,9 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table,
					     int write, void __user *buffer,
					     size_t *length, loff_t *ppos);
#endif
extern void wait_for_kprobe_optimizer(void);
#else
static inline void wait_for_kprobe_optimizer(void) { }
#endif /* CONFIG_OPTPROBES */
#ifdef CONFIG_KPROBES_ON_FTRACE
extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+7 −1
Original line number Diff line number Diff line
@@ -595,7 +595,7 @@ static void kprobe_optimizer(struct work_struct *work)
}

/* Wait for completing optimization and unoptimization */
static void wait_for_kprobe_optimizer(void)
void wait_for_kprobe_optimizer(void)
{
	mutex_lock(&kprobe_mutex);

@@ -2183,6 +2183,12 @@ static int kprobes_module_callback(struct notifier_block *nb,
				 * The vaddr this probe is installed will soon
				 * be vfreed buy not synced to disk. Hence,
				 * disarming the breakpoint isn't needed.
				 *
				 * Note, this will also move any optimized probes
				 * that are pending to be removed from their
				 * corresponding lists to the freeing_list and
				 * will not be touched by the delayed
				 * kprobe_optimizer work handler.
				 */
				kill_kprobe(p);
			}
+10 −2
Original line number Diff line number Diff line
@@ -4144,9 +4144,9 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
	int i, ret = -ENODEV;
	int size;

	if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
	if (!glob || !strlen(glob) || !strcmp(glob, "*"))
		func_g.search = NULL;
	else if (glob) {
	else {
		int not;

		func_g.type = filter_parse_regex(glob, strlen(glob),
@@ -4256,6 +4256,14 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
	return ret;
}

void clear_ftrace_function_probes(struct trace_array *tr)
{
	struct ftrace_func_probe *probe, *n;

	list_for_each_entry_safe(probe, n, &tr->func_probes, list)
		unregister_ftrace_function_probe_func(NULL, tr, probe->probe_ops);
}

static LIST_HEAD(ftrace_commands);
static DEFINE_MUTEX(ftrace_cmd_mutex);

+32 −2
Original line number Diff line number Diff line
@@ -1558,7 +1558,7 @@ static __init int init_trace_selftests(void)

	return 0;
}
early_initcall(init_trace_selftests);
core_initcall(init_trace_selftests);
#else
static inline int run_tracer_selftest(struct tracer *type)
{
@@ -2568,7 +2568,36 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
		   int pc)
{
	__ftrace_trace_stack(tr->trace_buffer.buffer, flags, skip, pc, NULL);
	struct ring_buffer *buffer = tr->trace_buffer.buffer;

	if (rcu_is_watching()) {
		__ftrace_trace_stack(buffer, flags, skip, pc, NULL);
		return;
	}

	/*
	 * When an NMI triggers, RCU is enabled via rcu_nmi_enter(),
	 * but if the above rcu_is_watching() failed, then the NMI
	 * triggered someplace critical, and rcu_irq_enter() should
	 * not be called from NMI.
	 */
	if (unlikely(in_nmi()))
		return;

	/*
	 * It is possible that a function is being traced in a
	 * location that RCU is not watching. A call to
	 * rcu_irq_enter() will make sure that it is, but there's
	 * a few internal rcu functions that could be traced
	 * where that wont work either. In those cases, we just
	 * do nothing.
	 */
	if (unlikely(rcu_irq_enter_disabled()))
		return;

	rcu_irq_enter_irqson();
	__ftrace_trace_stack(buffer, flags, skip, pc, NULL);
	rcu_irq_exit_irqson();
}

/**
@@ -7550,6 +7579,7 @@ static int instance_rmdir(const char *name)
	}

	tracing_set_nop(tr);
	clear_ftrace_function_probes(tr);
	event_trace_del_tracer(tr);
	ftrace_clear_pids(tr);
	ftrace_destroy_function_files(tr);
+5 −0
Original line number Diff line number Diff line
@@ -980,6 +980,7 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr,
extern int
unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
				      struct ftrace_probe_ops *ops);
extern void clear_ftrace_function_probes(struct trace_array *tr);

int register_ftrace_command(struct ftrace_func_command *cmd);
int unregister_ftrace_command(struct ftrace_func_command *cmd);
@@ -998,6 +999,10 @@ static inline __init int unregister_ftrace_command(char *cmd_name)
{
	return -EINVAL;
}
static inline void clear_ftrace_function_probes(struct trace_array *tr)
{
}

/*
 * The ops parameter passed in is usually undefined.
 * This must be a macro.
Loading