diff --git a/source/tools/monitor/sched/schedmoni/bpf/schedmoni.bpf.c b/source/tools/monitor/sched/schedmoni/bpf/schedmoni.bpf.c index 249a37dea4f130d918ada0fac81124b763d133e8..94a0110d260c49d793655d7cd25f1b7af0cbc2a6 100644 --- a/source/tools/monitor/sched/schedmoni/bpf/schedmoni.bpf.c +++ b/source/tools/monitor/sched/schedmoni/bpf/schedmoni.bpf.c @@ -231,7 +231,7 @@ int BPF_KPROBE(account_process_tick, struct task_struct *p, int user_tick) latp->ticks_without_resched = 0; } else { latp->ticks_without_resched++; - resched_latency = now - latp->last_seen_need_resched_ns; + resched_latency = (now - latp->last_seen_need_resched_ns)/1000; if (resched_latency > _(argsp->min_us)) { struct key_t key; struct ext_key ext_key; @@ -243,7 +243,7 @@ int BPF_KPROBE(account_process_tick, struct task_struct *p, int user_tick) key.ret = bpf_get_stackid(ctx, &stackmap, KERN_STACKID_FLAGS); ext_key.stamp = now; ext_key.ret = key.ret; - ext_val.lat_us = resched_latency/1000; + ext_val.lat_us = resched_latency; bpf_get_current_comm(&ext_val.comm, sizeof(ext_val.comm)); ext_val.pid = bpf_get_current_pid_tgid(); ext_val.nosched_ticks = latp->ticks_without_resched; diff --git a/source/tools/monitor/sched/schedmoni/nosched.c b/source/tools/monitor/sched/schedmoni/nosched.c index 95a1a4c532a071ffe947a1651b918810eb41d8ec..0a0f300bf1a1d2e8332a731b212c78d6f994e3cd 100644 --- a/source/tools/monitor/sched/schedmoni/nosched.c +++ b/source/tools/monitor/sched/schedmoni/nosched.c @@ -93,7 +93,7 @@ static void print_ksym(__u64 addr) return; sym = ksym_search(addr); - fprintf(fp_nsc, "<%llx> %s\n", addr, sym->name); + fprintf(fp_nsc, "<0x%llx> %s\n", addr, sym->name); } static void print_stack(int fd, struct ext_key *key) @@ -133,7 +133,7 @@ static void print_stacks(int fd, int ext_fd) struct ext_key ext_key = {}, next_key; struct ext_val value; - fprintf(fp_nsc, "%-21s %-6s %-16s %-8s %-10s\n", "TIME", "CPU", "COMM", "TID", "LAT(us)"); + fprintf(fp_nsc, "%-21s %-6s %-16s %-8s %-10s\n", "TIME(nosch)", "CPU", "COMM", "TID", "LAT(us)"); while (bpf_map_get_next_key(ext_fd, &ext_key, &next_key) == 0) { bpf_map_lookup_elem(ext_fd, &next_key, &value); memset(dt, 0, sizeof(dt)); diff --git a/source/tools/monitor/sched/schedmoni/runqslow.c b/source/tools/monitor/sched/schedmoni/runqslow.c index 0b0a2ee59a1454540473dac5fe84303587a67bc8..e4c101c5e959a28e013633e2dee34c6ebc551019 100644 --- a/source/tools/monitor/sched/schedmoni/runqslow.c +++ b/source/tools/monitor/sched/schedmoni/runqslow.c @@ -45,11 +45,10 @@ void *runslw_handler(void *arg) struct perf_buffer_opts pb_opts = {}; previous = env.previous; - fprintf(fp_rsw, "Tracing run queue latency higher than %llu us\n", env.min_us); if (env.previous) - fprintf(fp_rsw, "%-21s %-6s %-16s %-8s %-10s %-16s %-6s\n", "TIME", "CPU", "COMM", "TID", "LAT(us)", "PREV COMM", "PREV TID"); + fprintf(fp_rsw, "%-21s %-6s %-16s %-8s %-10s %-16s %-6s\n", "TIME(runslw)", "CPU", "COMM", "TID", "LAT(us)", "PREV COMM", "PREV TID"); else - fprintf(fp_rsw, "%-21s %-6s %-16s %-8s %-10s\n", "TIME", "CPU", "COMM", "TID", "LAT(us)"); + fprintf(fp_rsw, "%-21s %-6s %-16s %-8s %-10s\n", "TIME(runslw)", "CPU", "COMM", "TID", "LAT(us)"); pb_opts.sample_cb = handle_event; pb = perf_buffer__new(data->fd, 64, &pb_opts); diff --git a/source/tools/monitor/sched/schedmoni/schedmoni.c b/source/tools/monitor/sched/schedmoni/schedmoni.c index 989f08c92c1576748d96437017f482db278605e0..7e9cb5ccc41e2d5d74c8a40feb4402f29a9f80fd 100644 --- a/source/tools/monitor/sched/schedmoni/schedmoni.c +++ b/source/tools/monitor/sched/schedmoni/schedmoni.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) #include +#include #include #include #include @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include #include #include "schedmoni.h" @@ -14,32 +17,36 @@ FILE *fp_nsc = NULL, *fp_rsw = NULL; volatile sig_atomic_t exiting = 0; -char rswf[] = "/var/log/sysak/runslow.log"; -char nscf[] = "/var/log/sysak/nosched.log"; +char log_dir[] = "/var/log/sysak/schedmoni"; +char rswf[] = "/var/log/sysak/schedmoni/runslow.log"; +char nscf[] = "/var/log/sysak/schedmoni/nosched.log"; char filename[256] = {0}; struct env env = { + .span = 0, .min_us = 10000, .fp = NULL, }; const char *argp_program_version = "schedmoni 0.1"; const char argp_program_doc[] = -"Trace high run queue latency.\n" +"Trace schedule latency.\n" "\n" -"USAGE: schedmoni [--help] [-p PID] [-t TID] [-P] [min_us] [-f ./runqslow.log]\n" +"USAGE: schedmoni [--help] [-s SPAN] [-t TID] [-P] [min_us] [-f ./runslow.log]\n" "\n" "EXAMPLES:\n" " schedmoni # trace latency higher than 10000 us (default)\n" " schedmoni -f a.log # trace latency and record result to a.log (default to /var/log/sysak/runslow.log)\n" " schedmoni 1000 # trace latency higher than 1000 us\n" -" schedmoni -p 123 # trace pid 123\n" +" schedmoni -p 123 # trace pid 12dd3\n" " schedmoni -t 123 # trace tid 123 (use for threads only)\n" +" schedmoni -s 10 # monitor for 10 seconds\n" " schedmoni -P # also show previous task name and TID\n"; static const struct argp_option opts[] = { { "pid", 'p', "PID", 0, "Process PID to trace"}, { "tid", 't', "TID", 0, "Thread TID to trace"}, + { "span", 's', "SPAN", 0, "How long to run"}, { "verbose", 'v', NULL, 0, "Verbose debug output" }, { "previous", 'P', NULL, 0, "also show previous task name and TID" }, { "logfile", 'f', "LOGFILE", 0, "logfile for result"}, @@ -60,11 +67,22 @@ static void bump_memlock_rlimit(void) } } +static int prepare_dictory(char *path) +{ + int ret; + + ret = mkdir(path, 0777); + if (ret < 0 && errno != EEXIST) + return errno; + else + return 0; +} + static error_t parse_arg(int key, char *arg, struct argp_state *state) { - static int pos_args; int pid; - long long min_us; + static int pos_args; + long long min_us, span; switch (key) { case 'h': @@ -94,6 +112,15 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) } env.tid = pid; break; + case 's': + errno = 0; + span = strtoul(arg, NULL, 10); + if (errno || span <= 0) { + fprintf(stderr, "Invalid SPAN: %s\n", arg); + argp_usage(state); + } + env.span = span; + break; case 'f': if (strlen(arg) < 2) { strncpy(filename, rswf, sizeof(filename)); @@ -179,6 +206,11 @@ static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va return vfprintf(stderr, format, args); } +static void sig_alarm(int signo) +{ + exiting = 1; +} + static void sig_int(int signo) { exiting = 1; @@ -194,7 +226,7 @@ int main(int argc, char **argv) void *res; int i, err, err1, err2; int arg_fd, ent_fd, stk_fd, stkext_fd; - pthread_t pt_runslw/*, pt_rqs*/; + pthread_t pt_runslw, pt_runnsc; struct schedmoni_bpf *obj; struct args args = {}; struct tharg runslw = {}; @@ -205,6 +237,10 @@ int main(int argc, char **argv) .doc = argp_program_doc, }; + err = prepare_dictory(log_dir); + if (err) + return err; + err = argp_parse(&argp, argc, argv, 0, NULL, NULL); if (err) return err; @@ -247,7 +283,8 @@ int main(int argc, char **argv) goto cleanup; } - if (signal(SIGINT, sig_int) == SIG_ERR) { + if (signal(SIGINT, sig_int) == SIG_ERR || + signal(SIGALRM, sig_alarm) == SIG_ERR) { fprintf(stderr, "can't set signal handler: %s\n", strerror(errno)); err = 1; goto cleanup; @@ -262,18 +299,20 @@ int main(int argc, char **argv) runnsc.fd = stk_fd; runnsc.ext_fd = stkext_fd; - err = pthread_create(&pt_runslw, NULL, runnsc_handler, &runnsc); + err = pthread_create(&pt_runnsc, NULL, runnsc_handler, &runnsc); if (err) { - fprintf(stderr, "can't pthread_create runslw: %s\n", strerror(errno)); + fprintf(stderr, "can't pthread_create runnsc: %s\n", strerror(errno)); goto cleanup; } + if (env.span) + alarm(env.span); + err1 = pthread_join(pt_runslw, &res); - err2 = pthread_join(pt_runslw, &res); + err2 = pthread_join(pt_runnsc, &res); if (err1 || err2) { goto cleanup; } - //printf("retvalue=%d\n", *res); cleanup: schedmoni_bpf__destroy(obj); diff --git a/source/tools/monitor/sched/schedmoni/schedmoni.h b/source/tools/monitor/sched/schedmoni/schedmoni.h index 5b1ba74d2d716add114525da968e159b0cec5b8c..5022c0f1908b54ac3568a1cc7edd2975bae9ef4e 100644 --- a/source/tools/monitor/sched/schedmoni/schedmoni.h +++ b/source/tools/monitor/sched/schedmoni/schedmoni.h @@ -24,6 +24,7 @@ struct tharg { struct env { pid_t pid; pid_t tid; + unsigned long span; __u64 min_us; bool previous; bool verbose;