diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 13f65420f188..656d22cf42fc 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -36,10 +36,11 @@ struct trace_eval_map {
extern struct srcu_struct tracepoint_srcu;
extern int
-tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
+tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data,
+ bool no_warn);
extern int
tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
- int prio);
+ int prio, bool no_warn);
extern int
tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
extern void@@ -250,14 +251,16 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
register_trace_##name(void (*probe)(data_proto), void *data) \
{ \
return tracepoint_probe_register(&__tracepoint_##name, \
- (void *)probe, data); \
+ (void *)probe, data, \
+ false); \
} \
static inline int \
register_trace_prio_##name(void (*probe)(data_proto), void *data,\
int prio) \
{ \
return tracepoint_probe_register_prio(&__tracepoint_##name, \
- (void *)probe, data, prio); \
+ (void *)probe, data, \
+ prio, false); \
} \
static inline int \
unregister_trace_##name(void (*probe)(data_proto), void *data) \diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c
index 8bcffbdef3d3..b76738e61eee 100644
--- a/kernel/kcsan/kcsan_test.c
+++ b/kernel/kcsan/kcsan_test.c
@@ -1160,7 +1160,7 @@ static void register_tracepoints(struct tracepoint *tp, void *ignore)
{
check_trace_callback_type_console(probe_console);
if (!strcmp(tp->name, "console"))
- WARN_ON(tracepoint_probe_register(tp, probe_console, NULL));
+ WARN_ON(tracepoint_probe_register(tp, probe_console, NULL, false));
}
__no_kcsandiff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 7a52bc172841..3d3a80db40b5 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1840,7 +1840,7 @@ static int __bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *
if (prog->aux->max_tp_access > btp->writable_size)
return -EINVAL;
- return tracepoint_probe_register(tp, (void *)btp->bpf_func, prog);
+ return tracepoint_probe_register(tp, (void *)btp->bpf_func, prog, true);
}
int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 80e96989770e..07986569b1b9 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -500,7 +500,7 @@ int trace_event_reg(struct trace_event_call *call,
case TRACE_REG_REGISTER:
return tracepoint_probe_register(call->tp,
call->class->probe,
- file);
+ file, false);
case TRACE_REG_UNREGISTER:
tracepoint_probe_unregister(call->tp,
call->class->probe,
@@ -511,7 +511,7 @@ int trace_event_reg(struct trace_event_call *call,
case TRACE_REG_PERF_REGISTER:
return tracepoint_probe_register(call->tp,
call->class->perf_probe,
- call);
+ call, false);
case TRACE_REG_PERF_UNREGISTER:
tracepoint_probe_unregister(call->tp,
call->class->perf_probe,
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 9f478d29b926..3c3a517b229e 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -273,7 +273,8 @@ static void tracepoint_update_call(struct tracepoint *tp, struct tracepoint_func
* Add the probe function to a tracepoint.
*/
static int tracepoint_add_func(struct tracepoint *tp,
- struct tracepoint_func *func, int prio)
+ struct tracepoint_func *func, int prio,
+ bool no_warn)
{
struct tracepoint_func *old, *tp_funcs;
int ret;@@ -288,7 +289,7 @@ static int tracepoint_add_func(struct tracepoint *tp,
lockdep_is_held(&tracepoints_mutex));
old = func_add(&tp_funcs, func, prio);
if (IS_ERR(old)) {
- WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
+ WARN_ON_ONCE(!no_warn && PTR_ERR(old) != -ENOMEM);
return PTR_ERR(old);
}
@@ -349,6 +350,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
* @probe: probe handler
* @data: tracepoint data
* @prio: priority of this function over other registered functions
+ * @no_warn: Do not warn if the tracepoint is already registered
*
* Returns 0 if ok, error value on error.
* Note: if @tp is within a module, the caller is responsible for
@@ -357,7 +359,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
* within module exit functions.
*/
int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe,
- void *data, int prio)
+ void *data, int prio, bool no_warn)
{
struct tracepoint_func tp_func;
int ret;@@ -366,7 +368,7 @@ int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe,
tp_func.func = probe;
tp_func.data = data;
tp_func.prio = prio;
- ret = tracepoint_add_func(tp, &tp_func, prio);
+ ret = tracepoint_add_func(tp, &tp_func, prio, no_warn);
mutex_unlock(&tracepoints_mutex);
return ret;
}
@@ -377,6 +379,7 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_register_prio);
* @tp: tracepoint
* @probe: probe handler
* @data: tracepoint data
+ * @no_warn: Do not warn if the tracepoint is already registered
*
* Returns 0 if ok, error value on error.
* Note: if @tp is within a module, the caller is responsible for
@@ -384,9 +387,11 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_register_prio);
* performed either with a tracepoint module going notifier, or from
* within module exit functions.
*/
-int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data)
+int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data,
+ bool no_warn)
{
- return tracepoint_probe_register_prio(tp, probe, data, TRACEPOINT_DEFAULT_PRIO);
+ return tracepoint_probe_register_prio(tp, probe, data,
+ TRACEPOINT_DEFAULT_PRIO, no_warn);
}
EXPORT_SYMBOL_GPL(tracepoint_probe_register);
diff --git a/mm/kfence/kfence_test.c b/mm/kfence/kfence_test.c
index 4acf4251ee04..a9331c967690 100644
--- a/mm/kfence/kfence_test.c
+++ b/mm/kfence/kfence_test.c
@@ -820,7 +820,7 @@ static void register_tracepoints(struct tracepoint *tp, void *ignore)
{
check_trace_callback_type_console(probe_console);
if (!strcmp(tp->name, "console"))
- WARN_ON(tracepoint_probe_register(tp, probe_console, NULL));
+ WARN_ON(tracepoint_probe_register(tp, probe_console, NULL, true));
}
static void unregister_tracepoints(struct tracepoint *tp, void *ignore)