Skip to content

Commit

Permalink
Merge tag 'trace-v6.13-rc1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/trace/linux-trace

Pull tracing fixes from Steven Rostedt:

 - Fix trace histogram sort function cmp_entries_dup()

   The sort function cmp_entries_dup() returns either 1 or 0, and not -1
   if parameter "a" is less than "b" by memcmp().

 - Fix archs that call trace_hardirqs_off() without RCU watching

   Both x86 and arm64 no longer call any tracepoints with RCU not
   watching. It was assumed that it was safe to get rid of
   trace_*_rcuidle() version of the tracepoint calls. This was needed to
   get rid of the SRCU protection and be able to implement features like
   faultable traceponits and add rust tracepoints.

   Unfortunately, there were a few architectures that still relied on
   that logic. There's only one file that has tracepoints that are
   called without RCU watching. Add macro logic around the tracepoints
   for architectures that do not have CONFIG_ARCH_WANTS_NO_INSTR defined
   will check if the code is in the idle path (the only place RCU isn't
   watching), and enable RCU around calling the tracepoint, but only do
   it if the tracepoint is enabled.

* tag 'trace-v6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: Fix archs that still call tracepoints without RCU watching
  tracing: Fix cmp_entries_dup() to respect sort() comparison rules
  • Loading branch information
Linus Torvalds committed Dec 5, 2024
2 parents 2a770b4 + dc1b157 commit 9d6a414
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
43 changes: 37 additions & 6 deletions kernel/trace/trace_preemptirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,42 @@
#include <linux/module.h>
#include <linux/ftrace.h>
#include <linux/kprobes.h>
#include <linux/hardirq.h>
#include "trace.h"

#define CREATE_TRACE_POINTS
#include <trace/events/preemptirq.h>

/*
* Use regular trace points on architectures that implement noinstr
* tooling: these calls will only happen with RCU enabled, which can
* use a regular tracepoint.
*
* On older architectures, RCU may not be watching in idle. In that
* case, wake up RCU to watch while calling the tracepoint. These
* aren't NMI-safe - so exclude NMI contexts:
*/
#ifdef CONFIG_ARCH_WANTS_NO_INSTR
#define trace(point, args) trace_##point(args)
#else
#define trace(point, args) \
do { \
if (trace_##point##_enabled()) { \
bool exit_rcu = false; \
if (in_nmi()) \
break; \
if (!IS_ENABLED(CONFIG_TINY_RCU) && \
is_idle_task(current)) { \
ct_irq_enter(); \
exit_rcu = true; \
} \
trace_##point(args); \
if (exit_rcu) \
ct_irq_exit(); \
} \
} while (0)
#endif

#ifdef CONFIG_TRACE_IRQFLAGS
/* Per-cpu variable to prevent redundant calls when IRQs already off */
static DEFINE_PER_CPU(int, tracing_irq_cpu);
Expand All @@ -28,7 +59,7 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu);
void trace_hardirqs_on_prepare(void)
{
if (this_cpu_read(tracing_irq_cpu)) {
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
trace(irq_enable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1));
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
this_cpu_write(tracing_irq_cpu, 0);
}
Expand All @@ -39,7 +70,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);
void trace_hardirqs_on(void)
{
if (this_cpu_read(tracing_irq_cpu)) {
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
trace(irq_enable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1));
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
this_cpu_write(tracing_irq_cpu, 0);
}
Expand All @@ -61,7 +92,7 @@ void trace_hardirqs_off_finish(void)
if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1);
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
trace(irq_disable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1));
}

}
Expand All @@ -75,7 +106,7 @@ void trace_hardirqs_off(void)
if (!this_cpu_read(tracing_irq_cpu)) {
this_cpu_write(tracing_irq_cpu, 1);
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
trace(irq_disable, TP_ARGS(CALLER_ADDR0, CALLER_ADDR1));
}
}
EXPORT_SYMBOL(trace_hardirqs_off);
Expand All @@ -86,13 +117,13 @@ NOKPROBE_SYMBOL(trace_hardirqs_off);

void trace_preempt_on(unsigned long a0, unsigned long a1)
{
trace_preempt_enable(a0, a1);
trace(preempt_enable, TP_ARGS(a0, a1));
tracer_preempt_on(a0, a1);
}

void trace_preempt_off(unsigned long a0, unsigned long a1)
{
trace_preempt_disable(a0, a1);
trace(preempt_disable, TP_ARGS(a0, a1));
tracer_preempt_off(a0, a1);
}
#endif
6 changes: 1 addition & 5 deletions kernel/trace/tracing_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,15 +845,11 @@ int tracing_map_init(struct tracing_map *map)
static int cmp_entries_dup(const void *A, const void *B)
{
const struct tracing_map_sort_entry *a, *b;
int ret = 0;

a = *(const struct tracing_map_sort_entry **)A;
b = *(const struct tracing_map_sort_entry **)B;

if (memcmp(a->key, b->key, a->elt->map->key_size))
ret = 1;

return ret;
return memcmp(a->key, b->key, a->elt->map->key_size);
}

static int cmp_entries_sum(const void *A, const void *B)
Expand Down

0 comments on commit 9d6a414

Please sign in to comment.