@@ -385,6 +385,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
385
385
const char * event ,
386
386
const char * symbol ,
387
387
struct tracepoint * tpoint ,
388
+ struct module * mod ,
388
389
int maxactive ,
389
390
int nargs , bool is_return )
390
391
{
@@ -405,6 +406,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
405
406
tf -> fp .entry_handler = fentry_dispatcher ;
406
407
407
408
tf -> tpoint = tpoint ;
409
+ tf -> mod = mod ;
408
410
tf -> fp .nr_maxactive = maxactive ;
409
411
410
412
ret = trace_probe_init (& tf -> tp , event , group , false, nargs );
@@ -895,8 +897,23 @@ static struct notifier_block tracepoint_module_nb = {
895
897
struct __find_tracepoint_cb_data {
896
898
const char * tp_name ;
897
899
struct tracepoint * tpoint ;
900
+ struct module * mod ;
898
901
};
899
902
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
+
900
917
static void __find_tracepoint_cb (struct tracepoint * tp , void * priv )
901
918
{
902
919
struct __find_tracepoint_cb_data * data = priv ;
@@ -905,14 +922,28 @@ static void __find_tracepoint_cb(struct tracepoint *tp, void *priv)
905
922
data -> tpoint = tp ;
906
923
}
907
924
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 )
909
934
{
910
935
struct __find_tracepoint_cb_data data = {
911
936
.tp_name = tp_name ,
937
+ .mod = NULL ,
912
938
};
913
939
914
940
for_each_kernel_tracepoint (__find_tracepoint_cb , & data );
915
941
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
+
916
947
return data .tpoint ;
917
948
}
918
949
@@ -996,6 +1027,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
996
1027
char abuf [MAX_BTF_ARGS_LEN ];
997
1028
char * dbuf = NULL ;
998
1029
bool is_tracepoint = false;
1030
+ struct module * tp_mod = NULL ;
999
1031
struct tracepoint * tpoint = NULL ;
1000
1032
struct traceprobe_parse_context ctx = {
1001
1033
.flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE ,
@@ -1080,7 +1112,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1080
1112
1081
1113
if (is_tracepoint ) {
1082
1114
ctx .flags |= TPARG_FL_TPOINT ;
1083
- tpoint = find_tracepoint (symbol );
1115
+ tpoint = find_tracepoint (symbol , & tp_mod );
1084
1116
if (!tpoint ) {
1085
1117
trace_probe_log_set_index (1 );
1086
1118
trace_probe_log_err (0 , NO_TRACEPOINT );
@@ -1110,19 +1142,15 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1110
1142
goto out ;
1111
1143
1112
1144
/* 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 );
1115
1147
if (IS_ERR (tf )) {
1116
1148
ret = PTR_ERR (tf );
1117
1149
/* This must return -ENOMEM, else there is a bug */
1118
1150
WARN_ON_ONCE (ret != - ENOMEM );
1119
1151
goto out ; /* We know tf is not allocated */
1120
1152
}
1121
1153
1122
- if (is_tracepoint )
1123
- tf -> mod = __module_text_address (
1124
- (unsigned long )tf -> tpoint -> probestub );
1125
-
1126
1154
/* parse arguments */
1127
1155
for (i = 0 ; i < argc && i < MAX_TRACE_ARGS ; i ++ ) {
1128
1156
trace_probe_log_set_index (i + 2 );
@@ -1155,6 +1183,8 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1155
1183
}
1156
1184
1157
1185
out :
1186
+ if (tp_mod )
1187
+ module_put (tp_mod );
1158
1188
traceprobe_finish_parse (& ctx );
1159
1189
trace_probe_log_clear ();
1160
1190
kfree (new_argv );
0 commit comments