tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
                               int prio);
 extern int
+tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data,
+                                        int prio);
+extern int
 tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
+static inline int
+tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe,
+                                   void *data)
+{
+       return tracepoint_probe_register_prio_may_exist(tp, probe, data,
+                                                       TRACEPOINT_DEFAULT_PRIO);
+}
 extern void
 for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
                void *priv);
 
        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_may_exist(tp, (void *)btp->bpf_func,
+                                                  prog);
 }
 
 int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
 
  * 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 warn)
 {
        struct tracepoint_func *old, *tp_funcs;
        int ret;
                        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(warn && PTR_ERR(old) != -ENOMEM);
                return PTR_ERR(old);
        }
 
        return 0;
 }
 
+/**
+ * tracepoint_probe_register_prio_may_exist -  Connect a probe to a tracepoint with priority
+ * @tp: tracepoint
+ * @probe: probe handler
+ * @data: tracepoint data
+ * @prio: priority of this function over other registered functions
+ *
+ * Same as tracepoint_probe_register_prio() except that it will not warn
+ * if the tracepoint is already registered.
+ */
+int tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe,
+                                            void *data, int prio)
+{
+       struct tracepoint_func tp_func;
+       int ret;
+
+       mutex_lock(&tracepoints_mutex);
+       tp_func.func = probe;
+       tp_func.data = data;
+       tp_func.prio = prio;
+       ret = tracepoint_add_func(tp, &tp_func, prio, false);
+       mutex_unlock(&tracepoints_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(tracepoint_probe_register_prio_may_exist);
+
 /**
  * tracepoint_probe_register_prio -  Connect a probe to a tracepoint with priority
  * @tp: tracepoint
        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, true);
        mutex_unlock(&tracepoints_mutex);
        return ret;
 }