@@ -26,6 +26,9 @@ struct trace_eprobe {
2626 /* tracepoint event */
2727 const char * event_name ;
2828
29+ /* filter string for the tracepoint */
30+ char * filter_str ;
31+
2932 struct trace_event_call * event ;
3033
3134 struct dyn_event devent ;
@@ -664,14 +667,15 @@ static struct event_trigger_data *
664667new_eprobe_trigger (struct trace_eprobe * ep , struct trace_event_file * file )
665668{
666669 struct event_trigger_data * trigger ;
670+ struct event_filter * filter = NULL ;
667671 struct eprobe_data * edata ;
672+ int ret ;
668673
669674 edata = kzalloc (sizeof (* edata ), GFP_KERNEL );
670675 trigger = kzalloc (sizeof (* trigger ), GFP_KERNEL );
671676 if (!trigger || !edata ) {
672- kfree (edata );
673- kfree (trigger );
674- return ERR_PTR (- ENOMEM );
677+ ret = - ENOMEM ;
678+ goto error ;
675679 }
676680
677681 trigger -> flags = EVENT_TRIGGER_FL_PROBE ;
@@ -686,13 +690,25 @@ new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file)
686690 trigger -> cmd_ops = & event_trigger_cmd ;
687691
688692 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 );
690701
691702 edata -> file = file ;
692703 edata -> ep = ep ;
693704 trigger -> private_data = edata ;
694705
695706 return trigger ;
707+ error :
708+ free_event_filter (filter );
709+ kfree (edata );
710+ kfree (trigger );
711+ return ERR_PTR (ret );
696712}
697713
698714static int enable_eprobe (struct trace_eprobe * ep ,
@@ -726,6 +742,7 @@ static int disable_eprobe(struct trace_eprobe *ep,
726742{
727743 struct event_trigger_data * trigger = NULL , * iter ;
728744 struct trace_event_file * file ;
745+ struct event_filter * filter ;
729746 struct eprobe_data * edata ;
730747
731748 file = find_event_file (tr , ep -> event_system , ep -> event_name );
@@ -752,6 +769,10 @@ static int disable_eprobe(struct trace_eprobe *ep,
752769 /* Make sure nothing is using the edata or trigger */
753770 tracepoint_synchronize_unregister ();
754771
772+ filter = rcu_access_pointer (trigger -> filter );
773+
774+ if (filter )
775+ free_event_filter (filter );
755776 kfree (edata );
756777 kfree (trigger );
757778
@@ -927,12 +948,62 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[
927948 return ret ;
928949}
929950
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+
9301001static int __trace_eprobe_create (int argc , const char * argv [])
9311002{
9321003 /*
9331004 * 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) :
9361007 * <name>=$<field>[:TYPE]
9371008 */
9381009 const char * event = NULL , * group = EPROBE_EVENT_SYSTEM ;
@@ -942,8 +1013,8 @@ static int __trace_eprobe_create(int argc, const char *argv[])
9421013 char buf1 [MAX_EVENT_NAME_LEN ];
9431014 char buf2 [MAX_EVENT_NAME_LEN ];
9441015 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 ;
9471018
9481019 if (argc < 2 || argv [0 ][0 ] != 'e' )
9491020 return - ECANCELED ;
@@ -973,6 +1044,15 @@ static int __trace_eprobe_create(int argc, const char *argv[])
9731044 event = buf1 ;
9741045 }
9751046
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+
9761056 mutex_lock (& event_mutex );
9771057 event_call = find_and_get_event (sys_name , sys_event );
9781058 ep = alloc_event_probe (group , event , event_call , argc - 2 );
@@ -988,6 +1068,14 @@ static int __trace_eprobe_create(int argc, const char *argv[])
9881068 goto error ;
9891069 }
9901070
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+
9911079 argc -= 2 ; argv += 2 ;
9921080 /* parse arguments */
9931081 for (i = 0 ; i < argc && i < MAX_TRACE_ARGS ; i ++ ) {
0 commit comments