21
21
#define FPROBE_EVENT_SYSTEM "fprobes"
22
22
#define TRACEPOINT_EVENT_SYSTEM "tracepoints"
23
23
#define RETHOOK_MAXACTIVE_MAX 4096
24
+ #define TRACEPOINT_STUB ERR_PTR(-ENOENT)
24
25
25
26
static int trace_fprobe_create (const char * raw_command );
26
27
static int trace_fprobe_show (struct seq_file * m , struct dyn_event * ev );
@@ -674,6 +675,24 @@ static int unregister_fprobe_event(struct trace_fprobe *tf)
674
675
return trace_probe_unregister_event_call (& tf -> tp );
675
676
}
676
677
678
+ static int __regsiter_tracepoint_fprobe (struct trace_fprobe * tf )
679
+ {
680
+ struct tracepoint * tpoint = tf -> tpoint ;
681
+ unsigned long ip = (unsigned long )tpoint -> probestub ;
682
+ int ret ;
683
+
684
+ /*
685
+ * Here, we do 2 steps to enable fprobe on a tracepoint.
686
+ * At first, put __probestub_##TP function on the tracepoint
687
+ * and put a fprobe on the stub function.
688
+ */
689
+ ret = tracepoint_probe_register_prio_may_exist (tpoint ,
690
+ tpoint -> probestub , NULL , 0 );
691
+ if (ret < 0 )
692
+ return ret ;
693
+ return register_fprobe_ips (& tf -> fp , & ip , 1 );
694
+ }
695
+
677
696
/* Internal register function - just handle fprobe and flags */
678
697
static int __register_trace_fprobe (struct trace_fprobe * tf )
679
698
{
@@ -700,18 +719,12 @@ static int __register_trace_fprobe(struct trace_fprobe *tf)
700
719
tf -> fp .flags |= FPROBE_FL_DISABLED ;
701
720
702
721
if (trace_fprobe_is_tracepoint (tf )) {
703
- struct tracepoint * tpoint = tf -> tpoint ;
704
- unsigned long ip = (unsigned long )tpoint -> probestub ;
705
- /*
706
- * Here, we do 2 steps to enable fprobe on a tracepoint.
707
- * At first, put __probestub_##TP function on the tracepoint
708
- * and put a fprobe on the stub function.
709
- */
710
- ret = tracepoint_probe_register_prio_may_exist (tpoint ,
711
- tpoint -> probestub , NULL , 0 );
712
- if (ret < 0 )
713
- return ret ;
714
- return register_fprobe_ips (& tf -> fp , & ip , 1 );
722
+
723
+ /* This tracepoint is not loaded yet */
724
+ if (tf -> tpoint == TRACEPOINT_STUB )
725
+ return 0 ;
726
+
727
+ return __regsiter_tracepoint_fprobe (tf );
715
728
}
716
729
717
730
/* TODO: handle filter, nofilter or symbol list */
@@ -864,36 +877,6 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
864
877
return ret ;
865
878
}
866
879
867
- #ifdef CONFIG_MODULES
868
- static int __tracepoint_probe_module_cb (struct notifier_block * self ,
869
- unsigned long val , void * data )
870
- {
871
- struct tp_module * tp_mod = data ;
872
- struct trace_fprobe * tf ;
873
- struct dyn_event * pos ;
874
-
875
- if (val != MODULE_STATE_GOING )
876
- return NOTIFY_DONE ;
877
-
878
- mutex_lock (& event_mutex );
879
- for_each_trace_fprobe (tf , pos ) {
880
- if (tp_mod -> mod == tf -> mod ) {
881
- tracepoint_probe_unregister (tf -> tpoint ,
882
- tf -> tpoint -> probestub , NULL );
883
- tf -> tpoint = NULL ;
884
- tf -> mod = NULL ;
885
- }
886
- }
887
- mutex_unlock (& event_mutex );
888
-
889
- return NOTIFY_DONE ;
890
- }
891
-
892
- static struct notifier_block tracepoint_module_nb = {
893
- .notifier_call = __tracepoint_probe_module_cb ,
894
- };
895
- #endif /* CONFIG_MODULES */
896
-
897
880
struct __find_tracepoint_cb_data {
898
881
const char * tp_name ;
899
882
struct tracepoint * tpoint ;
@@ -906,10 +889,12 @@ static void __find_tracepoint_module_cb(struct tracepoint *tp, struct module *mo
906
889
907
890
if (!data -> tpoint && !strcmp (data -> tp_name , tp -> name )) {
908
891
data -> tpoint = tp ;
909
- data -> mod = mod ;
910
- if (!try_module_get (data -> mod )) {
911
- data -> tpoint = NULL ;
912
- data -> mod = NULL ;
892
+ if (!data -> mod ) {
893
+ data -> mod = mod ;
894
+ if (!try_module_get (data -> mod )) {
895
+ data -> tpoint = NULL ;
896
+ data -> mod = NULL ;
897
+ }
913
898
}
914
899
}
915
900
}
@@ -947,6 +932,67 @@ static struct tracepoint *find_tracepoint(const char *tp_name,
947
932
return data .tpoint ;
948
933
}
949
934
935
+ #ifdef CONFIG_MODULES
936
+ static void reenable_trace_fprobe (struct trace_fprobe * tf )
937
+ {
938
+ struct trace_probe * tp = & tf -> tp ;
939
+
940
+ list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
941
+ __enable_trace_fprobe (tf );
942
+ }
943
+ }
944
+
945
+ static struct tracepoint * find_tracepoint_in_module (struct module * mod ,
946
+ const char * tp_name )
947
+ {
948
+ struct __find_tracepoint_cb_data data = {
949
+ .tp_name = tp_name ,
950
+ .mod = mod ,
951
+ };
952
+
953
+ for_each_tracepoint_in_module (mod , __find_tracepoint_module_cb , & data );
954
+ return data .tpoint ;
955
+ }
956
+
957
+ static int __tracepoint_probe_module_cb (struct notifier_block * self ,
958
+ unsigned long val , void * data )
959
+ {
960
+ struct tp_module * tp_mod = data ;
961
+ struct tracepoint * tpoint ;
962
+ struct trace_fprobe * tf ;
963
+ struct dyn_event * pos ;
964
+
965
+ if (val != MODULE_STATE_GOING && val != MODULE_STATE_COMING )
966
+ return NOTIFY_DONE ;
967
+
968
+ mutex_lock (& event_mutex );
969
+ for_each_trace_fprobe (tf , pos ) {
970
+ if (val == MODULE_STATE_COMING && tf -> tpoint == TRACEPOINT_STUB ) {
971
+ tpoint = find_tracepoint_in_module (tp_mod -> mod , tf -> symbol );
972
+ if (tpoint ) {
973
+ tf -> tpoint = tpoint ;
974
+ tf -> mod = tp_mod -> mod ;
975
+ if (!WARN_ON_ONCE (__regsiter_tracepoint_fprobe (tf )) &&
976
+ trace_probe_is_enabled (& tf -> tp ))
977
+ reenable_trace_fprobe (tf );
978
+ }
979
+ } else if (val == MODULE_STATE_GOING && tp_mod -> mod == tf -> mod ) {
980
+ tracepoint_probe_unregister (tf -> tpoint ,
981
+ tf -> tpoint -> probestub , NULL );
982
+ tf -> tpoint = NULL ;
983
+ tf -> mod = NULL ;
984
+ }
985
+ }
986
+ mutex_unlock (& event_mutex );
987
+
988
+ return NOTIFY_DONE ;
989
+ }
990
+
991
+ static struct notifier_block tracepoint_module_nb = {
992
+ .notifier_call = __tracepoint_probe_module_cb ,
993
+ };
994
+ #endif /* CONFIG_MODULES */
995
+
950
996
static int parse_symbol_and_return (int argc , const char * argv [],
951
997
char * * symbol , bool * is_return ,
952
998
bool is_tracepoint )
@@ -1113,14 +1159,19 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1113
1159
if (is_tracepoint ) {
1114
1160
ctx .flags |= TPARG_FL_TPOINT ;
1115
1161
tpoint = find_tracepoint (symbol , & tp_mod );
1116
- if (!tpoint ) {
1162
+ if (tpoint ) {
1163
+ ctx .funcname = kallsyms_lookup (
1164
+ (unsigned long )tpoint -> probestub ,
1165
+ NULL , NULL , NULL , sbuf );
1166
+ } else if (IS_ENABLED (CONFIG_MODULES )) {
1167
+ /* This *may* be loaded afterwards */
1168
+ tpoint = TRACEPOINT_STUB ;
1169
+ ctx .funcname = symbol ;
1170
+ } else {
1117
1171
trace_probe_log_set_index (1 );
1118
1172
trace_probe_log_err (0 , NO_TRACEPOINT );
1119
1173
goto parse_error ;
1120
1174
}
1121
- ctx .funcname = kallsyms_lookup (
1122
- (unsigned long )tpoint -> probestub ,
1123
- NULL , NULL , NULL , sbuf );
1124
1175
} else
1125
1176
ctx .funcname = symbol ;
1126
1177
0 commit comments