Skip to content

Commit

Permalink
Support kfunc in klockstat.py
Browse files Browse the repository at this point in the history
Adding kfunc return trampoline probe if available instead of
kprobe/kretprobe probes.

The kfunc trampolines are faster - less intrusive. The benchmark
without klockstat.py script on background:

	$ perf bench sched messaging -l 50000
	# Running 'sched/messaging' benchmark:
	# 20 sender and receiver processes per group
	# 10 groups == 400 processes run

	     Total time: 18.571 [sec]

With kprobe tracing:
	$ perf bench sched messaging -l 50000
	# Running 'sched/messaging' benchmark:
	# 20 sender and receiver processes per group
	# 10 groups == 400 processes run

	     Total time: 183.395 [sec]

With kfunc tracing:
	$ perf bench sched messaging -l 50000
	# Running 'sched/messaging' benchmark:
	# 20 sender and receiver processes per group
	# 10 groups == 400 processes run

	     Total time: 39.773 [sec]

Signed-off-by: Jiri Olsa <[email protected]>
  • Loading branch information
olsajiri authored and yonghong-song committed Feb 27, 2020
1 parent c347fe6 commit da7cac7
Showing 1 changed file with 48 additions and 7 deletions.
55 changes: 48 additions & 7 deletions tools/klockstat.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def stack_id_err(stack_id):
return 1;
}
int mutex_lock_enter(struct pt_regs *ctx)
static int do_mutex_lock_enter(void *ctx, int skip)
{
if (!is_enabled())
return 0;
Expand All @@ -149,7 +149,7 @@ def stack_id_err(stack_id):
return 0;
}
int stackid = stack_traces.get_stackid(ctx, 0);
int stackid = stack_traces.get_stackid(ctx, skip);
struct depth_id did = {
.id = id,
.depth = *depth,
Expand Down Expand Up @@ -237,7 +237,7 @@ def stack_id_err(stack_id):
}
}
int mutex_lock_return(struct pt_regs *ctx)
static int do_mutex_lock_return(void)
{
if (!is_enabled())
return 0;
Expand Down Expand Up @@ -285,7 +285,7 @@ def stack_id_err(stack_id):
return 0;
}
int mutex_unlock_enter(struct pt_regs *ctx)
static int do_mutex_unlock_enter(void)
{
if (!is_enabled())
return 0;
Expand Down Expand Up @@ -330,9 +330,49 @@ def stack_id_err(stack_id):
time_held.delete(&did);
return 0;
}
"""

program_kprobe = """
int mutex_unlock_enter(struct pt_regs *ctx)
{
return do_mutex_unlock_enter();
}
int mutex_lock_return(struct pt_regs *ctx)
{
return do_mutex_lock_return();
}
int mutex_lock_enter(struct pt_regs *ctx)
{
return do_mutex_lock_enter(ctx, 0);
}
"""

program_kfunc = """
KFUNC_PROBE(mutex_unlock, void *lock)
{
do_mutex_unlock_enter();
}
KRETFUNC_PROBE(mutex_lock, void *lock, int ret)
{
do_mutex_lock_return();
}
KFUNC_PROBE(mutex_lock, void *lock)
{
do_mutex_lock_enter(ctx, 3);
}
"""

is_support_kfunc = BPF.support_kfunc()
if is_support_kfunc:
program += program_kfunc
else:
program += program_kprobe

def sort_list(maxs, totals, counts):
if (not args.sort):
return maxs;
Expand Down Expand Up @@ -387,9 +427,10 @@ def display(sort, maxs, totals, counts):

b = BPF(text=program)

b.attach_kprobe(event="mutex_unlock", fn_name="mutex_unlock_enter")
b.attach_kretprobe(event="mutex_lock", fn_name="mutex_lock_return")
b.attach_kprobe(event="mutex_lock", fn_name="mutex_lock_enter")
if not is_support_kfunc:
b.attach_kprobe(event="mutex_unlock", fn_name="mutex_unlock_enter")
b.attach_kretprobe(event="mutex_lock", fn_name="mutex_lock_return")
b.attach_kprobe(event="mutex_lock", fn_name="mutex_lock_enter")

enabled = b.get_table("enabled");

Expand Down

0 comments on commit da7cac7

Please sign in to comment.