tracing: Convert the per CPU "disabled" counter to local from atomic
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>
This commit is contained in:
committed by
Steven Rostedt (Google)
parent
cf64792f0a
commit
90633c34c3
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user