Skip to content

Commit dbc15d2

Browse files
committed
Merge tag 'trace-v5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: - Initialize tracing-graph-pause at task creation, not start of function tracing, to avoid corrupting the pause counter. - Set "pause-on-trace" for latency tracers as that option breaks their output (regression). - Fix the wrong error return for setting kretprobes on future modules (before they are loaded). - Fix re-registering the same kretprobe. - Add missing value check for added RCU variable reload. * tag 'trace-v5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracepoint: Fix race between tracing and removing tracepoint kretprobe: Avoid re-registration of the same kretprobe earlier tracing/kprobe: Fix to support kretprobe events on unloaded modules tracing: Use pause-on-trace with the latency tracers fgraph: Initialize tracing_graph_pause at task creation
2 parents 54fe3ff + c8b186a commit dbc15d2

File tree

7 files changed

+48
-21
lines changed

7 files changed

+48
-21
lines changed

include/linux/kprobes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ extern void kprobes_inc_nmissed_count(struct kprobe *p);
266266
extern bool arch_within_kprobe_blacklist(unsigned long addr);
267267
extern int arch_populate_kprobe_blacklist(void);
268268
extern bool arch_kprobe_on_func_entry(unsigned long offset);
269-
extern bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset);
269+
extern int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset);
270270

271271
extern bool within_kprobe_blacklist(unsigned long addr);
272272
extern int kprobe_add_ksym_blacklist(unsigned long entry);

include/linux/tracepoint.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
307307
\
308308
it_func_ptr = \
309309
rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
310-
do { \
311-
it_func = (it_func_ptr)->func; \
312-
__data = (it_func_ptr)->data; \
313-
((void(*)(void *, proto))(it_func))(__data, args); \
314-
} while ((++it_func_ptr)->func); \
310+
if (it_func_ptr) { \
311+
do { \
312+
it_func = (it_func_ptr)->func; \
313+
__data = (it_func_ptr)->data; \
314+
((void(*)(void *, proto))(it_func))(__data, args); \
315+
} while ((++it_func_ptr)->func); \
316+
} \
315317
return 0; \
316318
} \
317319
DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);

init/init_task.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ struct task_struct init_task
198198
.lockdep_recursion = 0,
199199
#endif
200200
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
201-
.ret_stack = NULL,
201+
.ret_stack = NULL,
202+
.tracing_graph_pause = ATOMIC_INIT(0),
202203
#endif
203204
#if defined(CONFIG_TRACING) && defined(CONFIG_PREEMPTION)
204205
.trace_recursion = 0,

kernel/kprobes.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,28 +1954,48 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset)
19541954
return !offset;
19551955
}
19561956

1957-
bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
1957+
/**
1958+
* kprobe_on_func_entry() -- check whether given address is function entry
1959+
* @addr: Target address
1960+
* @sym: Target symbol name
1961+
* @offset: The offset from the symbol or the address
1962+
*
1963+
* This checks whether the given @addr+@offset or @sym+@offset is on the
1964+
* function entry address or not.
1965+
* This returns 0 if it is the function entry, or -EINVAL if it is not.
1966+
* And also it returns -ENOENT if it fails the symbol or address lookup.
1967+
* Caller must pass @addr or @sym (either one must be NULL), or this
1968+
* returns -EINVAL.
1969+
*/
1970+
int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
19581971
{
19591972
kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
19601973

19611974
if (IS_ERR(kp_addr))
1962-
return false;
1975+
return PTR_ERR(kp_addr);
19631976

1964-
if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) ||
1965-
!arch_kprobe_on_func_entry(offset))
1966-
return false;
1977+
if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset))
1978+
return -ENOENT;
19671979

1968-
return true;
1980+
if (!arch_kprobe_on_func_entry(offset))
1981+
return -EINVAL;
1982+
1983+
return 0;
19691984
}
19701985

19711986
int register_kretprobe(struct kretprobe *rp)
19721987
{
1973-
int ret = 0;
1988+
int ret;
19741989
struct kretprobe_instance *inst;
19751990
int i;
19761991
void *addr;
19771992

1978-
if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset))
1993+
ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset);
1994+
if (ret)
1995+
return ret;
1996+
1997+
/* If only rp->kp.addr is specified, check reregistering kprobes */
1998+
if (rp->kp.addr && check_kprobe_rereg(&rp->kp))
19791999
return -EINVAL;
19802000

19812001
if (kretprobe_blacklist_size) {

kernel/trace/fgraph.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
394394
}
395395

396396
if (t->ret_stack == NULL) {
397-
atomic_set(&t->tracing_graph_pause, 0);
398397
atomic_set(&t->trace_overrun, 0);
399398
t->curr_ret_stack = -1;
400399
t->curr_ret_depth = -1;
@@ -489,7 +488,6 @@ static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack);
489488
static void
490489
graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack)
491490
{
492-
atomic_set(&t->tracing_graph_pause, 0);
493491
atomic_set(&t->trace_overrun, 0);
494492
t->ftrace_timestamp = 0;
495493
/* make curr_ret_stack visible before we add the ret_stack */

kernel/trace/trace_irqsoff.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ static int __irqsoff_tracer_init(struct trace_array *tr)
562562
/* non overwrite screws up the latency tracers */
563563
set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 1);
564564
set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, 1);
565+
/* without pause, we will produce garbage if another latency occurs */
566+
set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, 1);
565567

566568
tr->max_latency = 0;
567569
irqsoff_trace = tr;
@@ -583,11 +585,13 @@ static void __irqsoff_tracer_reset(struct trace_array *tr)
583585
{
584586
int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
585587
int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
588+
int pause_flag = save_flags & TRACE_ITER_PAUSE_ON_TRACE;
586589

587590
stop_irqsoff_tracer(tr, is_graph(tr));
588591

589592
set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, lat_flag);
590593
set_tracer_flag(tr, TRACE_ITER_OVERWRITE, overwrite_flag);
594+
set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, pause_flag);
591595
ftrace_reset_array_ops(tr);
592596

593597
irqsoff_busy = false;

kernel/trace/trace_kprobe.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ bool trace_kprobe_on_func_entry(struct trace_event_call *call)
221221
{
222222
struct trace_kprobe *tk = trace_kprobe_primary_from_call(call);
223223

224-
return tk ? kprobe_on_func_entry(tk->rp.kp.addr,
224+
return tk ? (kprobe_on_func_entry(tk->rp.kp.addr,
225225
tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name,
226-
tk->rp.kp.addr ? 0 : tk->rp.kp.offset) : false;
226+
tk->rp.kp.addr ? 0 : tk->rp.kp.offset) == 0) : false;
227227
}
228228

229229
bool trace_kprobe_error_injectable(struct trace_event_call *call)
@@ -828,9 +828,11 @@ static int trace_kprobe_create(int argc, const char *argv[])
828828
}
829829
if (is_return)
830830
flags |= TPARG_FL_RETURN;
831-
if (kprobe_on_func_entry(NULL, symbol, offset))
831+
ret = kprobe_on_func_entry(NULL, symbol, offset);
832+
if (ret == 0)
832833
flags |= TPARG_FL_FENTRY;
833-
if (offset && is_return && !(flags & TPARG_FL_FENTRY)) {
834+
/* Defer the ENOENT case until register kprobe */
835+
if (ret == -EINVAL && is_return) {
834836
trace_probe_log_err(0, BAD_RETPROBE);
835837
goto parse_error;
836838
}

0 commit comments

Comments
 (0)