Commit 289e7b0f authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Steven Rostedt
Browse files

tracing: Account bottom half disabled sections.

Disabling only bottom halves via local_bh_disable() disables also
preemption but this remains invisible to tracing. On a CONFIG_PREEMPT
kernel one might wonder why there is no scheduling happening despite the
N flag in the trace. The reason might be the a rcu_read_lock_bh()
section.

Add a 'b' to the tracing output if in task context with disabled bottom
halves.

Link: https://lkml.kernel.org/r/YbcbtdtC/bjCKo57@linutronix.de



Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 86599dbe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ enum trace_flag_type {
	TRACE_FLAG_SOFTIRQ		= 0x10,
	TRACE_FLAG_PREEMPT_RESCHED	= 0x20,
	TRACE_FLAG_NMI			= 0x40,
	TRACE_FLAG_BH_OFF		= 0x80,
};

#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
+4 −2
Original line number Diff line number Diff line
@@ -2603,6 +2603,8 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status)
		trace_flags |= TRACE_FLAG_HARDIRQ;
	if (in_serving_softirq())
		trace_flags |= TRACE_FLAG_SOFTIRQ;
	if (softirq_count() >> (SOFTIRQ_SHIFT + 1))
		trace_flags |= TRACE_FLAG_BH_OFF;

	if (tif_need_resched())
		trace_flags |= TRACE_FLAG_NEED_RESCHED;
@@ -4190,7 +4192,7 @@ 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"
		    "#                   / _-----=> irqs-off/BH-disabled\n"
		    "#                  | / _----=> need-resched    \n"
		    "#                  || / _---=> hardirq/softirq \n"
		    "#                  ||| / _--=> preempt-depth   \n"
@@ -4231,7 +4233,7 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file

	print_event_info(buf, m);

	seq_printf(m, "#                            %.*s  _-----=> irqs-off\n", prec, space);
	seq_printf(m, "#                            %.*s  _-----=> irqs-off/BH-disabled\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);
+4 −0
Original line number Diff line number Diff line
@@ -445,14 +445,18 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
	char irqs_off;
	int hardirq;
	int softirq;
	int bh_off;
	int nmi;

	nmi = entry->flags & TRACE_FLAG_NMI;
	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
	bh_off = entry->flags & TRACE_FLAG_BH_OFF;

	irqs_off =
		(entry->flags & TRACE_FLAG_IRQS_OFF && bh_off) ? 'D' :
		(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
		bh_off ? 'b' :
		(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
		'.';