From: Andrew Birchall Date: Wed, 4 May 2016 23:03:34 +0000 (-0700) Subject: add --kernel-threads-only to tools/offcputime X-Git-Tag: v0.2.0~84^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=582b5dd250ee8969896caca560b61c0e8f79314b;p=platform%2Fupstream%2Fbcc.git add --kernel-threads-only to tools/offcputime Summary: Adds `--kernel-threads-only` arg The kernel-threads-only arg is exclusive with pid/user-threads-only via `parser.add_mutually_exclusive_group`. The output message now indicates what we are tracing (pid/user threads/kernel threads/all threads). Removed the --verbose arg (unused). Test Plan: Run with combinations of the args; validate output looks sane: // test mutually exclusive group ``` devbig680[bcc](abirchall_dev): ~/bcc_run_tool.sh offcputime -k -u 1 [Running] /data/users/abirchall/bcc/tools/offcputime.py -k -u 1 usage: offcputime.py [-h] [-p PID | -k | -u] [-v] [-f] [duration] offcputime.py: error: argument -u/--user-threads-only: not allowed with argument -k/--kernel-threads-only ``` // kernel threads only ``` devbig680[bcc](abirchall_dev): ~/bcc_run_tool.sh offcputime -f -k 1 [Running] /data/users/abirchall/bcc/tools/offcputime.py -f -k 1 swapper/21;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 11 swapper/16;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 19 swapper/22;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 20 swapper/31;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 20 swapper/23;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 67 swapper/25;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule 74 ... ``` `~/bcc_run_tool.sh offcputime -f --kernel-threads-only 1` // user threads only `~/bcc_run_tool.sh offcputime -f --user-threads-only 1` `~/bcc_run_tool.sh offcputime -f -u 1` // specific pid `~/bcc_run_tool.sh offcputime -f -p $(pidof hphpi) 1` ``` devbig680[bcc](abirchall_dev): ~/bcc_run_tool.sh offcputime --pid $(pidof mcrouter) 10 | head [Running] /data/users/abirchall/bcc/tools/offcputime.py --pid 95929 10 Tracing off-CPU time (us) of PID 95929 by kernel stack for 10 secs. ``` Note that this last case (specific PID) doesn't appear to be working; I can debug that in a follow up commit. --- diff --git a/tools/offcputime.py b/tools/offcputime.py index 31dc0a3..751349f 100755 --- a/tools/offcputime.py +++ b/tools/offcputime.py @@ -3,11 +3,7 @@ # offcputime Summarize off-CPU time by kernel stack trace # For Linux, uses BCC, eBPF. # -# USAGE: offcputime [-h] [-u] [-p PID] [-v] [-f] [duration] -# -# The current implementation uses an unrolled loop for x86_64, and was written -# as a proof of concept. This implementation should be replaced in the future -# with an appropriate bpf_ call, when available. +# USAGE: offcputime [-h] [-p PID | -u | -k] [-f] [duration] # # Copyright 2016 Netflix, Inc. # Licensed under the Apache License, Version 2.0 (the "License") @@ -43,20 +39,21 @@ examples = """examples: ./offcputime # trace off-CPU stack time until Ctrl-C ./offcputime 5 # trace for 5 seconds only ./offcputime -f 5 # 5 seconds, and output in folded format - ./offcputime -u # don't include kernel threads (user only) - ./offcputime -p 185 # trace for PID 185 only + ./offcputime -p 185 # only trace threads for PID 185 + ./offcputime -u # only trace user threads (no kernel) + ./offcputime -k # only trace kernel threads (no user) """ parser = argparse.ArgumentParser( description="Summarize off-CPU time by kernel stack trace", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=examples) thread_group = parser.add_mutually_exclusive_group() -thread_group.add_argument("-u", "--useronly", action="store_true", - help="user threads only (no kernel threads)") thread_group.add_argument("-p", "--pid", type=positive_int, help="trace this PID only") -parser.add_argument("-v", "--verbose", action="store_true", - help="show raw addresses") +thread_group.add_argument("-k", "--kernel-threads-only", action="store_true", + help="kernel threads only (no user threads)") +thread_group.add_argument("-u", "--user-threads-only", action="store_true", + help="user threads only (no kernel threads)") parser.add_argument("-f", "--folded", action="store_true", help="output folded format") parser.add_argument("--stack-storage-size", default=1024, @@ -94,7 +91,7 @@ int oncpu(struct pt_regs *ctx, struct task_struct *prev) { u64 ts, *tsp; // record previous thread sleep time - if (FILTER) { + if (THREAD_FILTER) { pid = prev->pid; ts = bpf_ktime_get_ns(); start.update(&pid, &ts); @@ -125,13 +122,20 @@ int oncpu(struct pt_regs *ctx, struct task_struct *prev) { """ # set thread filter +thread_context = "" if args.pid is not None: - filter = 'pid == %s' % args.pid -elif args.useronly: - filter = '!(prev->flags & PF_KTHREAD)' + thread_context = "PID %s" % args.pid + thread_filter = 'pid == %s' % args.pid +elif args.user_threads_only: + thread_context = "user threads" + thread_filter = '!(prev->flags & PF_KTHREAD)' +elif args.kernel_threads_only: + thread_context = "kernel threads" + thread_filter = 'prev->flags & PF_KTHREAD' else: - filter = '1' -bpf_text = bpf_text.replace('FILTER', filter) + thread_context = "all threads" + thread_filter = '1' +bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter) # set stack storage size bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size)) @@ -146,7 +150,8 @@ if matched == 0: # header if not folded: - print("Tracing off-CPU time (us) by kernel stack", end="") + print("Tracing off-CPU time (us) of %s by kernel stack" % + thread_context, end="") if duration < 99999999: print(" for %d secs." % duration) else: diff --git a/tools/offcputime_example.txt b/tools/offcputime_example.txt index cb42b4b..fb984c6 100644 --- a/tools/offcputime_example.txt +++ b/tools/offcputime_example.txt @@ -718,7 +718,7 @@ creating your "off-CPU time flame graphs". USAGE message: # ./offcputime -h -usage: offcputime.py [-h] [-u | -p PID] [-v] [-f] +usage: offcputime.py [-h] [-p PID | -k | -u] [-f] [--stack-storage-size STACK_STORAGE_SIZE] [duration] @@ -729,9 +729,11 @@ positional arguments: optional arguments: -h, --help show this help message and exit - -u, --useronly user threads only (no kernel threads) -p PID, --pid PID trace this PID only - -v, --verbose show raw addresses + -k, --kernel-threads-only + kernel threads only (no user threads) + -u, --user-threads-only + user threads only (no kernel threads) -f, --folded output folded format --stack-storage-size STACK_STORAGE_SIZE the number of unique stack traces that can be stored @@ -741,5 +743,6 @@ examples: ./offcputime # trace off-CPU stack time until Ctrl-C ./offcputime 5 # trace for 5 seconds only ./offcputime -f 5 # 5 seconds, and output in folded format - ./offcputime -u # don't include kernel threads (user only) - ./offcputime -p 185 # trace for PID 185 only + ./offcputime -p 185 # only trace threads for PID 185 + ./offcputime -u # only trace user threads (no kernel) + ./offcputime -k # only trace kernel threads (no user)