2121#define FPROBE_EVENT_SYSTEM "fprobes"
2222#define TRACEPOINT_EVENT_SYSTEM "tracepoints"
2323#define RETHOOK_MAXACTIVE_MAX 4096
24+ #define TRACEPOINT_STUB ERR_PTR(-ENOENT)
2425
2526static int trace_fprobe_create (const char * raw_command );
2627static 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)
674675 return trace_probe_unregister_event_call (& tf -> tp );
675676}
676677
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+
677696/* Internal register function - just handle fprobe and flags */
678697static int __register_trace_fprobe (struct trace_fprobe * tf )
679698{
@@ -700,18 +719,12 @@ static int __register_trace_fprobe(struct trace_fprobe *tf)
700719 tf -> fp .flags |= FPROBE_FL_DISABLED ;
701720
702721 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 );
715728 }
716729
717730 /* TODO: handle filter, nofilter or symbol list */
@@ -864,36 +877,6 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
864877 return ret ;
865878}
866879
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-
897880struct __find_tracepoint_cb_data {
898881 const char * tp_name ;
899882 struct tracepoint * tpoint ;
@@ -906,10 +889,12 @@ static void __find_tracepoint_module_cb(struct tracepoint *tp, struct module *mo
906889
907890 if (!data -> tpoint && !strcmp (data -> tp_name , tp -> name )) {
908891 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+ }
913898 }
914899 }
915900}
@@ -947,6 +932,67 @@ static struct tracepoint *find_tracepoint(const char *tp_name,
947932 return data .tpoint ;
948933}
949934
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+
950996static int parse_symbol_and_return (int argc , const char * argv [],
951997 char * * symbol , bool * is_return ,
952998 bool is_tracepoint )
@@ -1113,14 +1159,19 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11131159 if (is_tracepoint ) {
11141160 ctx .flags |= TPARG_FL_TPOINT ;
11151161 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 {
11171171 trace_probe_log_set_index (1 );
11181172 trace_probe_log_err (0 , NO_TRACEPOINT );
11191173 goto parse_error ;
11201174 }
1121- ctx .funcname = kallsyms_lookup (
1122- (unsigned long )tpoint -> probestub ,
1123- NULL , NULL , NULL , sbuf );
11241175 } else
11251176 ctx .funcname = symbol ;
11261177
0 commit comments