@@ -185,10 +185,15 @@ struct probe_arg {
185185 const char * name ;
186186};
187187
188+ /* Flags for trace_probe */
189+ #define TP_FLAG_TRACE 1
190+ #define TP_FLAG_PROFILE 2
191+
188192struct trace_probe {
189193 struct list_head list ;
190194 struct kretprobe rp ; /* Use rp.kp for kprobe use */
191195 unsigned long nhit ;
196+ unsigned int flags ; /* For TP_FLAG_* */
192197 const char * symbol ; /* symbol name */
193198 struct ftrace_event_call call ;
194199 struct trace_event event ;
@@ -200,10 +205,6 @@ struct trace_probe {
200205 (offsetof(struct trace_probe, args) + \
201206 (sizeof(struct probe_arg) * (n)))
202207
203- static int kprobe_trace_func (struct kprobe * kp , struct pt_regs * regs );
204- static int kretprobe_trace_func (struct kretprobe_instance * ri ,
205- struct pt_regs * regs );
206-
207208static __kprobes int probe_is_return (struct trace_probe * tp )
208209{
209210 return tp -> rp .handler != NULL ;
@@ -263,6 +264,10 @@ static void unregister_probe_event(struct trace_probe *tp);
263264static DEFINE_MUTEX (probe_lock );
264265static LIST_HEAD (probe_list );
265266
267+ static int kprobe_dispatcher (struct kprobe * kp , struct pt_regs * regs );
268+ static int kretprobe_dispatcher (struct kretprobe_instance * ri ,
269+ struct pt_regs * regs );
270+
266271/*
267272 * Allocate new trace_probe and initialize it (including kprobes).
268273 */
@@ -288,11 +293,10 @@ static struct trace_probe *alloc_trace_probe(const char *group,
288293 } else
289294 tp -> rp .kp .addr = addr ;
290295
291- /* Set handler here for checking whether this probe is return or not. */
292296 if (is_return )
293- tp -> rp .handler = kretprobe_trace_func ;
297+ tp -> rp .handler = kretprobe_dispatcher ;
294298 else
295- tp -> rp .kp .pre_handler = kprobe_trace_func ;
299+ tp -> rp .kp .pre_handler = kprobe_dispatcher ;
296300
297301 if (!event )
298302 goto error ;
@@ -379,6 +383,7 @@ static int register_trace_probe(struct trace_probe *tp)
379383 goto end ;
380384 }
381385
386+ tp -> flags = TP_FLAG_TRACE ;
382387 if (probe_is_return (tp ))
383388 ret = register_kretprobe (& tp -> rp );
384389 else
@@ -987,23 +992,24 @@ static int probe_event_enable(struct ftrace_event_call *call)
987992{
988993 struct trace_probe * tp = (struct trace_probe * )call -> data ;
989994
990- if ( probe_is_return ( tp )) {
991- tp -> rp . handler = kretprobe_trace_func ;
995+ tp -> flags |= TP_FLAG_TRACE ;
996+ if ( probe_is_return ( tp ))
992997 return enable_kretprobe (& tp -> rp );
993- } else {
994- tp -> rp .kp .pre_handler = kprobe_trace_func ;
998+ else
995999 return enable_kprobe (& tp -> rp .kp );
996- }
9971000}
9981001
9991002static void probe_event_disable (struct ftrace_event_call * call )
10001003{
10011004 struct trace_probe * tp = (struct trace_probe * )call -> data ;
10021005
1003- if (probe_is_return (tp ))
1004- disable_kretprobe (& tp -> rp );
1005- else
1006- disable_kprobe (& tp -> rp .kp );
1006+ tp -> flags &= ~TP_FLAG_TRACE ;
1007+ if (!(tp -> flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE ))) {
1008+ if (probe_is_return (tp ))
1009+ disable_kretprobe (& tp -> rp );
1010+ else
1011+ disable_kprobe (& tp -> rp .kp );
1012+ }
10071013}
10081014
10091015static int probe_event_raw_init (struct ftrace_event_call * event_call )
@@ -1212,22 +1218,57 @@ static int probe_profile_enable(struct ftrace_event_call *call)
12121218 if (atomic_inc_return (& call -> profile_count ))
12131219 return 0 ;
12141220
1215- if ( probe_is_return ( tp )) {
1216- tp -> rp . handler = kretprobe_profile_func ;
1221+ tp -> flags |= TP_FLAG_PROFILE ;
1222+ if ( probe_is_return ( tp ))
12171223 return enable_kretprobe (& tp -> rp );
1218- } else {
1219- tp -> rp .kp .pre_handler = kprobe_profile_func ;
1224+ else
12201225 return enable_kprobe (& tp -> rp .kp );
1221- }
12221226}
12231227
12241228static void probe_profile_disable (struct ftrace_event_call * call )
12251229{
1230+ struct trace_probe * tp = (struct trace_probe * )call -> data ;
1231+
12261232 if (atomic_add_negative (-1 , & call -> profile_count ))
1227- probe_event_disable (call );
1233+ tp -> flags &= ~TP_FLAG_PROFILE ;
1234+
1235+ if (!(tp -> flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE ))) {
1236+ if (probe_is_return (tp ))
1237+ disable_kretprobe (& tp -> rp );
1238+ else
1239+ disable_kprobe (& tp -> rp .kp );
1240+ }
12281241}
1242+ #endif /* CONFIG_EVENT_PROFILE */
1243+
1244+
1245+ static __kprobes
1246+ int kprobe_dispatcher (struct kprobe * kp , struct pt_regs * regs )
1247+ {
1248+ struct trace_probe * tp = container_of (kp , struct trace_probe , rp .kp );
12291249
1250+ if (tp -> flags & TP_FLAG_TRACE )
1251+ kprobe_trace_func (kp , regs );
1252+ #ifdef CONFIG_EVENT_PROFILE
1253+ if (tp -> flags & TP_FLAG_PROFILE )
1254+ kprobe_profile_func (kp , regs );
12301255#endif /* CONFIG_EVENT_PROFILE */
1256+ return 0 ; /* We don't tweek kernel, so just return 0 */
1257+ }
1258+
1259+ static __kprobes
1260+ int kretprobe_dispatcher (struct kretprobe_instance * ri , struct pt_regs * regs )
1261+ {
1262+ struct trace_probe * tp = container_of (ri -> rp , struct trace_probe , rp );
1263+
1264+ if (tp -> flags & TP_FLAG_TRACE )
1265+ kretprobe_trace_func (ri , regs );
1266+ #ifdef CONFIG_EVENT_PROFILE
1267+ if (tp -> flags & TP_FLAG_PROFILE )
1268+ kretprobe_profile_func (ri , regs );
1269+ #endif /* CONFIG_EVENT_PROFILE */
1270+ return 0 ; /* We don't tweek kernel, so just return 0 */
1271+ }
12311272
12321273static int register_probe_event (struct trace_probe * tp )
12331274{
0 commit comments