@@ -26,6 +26,9 @@ struct trace_eprobe {
26
26
/* tracepoint event */
27
27
const char * event_name ;
28
28
29
+ /* filter string for the tracepoint */
30
+ char * filter_str ;
31
+
29
32
struct trace_event_call * event ;
30
33
31
34
struct dyn_event devent ;
@@ -664,14 +667,15 @@ static struct event_trigger_data *
664
667
new_eprobe_trigger (struct trace_eprobe * ep , struct trace_event_file * file )
665
668
{
666
669
struct event_trigger_data * trigger ;
670
+ struct event_filter * filter = NULL ;
667
671
struct eprobe_data * edata ;
672
+ int ret ;
668
673
669
674
edata = kzalloc (sizeof (* edata ), GFP_KERNEL );
670
675
trigger = kzalloc (sizeof (* trigger ), GFP_KERNEL );
671
676
if (!trigger || !edata ) {
672
- kfree (edata );
673
- kfree (trigger );
674
- return ERR_PTR (- ENOMEM );
677
+ ret = - ENOMEM ;
678
+ goto error ;
675
679
}
676
680
677
681
trigger -> flags = EVENT_TRIGGER_FL_PROBE ;
@@ -686,13 +690,25 @@ new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file)
686
690
trigger -> cmd_ops = & event_trigger_cmd ;
687
691
688
692
INIT_LIST_HEAD (& trigger -> list );
689
- RCU_INIT_POINTER (trigger -> filter , NULL );
693
+
694
+ if (ep -> filter_str ) {
695
+ ret = create_event_filter (file -> tr , file -> event_call ,
696
+ ep -> filter_str , false, & filter );
697
+ if (ret )
698
+ goto error ;
699
+ }
700
+ RCU_INIT_POINTER (trigger -> filter , filter );
690
701
691
702
edata -> file = file ;
692
703
edata -> ep = ep ;
693
704
trigger -> private_data = edata ;
694
705
695
706
return trigger ;
707
+ error :
708
+ free_event_filter (filter );
709
+ kfree (edata );
710
+ kfree (trigger );
711
+ return ERR_PTR (ret );
696
712
}
697
713
698
714
static int enable_eprobe (struct trace_eprobe * ep ,
@@ -726,6 +742,7 @@ static int disable_eprobe(struct trace_eprobe *ep,
726
742
{
727
743
struct event_trigger_data * trigger = NULL , * iter ;
728
744
struct trace_event_file * file ;
745
+ struct event_filter * filter ;
729
746
struct eprobe_data * edata ;
730
747
731
748
file = find_event_file (tr , ep -> event_system , ep -> event_name );
@@ -752,6 +769,10 @@ static int disable_eprobe(struct trace_eprobe *ep,
752
769
/* Make sure nothing is using the edata or trigger */
753
770
tracepoint_synchronize_unregister ();
754
771
772
+ filter = rcu_access_pointer (trigger -> filter );
773
+
774
+ if (filter )
775
+ free_event_filter (filter );
755
776
kfree (edata );
756
777
kfree (trigger );
757
778
@@ -927,12 +948,62 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[
927
948
return ret ;
928
949
}
929
950
951
+ static int trace_eprobe_parse_filter (struct trace_eprobe * ep , int argc , const char * argv [])
952
+ {
953
+ struct event_filter * dummy ;
954
+ int i , ret , len = 0 ;
955
+ char * p ;
956
+
957
+ if (argc == 0 ) {
958
+ trace_probe_log_err (0 , NO_EP_FILTER );
959
+ return - EINVAL ;
960
+ }
961
+
962
+ /* Recover the filter string */
963
+ for (i = 0 ; i < argc ; i ++ )
964
+ len += strlen (argv [i ]) + 1 ;
965
+
966
+ ep -> filter_str = kzalloc (len , GFP_KERNEL );
967
+ if (!ep -> filter_str )
968
+ return - ENOMEM ;
969
+
970
+ p = ep -> filter_str ;
971
+ for (i = 0 ; i < argc ; i ++ ) {
972
+ ret = snprintf (p , len , "%s " , argv [i ]);
973
+ if (ret < 0 )
974
+ goto error ;
975
+ if (ret > len ) {
976
+ ret = - E2BIG ;
977
+ goto error ;
978
+ }
979
+ p += ret ;
980
+ len -= ret ;
981
+ }
982
+ p [-1 ] = '\0' ;
983
+
984
+ /*
985
+ * Ensure the filter string can be parsed correctly. Note, this
986
+ * filter string is for the original event, not for the eprobe.
987
+ */
988
+ ret = create_event_filter (top_trace_array (), ep -> event , ep -> filter_str ,
989
+ true, & dummy );
990
+ free_event_filter (dummy );
991
+ if (ret )
992
+ goto error ;
993
+
994
+ return 0 ;
995
+ error :
996
+ kfree (ep -> filter_str );
997
+ ep -> filter_str = NULL ;
998
+ return ret ;
999
+ }
1000
+
930
1001
static int __trace_eprobe_create (int argc , const char * argv [])
931
1002
{
932
1003
/*
933
1004
* Argument syntax:
934
- * e[:[GRP/][ENAME]] SYSTEM.EVENT [FETCHARGS]
935
- * Fetch args:
1005
+ * e[:[GRP/][ENAME]] SYSTEM.EVENT [FETCHARGS] [if FILTER]
1006
+ * Fetch args (no space) :
936
1007
* <name>=$<field>[:TYPE]
937
1008
*/
938
1009
const char * event = NULL , * group = EPROBE_EVENT_SYSTEM ;
@@ -942,8 +1013,8 @@ static int __trace_eprobe_create(int argc, const char *argv[])
942
1013
char buf1 [MAX_EVENT_NAME_LEN ];
943
1014
char buf2 [MAX_EVENT_NAME_LEN ];
944
1015
char gbuf [MAX_EVENT_NAME_LEN ];
945
- int ret = 0 ;
946
- int i ;
1016
+ int ret = 0 , filter_idx = 0 ;
1017
+ int i , filter_cnt ;
947
1018
948
1019
if (argc < 2 || argv [0 ][0 ] != 'e' )
949
1020
return - ECANCELED ;
@@ -973,6 +1044,15 @@ static int __trace_eprobe_create(int argc, const char *argv[])
973
1044
event = buf1 ;
974
1045
}
975
1046
1047
+ for (i = 2 ; i < argc ; i ++ ) {
1048
+ if (!strcmp (argv [i ], "if" )) {
1049
+ filter_idx = i + 1 ;
1050
+ filter_cnt = argc - filter_idx ;
1051
+ argc = i ;
1052
+ break ;
1053
+ }
1054
+ }
1055
+
976
1056
mutex_lock (& event_mutex );
977
1057
event_call = find_and_get_event (sys_name , sys_event );
978
1058
ep = alloc_event_probe (group , event , event_call , argc - 2 );
@@ -988,6 +1068,14 @@ static int __trace_eprobe_create(int argc, const char *argv[])
988
1068
goto error ;
989
1069
}
990
1070
1071
+ if (filter_idx ) {
1072
+ trace_probe_log_set_index (filter_idx );
1073
+ ret = trace_eprobe_parse_filter (ep , filter_cnt , argv + filter_idx );
1074
+ if (ret )
1075
+ goto parse_error ;
1076
+ } else
1077
+ ep -> filter_str = NULL ;
1078
+
991
1079
argc -= 2 ; argv += 2 ;
992
1080
/* parse arguments */
993
1081
for (i = 0 ; i < argc && i < MAX_TRACE_ARGS ; i ++ ) {
0 commit comments