Skip to contentSkip to conversation

tracing/kprobes: Add trace event trigger invocations

PATCH Superseded Tom Zanussi 3 participants 4 messages Dec 29, 2013 – Jan 6, 2014 Tracing

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 tracing/kprobes: Add trace event trigger invocations

Add code to the kprobe/kretprobe event functions that will invoke any event triggers associated with a probe's ftrace_event_file.

The code to do this is very similar to the invocation code already used to invoke the triggers associated with static events and essentially replaces the existing soft-disable checks with a superset that preserves the original behavior but adds the bits needed to support event triggers.

---
 kernel/trace/trace_kprobe.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)
kernel/trace/trace_kprobe.c +36 -6
index dae9541..1ee13eb 100644
@@ -812,12 +812,20 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	struct ring_buffer *buffer;
 	int size, dsize, pc;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();
@@ -835,9 +843,16 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	entry->ip = (unsigned long)tp->rp.kp.addr;
 	store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
-	if (!filter_check_discard(ftrace_file, entry, buffer, event))
+	if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
+		__tt = event_triggers_call(ftrace_file, entry);
+
+	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
+		ring_buffer_discard_commit(buffer, event);
+	else if (!filter_check_discard(ftrace_file, entry, buffer, event))
 		trace_buffer_unlock_commit_regs(buffer, event,
 						irq_flags, pc, regs);
+	if (__tt)
+		event_triggers_post_call(ftrace_file, __tt);
 }
 
 static __kprobes void
@@ -860,12 +875,20 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
 	struct ring_buffer *buffer;
 	int size, pc, dsize;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();
@@ -884,9 +907,16 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
 	entry->ret_ip = (unsigned long)ri->ret_addr;
 	store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
-	if (!filter_check_discard(ftrace_file, entry, buffer, event))
+	if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
+		__tt = event_triggers_call(ftrace_file, entry);
+
+	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
+		ring_buffer_discard_commit(buffer, event);
+	else if (!filter_check_discard(ftrace_file, entry, buffer, event))
 		trace_buffer_unlock_commit_regs(buffer, event,
 						irq_flags, pc, regs);
+	if (__tt)
+		event_triggers_post_call(ftrace_file, __tt);
 }
 
 static __kprobes void
Signature · 1 line
1.8.3.1
Acked-by on v1 1/1
#1 lore raw
Quoted 10 lines · Tom Zanussi

Add code to the kprobe/kretprobe event functions that will invoke any event triggers associated with a probe's ftrace_event_file.

The code to do this is very similar to the invocation code already used to invoke the triggers associated with static events and essentially replaces the existing soft-disable checks with a superset that preserves the original behavior but adds the bits needed to support event triggers.

Looks good for me :)

Thank you!

Quoted 91 lines
---
 kernel/trace/trace_kprobe.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)
kernel/trace/trace_kprobe.c +36 -6
index dae9541..1ee13eb 100644
@@ -812,12 +812,20 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	struct ring_buffer *buffer;
 	int size, dsize, pc;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();
@@ -835,9 +843,16 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	entry->ip = (unsigned long)tp->rp.kp.addr;
 	store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
-	if (!filter_check_discard(ftrace_file, entry, buffer, event))
+	if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
+		__tt = event_triggers_call(ftrace_file, entry);
+
+	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
+		ring_buffer_discard_commit(buffer, event);
+	else if (!filter_check_discard(ftrace_file, entry, buffer, event))
 		trace_buffer_unlock_commit_regs(buffer, event,
 						irq_flags, pc, regs);
+	if (__tt)
+		event_triggers_post_call(ftrace_file, __tt);
 }
 
 static __kprobes void
@@ -860,12 +875,20 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
 	struct ring_buffer *buffer;
 	int size, pc, dsize;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();
@@ -884,9 +907,16 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
 	entry->ret_ip = (unsigned long)ri->ret_addr;
 	store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
 
-	if (!filter_check_discard(ftrace_file, entry, buffer, event))
+	if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
+		__tt = event_triggers_call(ftrace_file, entry);
+
+	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
+		ring_buffer_discard_commit(buffer, event);
+	else if (!filter_check_discard(ftrace_file, entry, buffer, event))
 		trace_buffer_unlock_commit_regs(buffer, event,
 						irq_flags, pc, regs);
+	if (__tt)
+		event_triggers_post_call(ftrace_file, __tt);
 }
 
 static __kprobes void
Signature · 4 lines
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
maintainer
#2 lore raw
In reply to Tom Zanussi
Quoted 19 lines · On Sat, 28 Dec 2013 20:24:08 -0600 Tom Zanussi <[email protected]>…

Add code to the kprobe/kretprobe event functions that will invoke any event triggers associated with a probe's ftrace_event_file.

The code to do this is very similar to the invocation code already used to invoke the triggers associated with static events and essentially replaces the existing soft-disable checks with a superset that preserves the original behavior but adds the bits needed to support event triggers.

---
 kernel/trace/trace_kprobe.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)
kernel/trace/trace_kprobe.c +0 -0
index dae9541..1ee13eb 100644

kernel/trace/trace_kprobe.c __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, · line 816

Quoted 5 lines
kernel/trace/trace_kprobe.c +2 -0
@@ -812,12 +812,20 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	struct ring_buffer *buffer;
 	int size, dsize, pc;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;

What's the significance of the "__" in the variable?

Looks as if you copied it from the ftrace_raw_event_* macro. The "__" there is usually recommended because it is a macro and we try to avoid namespace collisions by adding the "__".

This is a proper function, please remove the "__" from it.

Thanks,

-- Steve

Quoted 17 lines
kernel/trace/trace_kprobe.c +8 -2
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();
#3 lore raw
Quoted 30 lines · Steven Rostedt
Quoted 19 lines · On Sat, 28 Dec 2013 20:24:08 -0600 Tom Zanussi <[email protected]>…

Add code to the kprobe/kretprobe event functions that will invoke any event triggers associated with a probe's ftrace_event_file.

The code to do this is very similar to the invocation code already used to invoke the triggers associated with static events and essentially replaces the existing soft-disable checks with a superset that preserves the original behavior but adds the bits needed to support event triggers.

---
 kernel/trace/trace_kprobe.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)
kernel/trace/trace_kprobe.c +0 -0
index dae9541..1ee13eb 100644

kernel/trace/trace_kprobe.c __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, · line 816

Quoted 5 lines
kernel/trace/trace_kprobe.c +2 -0
@@ -812,12 +812,20 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
 	struct ring_buffer *buffer;
 	int size, dsize, pc;
 	unsigned long irq_flags;
+	unsigned long eflags;
+	enum event_trigger_type __tt = ETT_NONE;

What's the significance of the "__" in the variable?

Quoted 6 lines

Looks as if you copied it from the ftrace_raw_event_* macro. The "__" there is usually recommended because it is a macro and we try to avoid namespace collisions by adding the "__".

This is a proper function, please remove the "__" from it.

Right, it was just for consistency with the other invocations. Updates to this and the syscall invocations which also do the same thing, coming up...

Tom

Quoted 22 lines

Thanks,

-- Steve

Quoted 17 lines
kernel/trace/trace_kprobe.c +8 -2
 	struct ftrace_event_call *call = &tp->call;
 
 	WARN_ON(call != ftrace_file->event_call);
 
-	if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
-		return;
+	eflags = ftrace_file->flags;
+
+	if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
+		if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
+			event_triggers_call(ftrace_file, NULL);
+		if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
+			return;
+	}
 
 	local_save_flags(irq_flags);
 	pc = preempt_count();