@@ -385,6 +385,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
385385 const char * event ,
386386 const char * symbol ,
387387 struct tracepoint * tpoint ,
388+ struct module * mod ,
388389 int maxactive ,
389390 int nargs , bool is_return )
390391{
@@ -405,6 +406,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
405406 tf -> fp .entry_handler = fentry_dispatcher ;
406407
407408 tf -> tpoint = tpoint ;
409+ tf -> mod = mod ;
408410 tf -> fp .nr_maxactive = maxactive ;
409411
410412 ret = trace_probe_init (& tf -> tp , event , group , false, nargs );
@@ -895,8 +897,23 @@ static struct notifier_block tracepoint_module_nb = {
895897struct __find_tracepoint_cb_data {
896898 const char * tp_name ;
897899 struct tracepoint * tpoint ;
900+ struct module * mod ;
898901};
899902
903+ static void __find_tracepoint_module_cb (struct tracepoint * tp , struct module * mod , void * priv )
904+ {
905+ struct __find_tracepoint_cb_data * data = priv ;
906+
907+ if (!data -> tpoint && !strcmp (data -> tp_name , tp -> name )) {
908+ data -> tpoint = tp ;
909+ data -> mod = mod ;
910+ if (!try_module_get (data -> mod )) {
911+ data -> tpoint = NULL ;
912+ data -> mod = NULL ;
913+ }
914+ }
915+ }
916+
900917static void __find_tracepoint_cb (struct tracepoint * tp , void * priv )
901918{
902919 struct __find_tracepoint_cb_data * data = priv ;
@@ -905,14 +922,28 @@ static void __find_tracepoint_cb(struct tracepoint *tp, void *priv)
905922 data -> tpoint = tp ;
906923}
907924
908- static struct tracepoint * find_tracepoint (const char * tp_name )
925+ /*
926+ * Find a tracepoint from kernel and module. If the tracepoint is in a module,
927+ * this increments the module refcount to prevent unloading until the
928+ * trace_fprobe is registered to the list. After registering the trace_fprobe
929+ * on the trace_fprobe list, the module refcount is decremented because
930+ * tracepoint_probe_module_cb will handle it.
931+ */
932+ static struct tracepoint * find_tracepoint (const char * tp_name ,
933+ struct module * * tp_mod )
909934{
910935 struct __find_tracepoint_cb_data data = {
911936 .tp_name = tp_name ,
937+ .mod = NULL ,
912938 };
913939
914940 for_each_kernel_tracepoint (__find_tracepoint_cb , & data );
915941
942+ if (!data .tpoint && IS_ENABLED (CONFIG_MODULES )) {
943+ for_each_module_tracepoint (__find_tracepoint_module_cb , & data );
944+ * tp_mod = data .mod ;
945+ }
946+
916947 return data .tpoint ;
917948}
918949
@@ -996,6 +1027,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
9961027 char abuf [MAX_BTF_ARGS_LEN ];
9971028 char * dbuf = NULL ;
9981029 bool is_tracepoint = false;
1030+ struct module * tp_mod = NULL ;
9991031 struct tracepoint * tpoint = NULL ;
10001032 struct traceprobe_parse_context ctx = {
10011033 .flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE ,
@@ -1080,7 +1112,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
10801112
10811113 if (is_tracepoint ) {
10821114 ctx .flags |= TPARG_FL_TPOINT ;
1083- tpoint = find_tracepoint (symbol );
1115+ tpoint = find_tracepoint (symbol , & tp_mod );
10841116 if (!tpoint ) {
10851117 trace_probe_log_set_index (1 );
10861118 trace_probe_log_err (0 , NO_TRACEPOINT );
@@ -1110,19 +1142,15 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11101142 goto out ;
11111143
11121144 /* setup a probe */
1113- tf = alloc_trace_fprobe (group , event , symbol , tpoint , maxactive ,
1114- argc , is_return );
1145+ tf = alloc_trace_fprobe (group , event , symbol , tpoint , tp_mod ,
1146+ maxactive , argc , is_return );
11151147 if (IS_ERR (tf )) {
11161148 ret = PTR_ERR (tf );
11171149 /* This must return -ENOMEM, else there is a bug */
11181150 WARN_ON_ONCE (ret != - ENOMEM );
11191151 goto out ; /* We know tf is not allocated */
11201152 }
11211153
1122- if (is_tracepoint )
1123- tf -> mod = __module_text_address (
1124- (unsigned long )tf -> tpoint -> probestub );
1125-
11261154 /* parse arguments */
11271155 for (i = 0 ; i < argc && i < MAX_TRACE_ARGS ; i ++ ) {
11281156 trace_probe_log_set_index (i + 2 );
@@ -1155,6 +1183,8 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11551183 }
11561184
11571185out :
1186+ if (tp_mod )
1187+ module_put (tp_mod );
11581188 traceprobe_finish_parse (& ctx );
11591189 trace_probe_log_clear ();
11601190 kfree (new_argv );
0 commit comments