tracing: Convert the per CPU "disabled" counter to local from atomic
authorSteven Rostedt <rostedt@goodmis.org>
Mon, 5 May 2025 21:21:15 +0000 (17:21 -0400)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Fri, 9 May 2025 19:19:10 +0000 (15:19 -0400)
The per CPU "disabled" counter is used for the latency tracers and stack
tracers to make sure that their accounting isn't messed up by an NMI or
interrupt coming in and affecting the same CPU data. But the counter is an
atomic_t type. As it only needs to synchronize against the current CPU,
switch it over to local_t type.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: https://lore.kernel.org/20250505212236.394925376@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace.h
kernel/trace/trace_functions.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_sched_wakeup.c

index 69c1ecf..188032d 100644 (file)
@@ -183,7 +183,7 @@ struct trace_array;
  * the trace, etc.)
  */
 struct trace_array_cpu {
-       atomic_t                disabled;
+       local_t                 disabled;
        void                    *buffer_page;   /* ring buffer spare */
 
        unsigned long           entries;
index bd15321..99a90f1 100644 (file)
@@ -291,7 +291,7 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
        parent_ip = function_get_true_parent_ip(parent_ip, fregs);
        cpu = raw_smp_processor_id();
        data = per_cpu_ptr(tr->array_buffer.data, cpu);
-       disabled = atomic_inc_return(&data->disabled);
+       disabled = local_inc_return(&data->disabled);
 
        if (likely(disabled == 1)) {
                trace_ctx = tracing_gen_ctx_flags(flags);
@@ -303,7 +303,7 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
                __trace_stack(tr, trace_ctx, skip);
        }
 
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
        local_irq_restore(flags);
 }
 
@@ -402,7 +402,7 @@ function_stack_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
        parent_ip = function_get_true_parent_ip(parent_ip, fregs);
        cpu = raw_smp_processor_id();
        data = per_cpu_ptr(tr->array_buffer.data, cpu);
-       disabled = atomic_inc_return(&data->disabled);
+       disabled = local_inc_return(&data->disabled);
 
        if (likely(disabled == 1)) {
                last_info = per_cpu_ptr(tr->last_func_repeats, cpu);
@@ -417,7 +417,7 @@ function_stack_no_repeats_trace_call(unsigned long ip, unsigned long parent_ip,
        }
 
  out:
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
        local_irq_restore(flags);
 }
 
index 40c39e9..0b6d932 100644 (file)
@@ -123,12 +123,12 @@ static int func_prolog_dec(struct trace_array *tr,
                return 0;
 
        *data = per_cpu_ptr(tr->array_buffer.data, cpu);
-       disabled = atomic_inc_return(&(*data)->disabled);
+       disabled = local_inc_return(&(*data)->disabled);
 
        if (likely(disabled == 1))
                return 1;
 
-       atomic_dec(&(*data)->disabled);
+       local_dec(&(*data)->disabled);
 
        return 0;
 }
@@ -152,7 +152,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip,
 
        trace_function(tr, ip, parent_ip, trace_ctx, fregs);
 
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 }
 #endif /* CONFIG_FUNCTION_TRACER */
 
@@ -209,7 +209,7 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,
 
        trace_ctx = tracing_gen_ctx_flags(flags);
        ret = __trace_graph_entry(tr, trace, trace_ctx);
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 
        return ret;
 }
@@ -238,7 +238,7 @@ static void irqsoff_graph_return(struct ftrace_graph_ret *trace,
 
        trace_ctx = tracing_gen_ctx_flags(flags);
        __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime);
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 }
 
 static struct fgraph_ops fgraph_ops = {
@@ -408,10 +408,10 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        data = per_cpu_ptr(tr->array_buffer.data, cpu);
 
-       if (unlikely(!data) || atomic_read(&data->disabled))
+       if (unlikely(!data) || local_read(&data->disabled))
                return;
 
-       atomic_inc(&data->disabled);
+       local_inc(&data->disabled);
 
        data->critical_sequence = max_sequence;
        data->preempt_timestamp = ftrace_now(cpu);
@@ -421,7 +421,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        per_cpu(tracing_cpu, cpu) = 1;
 
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 }
 
 static nokprobe_inline void
@@ -445,16 +445,16 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
        data = per_cpu_ptr(tr->array_buffer.data, cpu);
 
        if (unlikely(!data) ||
-           !data->critical_start || atomic_read(&data->disabled))
+           !data->critical_start || local_read(&data->disabled))
                return;
 
-       atomic_inc(&data->disabled);
+       local_inc(&data->disabled);
 
        trace_ctx = tracing_gen_ctx();
        __trace_function(tr, ip, parent_ip, trace_ctx);
        check_critical_timing(tr, data, parent_ip ? : ip, cpu);
        data->critical_start = 0;
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 }
 
 /* start and stop critical timings used to for stoppage (in idle) */
index a0db340..bf1cb80 100644 (file)
@@ -83,14 +83,14 @@ func_prolog_preempt_disable(struct trace_array *tr,
                goto out_enable;
 
        *data = per_cpu_ptr(tr->array_buffer.data, cpu);
-       disabled = atomic_inc_return(&(*data)->disabled);
+       disabled = local_inc_return(&(*data)->disabled);
        if (unlikely(disabled != 1))
                goto out;
 
        return 1;
 
 out:
-       atomic_dec(&(*data)->disabled);
+       local_dec(&(*data)->disabled);
 
 out_enable:
        preempt_enable_notrace();
@@ -144,7 +144,7 @@ static int wakeup_graph_entry(struct ftrace_graph_ent *trace,
        *calltime = trace_clock_local();
 
        ret = __trace_graph_entry(tr, trace, trace_ctx);
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
        preempt_enable_notrace();
 
        return ret;
@@ -173,7 +173,7 @@ static void wakeup_graph_return(struct ftrace_graph_ret *trace,
                return;
 
        __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime);
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
 
        preempt_enable_notrace();
        return;
@@ -243,7 +243,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip,
        trace_function(tr, ip, parent_ip, trace_ctx, fregs);
        local_irq_restore(flags);
 
-       atomic_dec(&data->disabled);
+       local_dec(&data->disabled);
        preempt_enable_notrace();
 }
 
@@ -471,7 +471,7 @@ probe_wakeup_sched_switch(void *ignore, bool preempt,
 
        /* disable local data, not wakeup_cpu data */
        cpu = raw_smp_processor_id();
-       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
+       disabled = local_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
        if (likely(disabled != 1))
                goto out;
 
@@ -508,7 +508,7 @@ out_unlock:
        arch_spin_unlock(&wakeup_lock);
        local_irq_restore(flags);
 out:
-       atomic_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
+       local_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
 }
 
 static void __wakeup_reset(struct trace_array *tr)
@@ -563,7 +563,7 @@ probe_wakeup(void *ignore, struct task_struct *p)
            (!dl_task(p) && (p->prio >= wakeup_prio || p->prio >= current->prio)))
                return;
 
-       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
+       disabled = local_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
        if (unlikely(disabled != 1))
                goto out;
 
@@ -610,7 +610,7 @@ probe_wakeup(void *ignore, struct task_struct *p)
 out_locked:
        arch_spin_unlock(&wakeup_lock);
 out:
-       atomic_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
+       local_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
 }
 
 static void start_wakeup_tracer(struct trace_array *tr)