@@ -600,98 +600,6 @@ static struct trace_fprobe *find_trace_fprobe(const char *event,
600600 return NULL ;
601601}
602602
603- static inline int __enable_trace_fprobe (struct trace_fprobe * tf )
604- {
605- if (trace_fprobe_is_registered (tf ))
606- enable_fprobe (& tf -> fp );
607-
608- return 0 ;
609- }
610-
611- static void __disable_trace_fprobe (struct trace_probe * tp )
612- {
613- struct trace_fprobe * tf ;
614-
615- list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
616- if (!trace_fprobe_is_registered (tf ))
617- continue ;
618- disable_fprobe (& tf -> fp );
619- }
620- }
621-
622- /*
623- * Enable trace_probe
624- * if the file is NULL, enable "perf" handler, or enable "trace" handler.
625- */
626- static int enable_trace_fprobe (struct trace_event_call * call ,
627- struct trace_event_file * file )
628- {
629- struct trace_probe * tp ;
630- struct trace_fprobe * tf ;
631- bool enabled ;
632- int ret = 0 ;
633-
634- tp = trace_probe_primary_from_call (call );
635- if (WARN_ON_ONCE (!tp ))
636- return - ENODEV ;
637- enabled = trace_probe_is_enabled (tp );
638-
639- /* This also changes "enabled" state */
640- if (file ) {
641- ret = trace_probe_add_file (tp , file );
642- if (ret )
643- return ret ;
644- } else
645- trace_probe_set_flag (tp , TP_FLAG_PROFILE );
646-
647- if (!enabled ) {
648- list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
649- /* TODO: check the fprobe is gone */
650- __enable_trace_fprobe (tf );
651- }
652- }
653-
654- return 0 ;
655- }
656-
657- /*
658- * Disable trace_probe
659- * if the file is NULL, disable "perf" handler, or disable "trace" handler.
660- */
661- static int disable_trace_fprobe (struct trace_event_call * call ,
662- struct trace_event_file * file )
663- {
664- struct trace_probe * tp ;
665-
666- tp = trace_probe_primary_from_call (call );
667- if (WARN_ON_ONCE (!tp ))
668- return - ENODEV ;
669-
670- if (file ) {
671- if (!trace_probe_get_file_link (tp , file ))
672- return - ENOENT ;
673- if (!trace_probe_has_single_file (tp ))
674- goto out ;
675- trace_probe_clear_flag (tp , TP_FLAG_TRACE );
676- } else
677- trace_probe_clear_flag (tp , TP_FLAG_PROFILE );
678-
679- if (!trace_probe_is_enabled (tp ))
680- __disable_trace_fprobe (tp );
681-
682- out :
683- if (file )
684- /*
685- * Synchronization is done in below function. For perf event,
686- * file == NULL and perf_trace_event_unreg() calls
687- * tracepoint_synchronize_unregister() to ensure synchronize
688- * event. We don't need to care about it.
689- */
690- trace_probe_remove_file (tp , file );
691-
692- return 0 ;
693- }
694-
695603/* Event entry printers */
696604static enum print_line_t
697605print_fentry_event (struct trace_iterator * iter , int flags ,
@@ -851,6 +759,29 @@ static int __regsiter_tracepoint_fprobe(struct trace_fprobe *tf)
851759 return register_fprobe_ips (& tf -> fp , & ip , 1 );
852760}
853761
762+ /* Returns an error if the target function is not available, or 0 */
763+ static int trace_fprobe_verify_target (struct trace_fprobe * tf )
764+ {
765+ int ret ;
766+
767+ if (trace_fprobe_is_tracepoint (tf )) {
768+
769+ /* This tracepoint is not loaded yet */
770+ if (!tracepoint_user_is_registered (tf -> tuser ))
771+ return 0 ;
772+
773+ /* We assume all stab function is tracable. */
774+ return tracepoint_user_ip (tf -> tuser ) ? 0 : - ENOENT ;
775+ }
776+
777+ /*
778+ * Note: since we don't lock the module, even if this succeeded,
779+ * register_fprobe() later can fail.
780+ */
781+ ret = fprobe_count_ips_from_filter (tf -> symbol , NULL );
782+ return (ret < 0 ) ? ret : 0 ;
783+ }
784+
854785/* Internal register function - just handle fprobe and flags */
855786static int __register_trace_fprobe (struct trace_fprobe * tf )
856787{
@@ -870,11 +801,7 @@ static int __register_trace_fprobe(struct trace_fprobe *tf)
870801 return ret ;
871802 }
872803
873- /* Set/clear disabled flag according to tp->flag */
874- if (trace_probe_is_enabled (& tf -> tp ))
875- tf -> fp .flags &= ~FPROBE_FL_DISABLED ;
876- else
877- tf -> fp .flags |= FPROBE_FL_DISABLED ;
804+ tf -> fp .flags &= ~FPROBE_FL_DISABLED ;
878805
879806 if (trace_fprobe_is_tracepoint (tf )) {
880807
@@ -895,10 +822,10 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf)
895822 if (trace_fprobe_is_registered (tf )) {
896823 unregister_fprobe (& tf -> fp );
897824 memset (& tf -> fp , 0 , sizeof (tf -> fp ));
898- if ( trace_fprobe_is_tracepoint ( tf )) {
899- tracepoint_user_put ( tf -> tuser );
900- tf -> tuser = NULL ;
901- }
825+ }
826+ if ( trace_fprobe_is_tracepoint ( tf )) {
827+ tracepoint_user_put ( tf -> tuser ) ;
828+ tf -> tuser = NULL ;
902829 }
903830}
904831
@@ -958,7 +885,7 @@ static bool trace_fprobe_has_same_fprobe(struct trace_fprobe *orig,
958885 return false;
959886}
960887
961- static int append_trace_fprobe (struct trace_fprobe * tf , struct trace_fprobe * to )
888+ static int append_trace_fprobe_event (struct trace_fprobe * tf , struct trace_fprobe * to )
962889{
963890 int ret ;
964891
@@ -986,7 +913,7 @@ static int append_trace_fprobe(struct trace_fprobe *tf, struct trace_fprobe *to)
986913 if (ret )
987914 return ret ;
988915
989- ret = __register_trace_fprobe (tf );
916+ ret = trace_fprobe_verify_target (tf );
990917 if (ret )
991918 trace_probe_unlink (& tf -> tp );
992919 else
@@ -995,8 +922,8 @@ static int append_trace_fprobe(struct trace_fprobe *tf, struct trace_fprobe *to)
995922 return ret ;
996923}
997924
998- /* Register a trace_probe and probe_event */
999- static int register_trace_fprobe (struct trace_fprobe * tf )
925+ /* Register a trace_probe and probe_event, and check the fprobe is available. */
926+ static int register_trace_fprobe_event (struct trace_fprobe * tf )
1000927{
1001928 struct trace_fprobe * old_tf ;
1002929 int ret ;
@@ -1006,7 +933,7 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
1006933 old_tf = find_trace_fprobe (trace_probe_name (& tf -> tp ),
1007934 trace_probe_group_name (& tf -> tp ));
1008935 if (old_tf )
1009- return append_trace_fprobe (tf , old_tf );
936+ return append_trace_fprobe_event (tf , old_tf );
1010937
1011938 /* Register new event */
1012939 ret = register_fprobe_event (tf );
@@ -1019,8 +946,8 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
1019946 return ret ;
1020947 }
1021948
1022- /* Register fprobe */
1023- ret = __register_trace_fprobe (tf );
949+ /* Verify fprobe is sane. */
950+ ret = trace_fprobe_verify_target (tf );
1024951 if (ret < 0 )
1025952 unregister_fprobe_event (tf );
1026953 else
@@ -1084,15 +1011,6 @@ static struct tracepoint *find_tracepoint(const char *tp_name,
10841011}
10851012
10861013#ifdef CONFIG_MODULES
1087- static void reenable_trace_fprobe (struct trace_fprobe * tf )
1088- {
1089- struct trace_probe * tp = & tf -> tp ;
1090-
1091- list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
1092- __enable_trace_fprobe (tf );
1093- }
1094- }
1095-
10961014/*
10971015 * Find a tracepoint from specified module. In this case, this does not get the
10981016 * module's refcount. The caller must ensure the module is not freed.
@@ -1146,9 +1064,8 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self,
11461064 }
11471065
11481066 /* Finally enable fprobe on this module. */
1149- if (!WARN_ON_ONCE (__regsiter_tracepoint_fprobe (tf )) &&
1150- trace_probe_is_enabled (& tf -> tp ))
1151- reenable_trace_fprobe (tf );
1067+ if (trace_probe_is_enabled (& tf -> tp ) && !trace_fprobe_is_registered (tf ))
1068+ WARN_ON_ONCE (__regsiter_tracepoint_fprobe (tf ));
11521069 } else if (val == MODULE_STATE_GOING ) {
11531070 tuser = tf -> tuser ;
11541071 /* Unregister all tracepoint_user in this module. */
@@ -1397,7 +1314,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],
13971314 if (ret < 0 )
13981315 return ret ;
13991316
1400- ret = register_trace_fprobe (tf );
1317+ ret = register_trace_fprobe_event (tf );
14011318 if (ret ) {
14021319 trace_probe_log_set_index (1 );
14031320 if (ret == - EILSEQ )
@@ -1466,6 +1383,84 @@ static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev)
14661383 return 0 ;
14671384}
14681385
1386+ /*
1387+ * Enable trace_probe
1388+ * if the file is NULL, enable "perf" handler, or enable "trace" handler.
1389+ */
1390+ static int enable_trace_fprobe (struct trace_event_call * call ,
1391+ struct trace_event_file * file )
1392+ {
1393+ struct trace_probe * tp ;
1394+ struct trace_fprobe * tf ;
1395+ bool enabled ;
1396+ int ret = 0 ;
1397+
1398+ tp = trace_probe_primary_from_call (call );
1399+ if (WARN_ON_ONCE (!tp ))
1400+ return - ENODEV ;
1401+ enabled = trace_probe_is_enabled (tp );
1402+
1403+ /* This also changes "enabled" state */
1404+ if (file ) {
1405+ ret = trace_probe_add_file (tp , file );
1406+ if (ret )
1407+ return ret ;
1408+ } else
1409+ trace_probe_set_flag (tp , TP_FLAG_PROFILE );
1410+
1411+ if (!enabled ) {
1412+ list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
1413+ ret = __register_trace_fprobe (tf );
1414+ if (ret < 0 )
1415+ return ret ;
1416+ }
1417+ }
1418+
1419+ return 0 ;
1420+ }
1421+
1422+ /*
1423+ * Disable trace_probe
1424+ * if the file is NULL, disable "perf" handler, or disable "trace" handler.
1425+ */
1426+ static int disable_trace_fprobe (struct trace_event_call * call ,
1427+ struct trace_event_file * file )
1428+ {
1429+ struct trace_fprobe * tf ;
1430+ struct trace_probe * tp ;
1431+
1432+ tp = trace_probe_primary_from_call (call );
1433+ if (WARN_ON_ONCE (!tp ))
1434+ return - ENODEV ;
1435+
1436+ if (file ) {
1437+ if (!trace_probe_get_file_link (tp , file ))
1438+ return - ENOENT ;
1439+ if (!trace_probe_has_single_file (tp ))
1440+ goto out ;
1441+ trace_probe_clear_flag (tp , TP_FLAG_TRACE );
1442+ } else
1443+ trace_probe_clear_flag (tp , TP_FLAG_PROFILE );
1444+
1445+ if (!trace_probe_is_enabled (tp )) {
1446+ list_for_each_entry (tf , trace_probe_probe_list (tp ), tp .list ) {
1447+ unregister_fprobe (& tf -> fp );
1448+ }
1449+ }
1450+
1451+ out :
1452+ if (file )
1453+ /*
1454+ * Synchronization is done in below function. For perf event,
1455+ * file == NULL and perf_trace_event_unreg() calls
1456+ * tracepoint_synchronize_unregister() to ensure synchronize
1457+ * event. We don't need to care about it.
1458+ */
1459+ trace_probe_remove_file (tp , file );
1460+
1461+ return 0 ;
1462+ }
1463+
14691464/*
14701465 * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex.
14711466 */
0 commit comments