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

Commit 457d2ee2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'tracing-fixes-for-linus' of...

Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  tracing, ring-buffer: add paranoid checks for loops
  ftrace: use kretprobe trampoline name to test in output
  tracing, alpha: undefined reference to `save_stack_trace'
parents da4a22cb 818e3dd3
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@ config TRACING
	bool
	bool
	select DEBUG_FS
	select DEBUG_FS
	select RING_BUFFER
	select RING_BUFFER
	select STACKTRACE
	select STACKTRACE if STACKTRACE_SUPPORT
	select TRACEPOINTS
	select TRACEPOINTS
	select NOP_TRACER
	select NOP_TRACER


+56 −0
Original line number Original line Diff line number Diff line
@@ -1022,8 +1022,23 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
	struct ring_buffer_event *event;
	struct ring_buffer_event *event;
	u64 ts, delta;
	u64 ts, delta;
	int commit = 0;
	int commit = 0;
	int nr_loops = 0;


 again:
 again:
	/*
	 * We allow for interrupts to reenter here and do a trace.
	 * If one does, it will cause this original code to loop
	 * back here. Even with heavy interrupts happening, this
	 * should only happen a few times in a row. If this happens
	 * 1000 times in a row, there must be either an interrupt
	 * storm or we have something buggy.
	 * Bail!
	 */
	if (unlikely(++nr_loops > 1000)) {
		RB_WARN_ON(cpu_buffer, 1);
		return NULL;
	}

	ts = ring_buffer_time_stamp(cpu_buffer->cpu);
	ts = ring_buffer_time_stamp(cpu_buffer->cpu);


	/*
	/*
@@ -1532,10 +1547,23 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
{
{
	struct buffer_page *reader = NULL;
	struct buffer_page *reader = NULL;
	unsigned long flags;
	unsigned long flags;
	int nr_loops = 0;


	spin_lock_irqsave(&cpu_buffer->lock, flags);
	spin_lock_irqsave(&cpu_buffer->lock, flags);


 again:
 again:
	/*
	 * This should normally only loop twice. But because the
	 * start of the reader inserts an empty page, it causes
	 * a case where we will loop three times. There should be no
	 * reason to loop four times (that I know of).
	 */
	if (unlikely(++nr_loops > 3)) {
		RB_WARN_ON(cpu_buffer, 1);
		reader = NULL;
		goto out;
	}

	reader = cpu_buffer->reader_page;
	reader = cpu_buffer->reader_page;


	/* If there's more to read, return this page */
	/* If there's more to read, return this page */
@@ -1665,6 +1693,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_event *event;
	struct ring_buffer_event *event;
	struct buffer_page *reader;
	struct buffer_page *reader;
	int nr_loops = 0;


	if (!cpu_isset(cpu, buffer->cpumask))
	if (!cpu_isset(cpu, buffer->cpumask))
		return NULL;
		return NULL;
@@ -1672,6 +1701,19 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
	cpu_buffer = buffer->buffers[cpu];
	cpu_buffer = buffer->buffers[cpu];


 again:
 again:
	/*
	 * We repeat when a timestamp is encountered. It is possible
	 * to get multiple timestamps from an interrupt entering just
	 * as one timestamp is about to be written. The max times
	 * that this can happen is the number of nested interrupts we
	 * can have.  Nesting 10 deep of interrupts is clearly
	 * an anomaly.
	 */
	if (unlikely(++nr_loops > 10)) {
		RB_WARN_ON(cpu_buffer, 1);
		return NULL;
	}

	reader = rb_get_reader_page(cpu_buffer);
	reader = rb_get_reader_page(cpu_buffer);
	if (!reader)
	if (!reader)
		return NULL;
		return NULL;
@@ -1722,6 +1764,7 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
	struct ring_buffer *buffer;
	struct ring_buffer *buffer;
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_event *event;
	struct ring_buffer_event *event;
	int nr_loops = 0;


	if (ring_buffer_iter_empty(iter))
	if (ring_buffer_iter_empty(iter))
		return NULL;
		return NULL;
@@ -1730,6 +1773,19 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
	buffer = cpu_buffer->buffer;
	buffer = cpu_buffer->buffer;


 again:
 again:
	/*
	 * We repeat when a timestamp is encountered. It is possible
	 * to get multiple timestamps from an interrupt entering just
	 * as one timestamp is about to be written. The max times
	 * that this can happen is the number of nested interrupts we
	 * can have. Nesting 10 deep of interrupts is clearly
	 * an anomaly.
	 */
	if (unlikely(++nr_loops > 10)) {
		RB_WARN_ON(cpu_buffer, 1);
		return NULL;
	}

	if (rb_per_cpu_empty(cpu_buffer))
	if (rb_per_cpu_empty(cpu_buffer))
		return NULL;
		return NULL;


+23 −18
Original line number Original line Diff line number Diff line
@@ -705,6 +705,7 @@ static void ftrace_trace_stack(struct trace_array *tr,
			       unsigned long flags,
			       unsigned long flags,
			       int skip, int pc)
			       int skip, int pc)
{
{
#ifdef CONFIG_STACKTRACE
	struct ring_buffer_event *event;
	struct ring_buffer_event *event;
	struct stack_entry *entry;
	struct stack_entry *entry;
	struct stack_trace trace;
	struct stack_trace trace;
@@ -730,6 +731,7 @@ static void ftrace_trace_stack(struct trace_array *tr,


	save_stack_trace(&trace);
	save_stack_trace(&trace);
	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
#endif
}
}


void __trace_stack(struct trace_array *tr,
void __trace_stack(struct trace_array *tr,
@@ -1086,17 +1088,20 @@ static void s_stop(struct seq_file *m, void *p)
	mutex_unlock(&trace_types_lock);
	mutex_unlock(&trace_types_lock);
}
}


#define KRETPROBE_MSG "[unknown/kretprobe'd]"

#ifdef CONFIG_KRETPROBES
#ifdef CONFIG_KRETPROBES
static inline int kretprobed(unsigned long addr)
static inline const char *kretprobed(const char *name)
{
{
	return addr == (unsigned long)kretprobe_trampoline;
	static const char tramp_name[] = "kretprobe_trampoline";
	int size = sizeof(tramp_name);

	if (strncmp(tramp_name, name, size) == 0)
		return "[unknown/kretprobe'd]";
	return name;
}
}
#else
#else
static inline int kretprobed(unsigned long addr)
static inline const char *kretprobed(const char *name)
{
{
	return 0;
	return name;
}
}
#endif /* CONFIG_KRETPROBES */
#endif /* CONFIG_KRETPROBES */


@@ -1105,10 +1110,13 @@ seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
{
{
#ifdef CONFIG_KALLSYMS
#ifdef CONFIG_KALLSYMS
	char str[KSYM_SYMBOL_LEN];
	char str[KSYM_SYMBOL_LEN];
	const char *name;


	kallsyms_lookup(address, NULL, NULL, NULL, str);
	kallsyms_lookup(address, NULL, NULL, NULL, str);


	return trace_seq_printf(s, fmt, str);
	name = kretprobed(str);

	return trace_seq_printf(s, fmt, name);
#endif
#endif
	return 1;
	return 1;
}
}
@@ -1119,9 +1127,12 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt,
{
{
#ifdef CONFIG_KALLSYMS
#ifdef CONFIG_KALLSYMS
	char str[KSYM_SYMBOL_LEN];
	char str[KSYM_SYMBOL_LEN];
	const char *name;


	sprint_symbol(str, address);
	sprint_symbol(str, address);
	return trace_seq_printf(s, fmt, str);
	name = kretprobed(str);

	return trace_seq_printf(s, fmt, name);
#endif
#endif
	return 1;
	return 1;
}
}
@@ -1375,9 +1386,6 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)


		seq_print_ip_sym(s, field->ip, sym_flags);
		seq_print_ip_sym(s, field->ip, sym_flags);
		trace_seq_puts(s, " (");
		trace_seq_puts(s, " (");
		if (kretprobed(field->parent_ip))
			trace_seq_puts(s, KRETPROBE_MSG);
		else
		seq_print_ip_sym(s, field->parent_ip, sym_flags);
		seq_print_ip_sym(s, field->parent_ip, sym_flags);
		trace_seq_puts(s, ")\n");
		trace_seq_puts(s, ")\n");
		break;
		break;
@@ -1494,9 +1502,6 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
			ret = trace_seq_printf(s, " <-");
			ret = trace_seq_printf(s, " <-");
			if (!ret)
			if (!ret)
				return TRACE_TYPE_PARTIAL_LINE;
				return TRACE_TYPE_PARTIAL_LINE;
			if (kretprobed(field->parent_ip))
				ret = trace_seq_puts(s, KRETPROBE_MSG);
			else
			ret = seq_print_ip_sym(s,
			ret = seq_print_ip_sym(s,
					       field->parent_ip,
					       field->parent_ip,
					       sym_flags);
					       sym_flags);