From 5256ffd0a051e11646a38debfd8bb68cfb738305 Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Wed, 23 Feb 2022 16:19:20 +0800 Subject: [PATCH 01/10] monitor/sched: add runqlen to summarize run queue length Summarize scheduler run queue length as a histogram. This is an upgrade to monitor/sched/runlat/runqlen based on ebpf. Signed-off-by: Hailong Liu --- source/tools/monitor/sched/runqlen/Makefile | 8 + .../monitor/sched/runqlen/bpf/runqlen.bpf.c | 108 +++++++ source/tools/monitor/sched/runqlen/runqlen.c | 305 ++++++++++++++++++ source/tools/monitor/sched/runqlen/runqlen.h | 12 + .../monitor/sched/runqlen/trace_helpers.c | 73 +++++ .../monitor/sched/runqlen/trace_helpers.h | 97 ++++++ .../monitor/sched/runqlen/uprobe_helpers.h | 18 ++ 7 files changed, 621 insertions(+) create mode 100644 source/tools/monitor/sched/runqlen/Makefile create mode 100644 source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c create mode 100644 source/tools/monitor/sched/runqlen/runqlen.c create mode 100644 source/tools/monitor/sched/runqlen/runqlen.h create mode 100644 source/tools/monitor/sched/runqlen/trace_helpers.c create mode 100644 source/tools/monitor/sched/runqlen/trace_helpers.h create mode 100644 source/tools/monitor/sched/runqlen/uprobe_helpers.h diff --git a/source/tools/monitor/sched/runqlen/Makefile b/source/tools/monitor/sched/runqlen/Makefile new file mode 100644 index 00000000..ceeea2e5 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/Makefile @@ -0,0 +1,8 @@ + +newdirs := $(shell find ./ -type d) + +bpfsrcs := $(wildcard bpf/*.bpf.c) +csrcs := $(wildcard *.c) +target := runqlen + +include $(SRC)/mk/bpf.mk diff --git a/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c b/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c new file mode 100644 index 00000000..c282200f --- /dev/null +++ b/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Wenbo Zhang +#include +#include +#include +#include +#include "../runqlen.h" +//#define MAX_CPU_NR 128 +//#define MAX_SLOTS 32 + +//const volatile bool targ_per_cpu = false; + +struct bpf_map_def SEC("maps") args_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(bool), + .max_entries = 1, +}; + +struct bpf_map_def SEC("maps") hist_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(struct hist), + .max_entries = MAX_CPU_NR, +}; + +#if 0 +/* + * Todo: + * task->se.cfs_rq->nr_running is not the perfect soluthon for child cpu-cgroup + */ +static u64 get_runq_nr_run(struct task_struct *task) +{ + int limit; + u64 nr_running = 0; + struct sched_entity *se, *topse; + + limit = BPF_CORE_READ(task, se.depth); + topse = BPF_CORE_READ(task, se.parent); + if (topse) { + for (se = topse; se && limit > 1; limit--) { + topse = se; + se = BPF_CORE_READ(se, parent); + } + nr_running = BPF_CORE_READ(topse, cfs_rq, nr_running); + } else { + nr_running = BPF_CORE_READ(task, se.cfs_rq, nr_running); + } + + return nr_running; +} +#else +static u64 get_runq_nr_run(struct task_struct *task) +{ + u64 nr_running = BPF_CORE_READ(task, se.cfs_rq, nr_running); + + return nr_running; +} +#endif + +SEC("perf_event") +int do_sample(struct bpf_perf_event_data *ctx) +{ + struct task_struct *task; + struct sched_entity *sep, *parent, *topse; + struct hist hist, *histp; + u64 slot, cpu = 0; + bool *targ_per_cpu_p , targ_per_cpu = false; + int arg_idx = 0; + + task = (void*)bpf_get_current_task(); + + slot = get_runq_nr_run(task); + /* + * Calculate run queue length by subtracting the currently running task, + * if present. len 0 == idle, len 1 == one running task. + */ + if (slot > 0) + slot--; + + targ_per_cpu_p = bpf_map_lookup_elem(&args_map, &arg_idx); + if (targ_per_cpu_p) + targ_per_cpu = *targ_per_cpu_p; + if (targ_per_cpu) { + cpu = bpf_get_smp_processor_id(); + /* + * When the program is started, the user space will immediately + * exit when it detects this situation, here just to pass the + * verifier's check. + */ + if (cpu >= MAX_CPU_NR) + return 0; + } + histp = bpf_map_lookup_elem(&hist_map, &cpu); + if (histp) { + if (slot >= MAX_SLOTS) + slot = MAX_SLOTS - 1; + if (targ_per_cpu) + histp->slots[slot]++; + else + __sync_fetch_and_add(&histp->slots[slot], 1); + bpf_map_update_elem(&hist_map, &cpu, histp, BPF_ANY); + } else + return -1; + return 0; +} + +char LICENSE[] SEC("license") = "GPL"; diff --git a/source/tools/monitor/sched/runqlen/runqlen.c b/source/tools/monitor/sched/runqlen/runqlen.c new file mode 100644 index 00000000..fafa81b9 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/runqlen.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +// Copyright (c) 2020 Wenbo Zhang +// +// Based on runqlen(8) from BCC by Brendan Gregg. +// 11-Sep-2020 Wenbo Zhang Created this. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "runqlen.h" +#include "bpf/runqlen.skel.h" +#include "trace_helpers.h" + +#define max(x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +struct env { + bool per_cpu; + bool runqocc; + bool timestamp; + time_t interval; + int freq; + int times; + bool verbose; +} env = { + .interval = 99999999, + .times = 99999999, + .freq = 99, +}; + +static volatile bool exiting; + +const char *argp_program_version = "runqlen 0.1"; +const char *argp_program_bug_address = + "https://github.com/iovisor/bcc/tree/master/libbpf-tools"; +const char argp_program_doc[] = +"Summarize scheduler run queue length as a histogram.\n" +"\n" +"USAGE: runqlen [--help] [-C] [-O] [-T] [-f FREQUENCY] [interval] [count]\n" +"\n" +"EXAMPLES:\n" +" runqlen # summarize run queue length as a histogram\n" +" runqlen 1 10 # print 1 second summaries, 10 times\n" +" runqlen -T 1 # 1s summaries and timestamps\n" +" runqlen -O # report run queue occupancy\n" +" runqlen -C # show each CPU separately\n" +" runqlen -f 199 # sample at 199HZ\n"; + +static const struct argp_option opts[] = { + { "cpus", 'C', NULL, 0, "Print output for each CPU separately" }, + { "frequency", 'f', "FREQUENCY", 0, "Sample with a certain frequency" }, + { "runqocc", 'O', NULL, 0, "Report run queue occupancy" }, + { "timestamp", 'T', NULL, 0, "Include timestamp on output" }, + { "verbose", 'v', NULL, 0, "Verbose debug output" }, + { NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" }, + {}, +}; + +static error_t parse_arg(int key, char *arg, struct argp_state *state) +{ + static int pos_args; + + switch (key) { + case 'h': + argp_state_help(state, stderr, ARGP_HELP_STD_HELP); + break; + case 'v': + env.verbose = true; + break; + case 'C': + env.per_cpu = true; + break; + case 'O': + env.runqocc = true; + break; + case 'T': + env.timestamp = true; + break; + case 'f': + errno = 0; + env.freq = strtol(arg, NULL, 10); + if (errno || env.freq <= 0) { + fprintf(stderr, "Invalid freq (in hz): %s\n", arg); + argp_usage(state); + } + break; + case ARGP_KEY_ARG: + errno = 0; + if (pos_args == 0) { + env.interval = strtol(arg, NULL, 10); + if (errno) { + fprintf(stderr, "invalid internal\n"); + argp_usage(state); + } + } else if (pos_args == 1) { + env.times = strtol(arg, NULL, 10); + if (errno) { + fprintf(stderr, "invalid times\n"); + argp_usage(state); + } + } else { + fprintf(stderr, + "unrecognized positional argument: %s\n", arg); + argp_usage(state); + } + pos_args++; + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static int nr_cpus; + +static int open_and_attach_perf_event(int freq, struct bpf_program *prog, + struct bpf_link *links[]) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, + .freq = 1, + .sample_period = freq, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; + int i, fd; + + for (i = 0; i < nr_cpus; i++) { + fd = syscall(__NR_perf_event_open, &attr, -1, i, -1, 0); + if (fd < 0) { + /* Ignore CPU that is offline */ + if (errno == ENODEV) + continue; + fprintf(stderr, "failed to init perf sampling: %s\n", + strerror(errno)); + return -1; + } + links[i] = bpf_program__attach_perf_event(prog, fd); + if (!links[i]) { + fprintf(stderr, "failed to attach perf event on cpu: %d\n", i); + close(fd); + return -1; + } + } + + return 0; +} + +static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) +{ + if (level == LIBBPF_DEBUG && !env.verbose) + return 0; + return vfprintf(stderr, format, args); +} + +static void sig_handler(int sig) +{ + exiting = true; +} + +static struct hist zero; + +static void print_runq_occupancy(int hist_fd) +{ + struct hist hist; + int slot, i = 0; + float runqocc; + + do { + __u64 samples, idle = 0, queued = 0, total = 0, meanlen = 0; + bpf_map_lookup_elem(hist_fd, &i, &hist); + bpf_map_update_elem(hist_fd, &i, &zero, BPF_ANY); + for (slot = 0; slot < MAX_SLOTS; slot++) { + __u64 val = hist.slots[slot]; + + if (slot == 0) + idle += val; + else { + total += val * slot; + queued += val; + } + } + samples = idle + queued; + runqocc = queued * 1.0 / max(1ULL, samples); + meanlen = total / max(1ULL, samples); + if (env.per_cpu) + printf("runqocc, CPU %-3d %6.2f%%, AVGlen %lld\n", i, + 100 * runqocc, meanlen); + else + printf("runqocc: %0.2f%%, AVGlen %lld\n", 100 * runqocc, meanlen); + } while (env.per_cpu && ++i < nr_cpus); +} + +static void print_linear_hists(int hist_fd) +{ + struct hist hist; + int i = 0; + + do { + bpf_map_lookup_elem(hist_fd, &i, &hist); + bpf_map_update_elem(hist_fd, &i, &zero, BPF_ANY); + //hist = bss->hists[i]; + //bss->hists[i] = zero; + if (env.per_cpu) + printf("cpu = %d\n", i); + print_linear_hist(hist.slots, MAX_SLOTS, 0, 1, "runqlen"); + } while (env.per_cpu && ++i < nr_cpus); +} + +int main(int argc, char **argv) +{ + static const struct argp argp = { + .options = opts, + .parser = parse_arg, + .doc = argp_program_doc, + }; + struct bpf_link *links[MAX_CPU_NR] = {}; + struct runqlen_bpf *obj; + struct tm *tm; + char ts[32]; + int err, i, hist_fd, arg_fd, arg_idx = 0; + time_t t; + + err = argp_parse(&argp, argc, argv, 0, NULL, NULL); + if (err) + return err; + + //libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(libbpf_print_fn); + + nr_cpus = libbpf_num_possible_cpus(); + if (nr_cpus < 0) { + printf("failed to get # of possible cpus: '%s'!\n", + strerror(-nr_cpus)); + return 1; + } + if (nr_cpus > MAX_CPU_NR) { + fprintf(stderr, "the number of cpu cores is too big, please " + "increase MAX_CPU_NR's value and recompile"); + return 1; + } + + obj = runqlen_bpf__open(); + if (!obj) { + fprintf(stderr, "failed to open BPF object\n"); + return 1; + } + + /* initialize global data (filtering options) */ + //obj->rodata->targ_per_cpu = env.per_cpu; + + err = runqlen_bpf__load(obj); + if (err) { + fprintf(stderr, "failed to load BPF object: %d\n", err); + goto cleanup; + } + + arg_fd = bpf_map__fd(obj->maps.args_map); + bpf_map_update_elem(arg_fd, &arg_idx, &env.per_cpu, BPF_ANY); + + err = open_and_attach_perf_event(env.freq, obj->progs.do_sample, links); + if (err) + goto cleanup; + + printf("Sampling run queue length... Hit Ctrl-C to end.\n"); + + signal(SIGINT, sig_handler); + + hist_fd = bpf_map__fd(obj->maps.hist_map); + while (1) { + sleep(env.interval); + printf("\n"); + + if (env.timestamp) { + time(&t); + tm = localtime(&t); + strftime(ts, sizeof(ts), "%H:%M:%S", tm); + printf("%-8s\n", ts); + } + + if (env.runqocc) + print_runq_occupancy(hist_fd); + else + print_linear_hists(hist_fd); + + if (exiting || --env.times == 0) + break; + } + +cleanup: + for (i = 0; i < nr_cpus; i++) + bpf_link__destroy(links[i]); + runqlen_bpf__destroy(obj); + + return err != 0; +} diff --git a/source/tools/monitor/sched/runqlen/runqlen.h b/source/tools/monitor/sched/runqlen/runqlen.h new file mode 100644 index 00000000..60527289 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/runqlen.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __RUNQLEN_H +#define __RUNQLEN_H + +#define MAX_CPU_NR 128 +#define MAX_SLOTS 32 + +struct hist { + __u32 slots[MAX_SLOTS]; +}; + +#endif /* __RUNQLEN_H */ diff --git a/source/tools/monitor/sched/runqlen/trace_helpers.c b/source/tools/monitor/sched/runqlen/trace_helpers.c new file mode 100644 index 00000000..6dc755f0 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/trace_helpers.c @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +// Copyright (c) 2020 Wenbo Zhang +// +// Based on ksyms improvements from Andrii Nakryiko, add more helpers. +// 28-Feb-2020 Wenbo Zhang Created this. +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "trace_helpers.h" +//#include "uprobe_helpers.h" +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +static void print_stars(unsigned int val, unsigned int val_max, int width) +{ + int num_stars, num_spaces, i; + bool need_plus; + + num_stars = min(val, val_max) * width / val_max; + num_spaces = width - num_stars; + need_plus = val > val_max; + + for (i = 0; i < num_stars; i++) + printf("*"); + for (i = 0; i < num_spaces; i++) + printf(" "); + if (need_plus) + printf("+"); +} + +void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, + unsigned int step, const char *val_type) +{ + int i, stars_max = 40, idx_min = -1, idx_max = -1; + unsigned int val, val_max = 0; + + for (i = 0; i < vals_size; i++) { + val = vals[i]; + if (val > 0) { + idx_max = i; + if (idx_min < 0) + idx_min = i; + } + if (val > val_max) + val_max = val; + } + + if (idx_max < 0) + return; + + printf(" %-13s : count distribution\n", val_type); + for (i = idx_min; i <= idx_max; i++) { + val = vals[i]; + printf(" %-10d : %-8d |", base + i * step, val); + print_stars(val, val_max, stars_max); + printf("|\n"); + } +} diff --git a/source/tools/monitor/sched/runqlen/trace_helpers.h b/source/tools/monitor/sched/runqlen/trace_helpers.h new file mode 100644 index 00000000..98fd640f --- /dev/null +++ b/source/tools/monitor/sched/runqlen/trace_helpers.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __TRACE_HELPERS_H +#define __TRACE_HELPERS_H + +#include + +#define NSEC_PER_SEC 1000000000ULL + +struct ksym { + const char *name; + unsigned long addr; +}; + +struct ksyms; + +struct ksyms *ksyms__load(void); +void ksyms__free(struct ksyms *ksyms); +const struct ksym *ksyms__map_addr(const struct ksyms *ksyms, + unsigned long addr); +const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms, + const char *name); + +struct sym { + const char *name; + unsigned long start; + unsigned long size; +}; + +struct syms; + +struct syms *syms__load_pid(int tgid); +struct syms *syms__load_file(const char *fname); +void syms__free(struct syms *syms); +const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr); + +struct syms_cache; + +struct syms_cache *syms_cache__new(int nr); +struct syms *syms_cache__get_syms(struct syms_cache *syms_cache, int tgid); +void syms_cache__free(struct syms_cache *syms_cache); + +struct partition { + char *name; + unsigned int dev; +}; + +struct partitions; + +struct partitions *partitions__load(void); +void partitions__free(struct partitions *partitions); +const struct partition * +partitions__get_by_dev(const struct partitions *partitions, unsigned int dev); +const struct partition * +partitions__get_by_name(const struct partitions *partitions, const char *name); + +void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type); +void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, + unsigned int step, const char *val_type); + +unsigned long long get_ktime_ns(void); + +bool is_kernel_module(const char *name); + +/* + * When attempting to use kprobe/kretprobe, please check out new fentry/fexit + * probes, as they provide better performance and usability. But in some + * situations we have to fallback to kprobe/kretprobe probes. This helper + * is used to detect fentry/fexit support for the specified kernel function. + * + * 1. A gap between kernel versions, kernel BTF is exposed + * starting from 5.4 kernel. but fentry/fexit is actually + * supported starting from 5.5. + * 2. Whether kernel supports module BTF or not + * + * *name* is the name of a kernel function to be attached to, which can be + * from vmlinux or a kernel module. + * *mod* is a hint that indicates the *name* may reside in module BTF, + * if NULL, it means *name* belongs to vmlinux. + */ +bool fentry_exists(const char *name, const char *mod); + +/* + * The name of a kernel function to be attached to may be changed between + * kernel releases. This helper is used to confirm whether the target kernel + * uses a certain function name before attaching. + * + * It is achieved by scaning + * /sys/kernel/debug/tracing/available_filter_functions + * If this file does not exist, it fallbacks to parse /proc/kallsyms, + * which is slower. + */ +bool kprobe_exists(const char *name); + +bool vmlinux_btf_exists(void); +bool module_btf_exists(const char *mod); + +#endif /* __TRACE_HELPERS_H */ diff --git a/source/tools/monitor/sched/runqlen/uprobe_helpers.h b/source/tools/monitor/sched/runqlen/uprobe_helpers.h new file mode 100644 index 00000000..47f77bb2 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/uprobe_helpers.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +/* Copyright (c) 2021 Google LLC. */ +#ifndef __UPROBE_HELPERS_H +#define __UPROBE_HELPERS_H + +#include +#include +#include + +int get_pid_binary_path(pid_t pid, char *path, size_t path_sz); +int get_pid_lib_path(pid_t pid, const char *lib, char *path, size_t path_sz); +int resolve_binary_path(const char *binary, pid_t pid, char *path, size_t path_sz); +off_t get_elf_func_offset(const char *path, const char *func); +Elf *open_elf(const char *path, int *fd_close); +Elf *open_elf_by_fd(int fd); +void close_elf(Elf *e, int fd_close); + +#endif /* __UPROBE_HELPERS_H */ -- Gitee From fd07a2cf49c6a1441376b97b2f868fe68663d607 Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Wed, 23 Feb 2022 16:37:50 +0800 Subject: [PATCH 02/10] sched/runqlen: Add README doc Add user manual for runqlen. Signed-off-by: Hailong Liu --- source/tools/monitor/sched/runqlen/README.txt | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 source/tools/monitor/sched/runqlen/README.txt diff --git a/source/tools/monitor/sched/runqlen/README.txt b/source/tools/monitor/sched/runqlen/README.txt new file mode 100644 index 00000000..c1f84e68 --- /dev/null +++ b/source/tools/monitor/sched/runqlen/README.txt @@ -0,0 +1,55 @@ +1 What is runqlen? +Summarize scheduler run queue length as a histogram. + + +2 Usage of runqlen +USAGE: runqlen [--help] [-C] [-O] [-T] [-f FREQUENCY] [interval] [count] + +EXAMPLES: + runqlen # summarize run queue length as a histogram + runqlen 1 10 # print 1 second summaries, 10 times + runqlen -T 1 # 1s summaries and timestamps + runqlen -O # report run queue occupancy + runqlen -C # show each CPU separately + runqlen -f 199 # sample at 199HZ + + -C, --cpus Print output for each CPU separately + -f, --frequency=FREQUENCY Sample with a certain frequency + -O, --runqocc Report run queue occupancy + -T, --timestamp Include timestamp on output + -v, --verbose Verbose debug output + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version + +3 Example +3.1 perf the run queue occupancy 2 times every 5 seconds +sudo sysak runqlen 5 2 -C -T -O + +16:06:54 +runqocc, CPU 0 0.00%, AVGlen 0 +runqocc, CPU 1 0.00%, AVGlen 0 +runqocc, CPU 2 0.00%, AVGlen 0 +runqocc, CPU 3 0.00%, AVGlen 0 + +16:06:55 +runqocc, CPU 0 0.00%, AVGlen 0 +runqocc, CPU 1 0.00%, AVGlen 0 +runqocc, CPU 2 0.00%, AVGlen 0 +runqocc, CPU 3 0.00%, AVGlen 0 + +3.2 perf the run queue histogram 1 times every 5 seconds +sudo sysak runqlen 5 2 -C -T -O +16:34:56 +cpu = 0 + runqlen : count distribution + 0 : 495 |****************************************| +cpu = 1 + runqlen : count distribution + 0 : 495 |****************************************| +cpu = 2 + runqlen : count distribution + 0 : 495 |****************************************| +cpu = 3 + runqlen : count distribution + 0 : 495 |****************************************| -- Gitee From 24bbd226205aa8b35c0791a4572124fa5affd7ed Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 11:33:45 +0800 Subject: [PATCH 03/10] Revert "monitor/sched: add runqlen to summarize run queue length" This reverts commit 5256ffd0a051e11646a38debfd8bb68cfb738305. --- source/tools/monitor/sched/runqlen/Makefile | 8 - .../monitor/sched/runqlen/bpf/runqlen.bpf.c | 108 ------- source/tools/monitor/sched/runqlen/runqlen.c | 305 ------------------ source/tools/monitor/sched/runqlen/runqlen.h | 12 - .../monitor/sched/runqlen/trace_helpers.c | 73 ----- .../monitor/sched/runqlen/trace_helpers.h | 97 ------ .../monitor/sched/runqlen/uprobe_helpers.h | 18 -- 7 files changed, 621 deletions(-) delete mode 100644 source/tools/monitor/sched/runqlen/Makefile delete mode 100644 source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c delete mode 100644 source/tools/monitor/sched/runqlen/runqlen.c delete mode 100644 source/tools/monitor/sched/runqlen/runqlen.h delete mode 100644 source/tools/monitor/sched/runqlen/trace_helpers.c delete mode 100644 source/tools/monitor/sched/runqlen/trace_helpers.h delete mode 100644 source/tools/monitor/sched/runqlen/uprobe_helpers.h diff --git a/source/tools/monitor/sched/runqlen/Makefile b/source/tools/monitor/sched/runqlen/Makefile deleted file mode 100644 index ceeea2e5..00000000 --- a/source/tools/monitor/sched/runqlen/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -newdirs := $(shell find ./ -type d) - -bpfsrcs := $(wildcard bpf/*.bpf.c) -csrcs := $(wildcard *.c) -target := runqlen - -include $(SRC)/mk/bpf.mk diff --git a/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c b/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c deleted file mode 100644 index c282200f..00000000 --- a/source/tools/monitor/sched/runqlen/bpf/runqlen.bpf.c +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2020 Wenbo Zhang -#include -#include -#include -#include -#include "../runqlen.h" -//#define MAX_CPU_NR 128 -//#define MAX_SLOTS 32 - -//const volatile bool targ_per_cpu = false; - -struct bpf_map_def SEC("maps") args_map = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(u32), - .value_size = sizeof(bool), - .max_entries = 1, -}; - -struct bpf_map_def SEC("maps") hist_map = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(u32), - .value_size = sizeof(struct hist), - .max_entries = MAX_CPU_NR, -}; - -#if 0 -/* - * Todo: - * task->se.cfs_rq->nr_running is not the perfect soluthon for child cpu-cgroup - */ -static u64 get_runq_nr_run(struct task_struct *task) -{ - int limit; - u64 nr_running = 0; - struct sched_entity *se, *topse; - - limit = BPF_CORE_READ(task, se.depth); - topse = BPF_CORE_READ(task, se.parent); - if (topse) { - for (se = topse; se && limit > 1; limit--) { - topse = se; - se = BPF_CORE_READ(se, parent); - } - nr_running = BPF_CORE_READ(topse, cfs_rq, nr_running); - } else { - nr_running = BPF_CORE_READ(task, se.cfs_rq, nr_running); - } - - return nr_running; -} -#else -static u64 get_runq_nr_run(struct task_struct *task) -{ - u64 nr_running = BPF_CORE_READ(task, se.cfs_rq, nr_running); - - return nr_running; -} -#endif - -SEC("perf_event") -int do_sample(struct bpf_perf_event_data *ctx) -{ - struct task_struct *task; - struct sched_entity *sep, *parent, *topse; - struct hist hist, *histp; - u64 slot, cpu = 0; - bool *targ_per_cpu_p , targ_per_cpu = false; - int arg_idx = 0; - - task = (void*)bpf_get_current_task(); - - slot = get_runq_nr_run(task); - /* - * Calculate run queue length by subtracting the currently running task, - * if present. len 0 == idle, len 1 == one running task. - */ - if (slot > 0) - slot--; - - targ_per_cpu_p = bpf_map_lookup_elem(&args_map, &arg_idx); - if (targ_per_cpu_p) - targ_per_cpu = *targ_per_cpu_p; - if (targ_per_cpu) { - cpu = bpf_get_smp_processor_id(); - /* - * When the program is started, the user space will immediately - * exit when it detects this situation, here just to pass the - * verifier's check. - */ - if (cpu >= MAX_CPU_NR) - return 0; - } - histp = bpf_map_lookup_elem(&hist_map, &cpu); - if (histp) { - if (slot >= MAX_SLOTS) - slot = MAX_SLOTS - 1; - if (targ_per_cpu) - histp->slots[slot]++; - else - __sync_fetch_and_add(&histp->slots[slot], 1); - bpf_map_update_elem(&hist_map, &cpu, histp, BPF_ANY); - } else - return -1; - return 0; -} - -char LICENSE[] SEC("license") = "GPL"; diff --git a/source/tools/monitor/sched/runqlen/runqlen.c b/source/tools/monitor/sched/runqlen/runqlen.c deleted file mode 100644 index fafa81b9..00000000 --- a/source/tools/monitor/sched/runqlen/runqlen.c +++ /dev/null @@ -1,305 +0,0 @@ -// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -// Copyright (c) 2020 Wenbo Zhang -// -// Based on runqlen(8) from BCC by Brendan Gregg. -// 11-Sep-2020 Wenbo Zhang Created this. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "runqlen.h" -#include "bpf/runqlen.skel.h" -#include "trace_helpers.h" - -#define max(x, y) ({ \ - typeof(x) _max1 = (x); \ - typeof(y) _max2 = (y); \ - (void) (&_max1 == &_max2); \ - _max1 > _max2 ? _max1 : _max2; }) - -struct env { - bool per_cpu; - bool runqocc; - bool timestamp; - time_t interval; - int freq; - int times; - bool verbose; -} env = { - .interval = 99999999, - .times = 99999999, - .freq = 99, -}; - -static volatile bool exiting; - -const char *argp_program_version = "runqlen 0.1"; -const char *argp_program_bug_address = - "https://github.com/iovisor/bcc/tree/master/libbpf-tools"; -const char argp_program_doc[] = -"Summarize scheduler run queue length as a histogram.\n" -"\n" -"USAGE: runqlen [--help] [-C] [-O] [-T] [-f FREQUENCY] [interval] [count]\n" -"\n" -"EXAMPLES:\n" -" runqlen # summarize run queue length as a histogram\n" -" runqlen 1 10 # print 1 second summaries, 10 times\n" -" runqlen -T 1 # 1s summaries and timestamps\n" -" runqlen -O # report run queue occupancy\n" -" runqlen -C # show each CPU separately\n" -" runqlen -f 199 # sample at 199HZ\n"; - -static const struct argp_option opts[] = { - { "cpus", 'C', NULL, 0, "Print output for each CPU separately" }, - { "frequency", 'f', "FREQUENCY", 0, "Sample with a certain frequency" }, - { "runqocc", 'O', NULL, 0, "Report run queue occupancy" }, - { "timestamp", 'T', NULL, 0, "Include timestamp on output" }, - { "verbose", 'v', NULL, 0, "Verbose debug output" }, - { NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" }, - {}, -}; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - static int pos_args; - - switch (key) { - case 'h': - argp_state_help(state, stderr, ARGP_HELP_STD_HELP); - break; - case 'v': - env.verbose = true; - break; - case 'C': - env.per_cpu = true; - break; - case 'O': - env.runqocc = true; - break; - case 'T': - env.timestamp = true; - break; - case 'f': - errno = 0; - env.freq = strtol(arg, NULL, 10); - if (errno || env.freq <= 0) { - fprintf(stderr, "Invalid freq (in hz): %s\n", arg); - argp_usage(state); - } - break; - case ARGP_KEY_ARG: - errno = 0; - if (pos_args == 0) { - env.interval = strtol(arg, NULL, 10); - if (errno) { - fprintf(stderr, "invalid internal\n"); - argp_usage(state); - } - } else if (pos_args == 1) { - env.times = strtol(arg, NULL, 10); - if (errno) { - fprintf(stderr, "invalid times\n"); - argp_usage(state); - } - } else { - fprintf(stderr, - "unrecognized positional argument: %s\n", arg); - argp_usage(state); - } - pos_args++; - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static int nr_cpus; - -static int open_and_attach_perf_event(int freq, struct bpf_program *prog, - struct bpf_link *links[]) -{ - struct perf_event_attr attr = { - .type = PERF_TYPE_SOFTWARE, - .freq = 1, - .sample_period = freq, - .config = PERF_COUNT_SW_CPU_CLOCK, - }; - int i, fd; - - for (i = 0; i < nr_cpus; i++) { - fd = syscall(__NR_perf_event_open, &attr, -1, i, -1, 0); - if (fd < 0) { - /* Ignore CPU that is offline */ - if (errno == ENODEV) - continue; - fprintf(stderr, "failed to init perf sampling: %s\n", - strerror(errno)); - return -1; - } - links[i] = bpf_program__attach_perf_event(prog, fd); - if (!links[i]) { - fprintf(stderr, "failed to attach perf event on cpu: %d\n", i); - close(fd); - return -1; - } - } - - return 0; -} - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - if (level == LIBBPF_DEBUG && !env.verbose) - return 0; - return vfprintf(stderr, format, args); -} - -static void sig_handler(int sig) -{ - exiting = true; -} - -static struct hist zero; - -static void print_runq_occupancy(int hist_fd) -{ - struct hist hist; - int slot, i = 0; - float runqocc; - - do { - __u64 samples, idle = 0, queued = 0, total = 0, meanlen = 0; - bpf_map_lookup_elem(hist_fd, &i, &hist); - bpf_map_update_elem(hist_fd, &i, &zero, BPF_ANY); - for (slot = 0; slot < MAX_SLOTS; slot++) { - __u64 val = hist.slots[slot]; - - if (slot == 0) - idle += val; - else { - total += val * slot; - queued += val; - } - } - samples = idle + queued; - runqocc = queued * 1.0 / max(1ULL, samples); - meanlen = total / max(1ULL, samples); - if (env.per_cpu) - printf("runqocc, CPU %-3d %6.2f%%, AVGlen %lld\n", i, - 100 * runqocc, meanlen); - else - printf("runqocc: %0.2f%%, AVGlen %lld\n", 100 * runqocc, meanlen); - } while (env.per_cpu && ++i < nr_cpus); -} - -static void print_linear_hists(int hist_fd) -{ - struct hist hist; - int i = 0; - - do { - bpf_map_lookup_elem(hist_fd, &i, &hist); - bpf_map_update_elem(hist_fd, &i, &zero, BPF_ANY); - //hist = bss->hists[i]; - //bss->hists[i] = zero; - if (env.per_cpu) - printf("cpu = %d\n", i); - print_linear_hist(hist.slots, MAX_SLOTS, 0, 1, "runqlen"); - } while (env.per_cpu && ++i < nr_cpus); -} - -int main(int argc, char **argv) -{ - static const struct argp argp = { - .options = opts, - .parser = parse_arg, - .doc = argp_program_doc, - }; - struct bpf_link *links[MAX_CPU_NR] = {}; - struct runqlen_bpf *obj; - struct tm *tm; - char ts[32]; - int err, i, hist_fd, arg_fd, arg_idx = 0; - time_t t; - - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - - //libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - libbpf_set_print(libbpf_print_fn); - - nr_cpus = libbpf_num_possible_cpus(); - if (nr_cpus < 0) { - printf("failed to get # of possible cpus: '%s'!\n", - strerror(-nr_cpus)); - return 1; - } - if (nr_cpus > MAX_CPU_NR) { - fprintf(stderr, "the number of cpu cores is too big, please " - "increase MAX_CPU_NR's value and recompile"); - return 1; - } - - obj = runqlen_bpf__open(); - if (!obj) { - fprintf(stderr, "failed to open BPF object\n"); - return 1; - } - - /* initialize global data (filtering options) */ - //obj->rodata->targ_per_cpu = env.per_cpu; - - err = runqlen_bpf__load(obj); - if (err) { - fprintf(stderr, "failed to load BPF object: %d\n", err); - goto cleanup; - } - - arg_fd = bpf_map__fd(obj->maps.args_map); - bpf_map_update_elem(arg_fd, &arg_idx, &env.per_cpu, BPF_ANY); - - err = open_and_attach_perf_event(env.freq, obj->progs.do_sample, links); - if (err) - goto cleanup; - - printf("Sampling run queue length... Hit Ctrl-C to end.\n"); - - signal(SIGINT, sig_handler); - - hist_fd = bpf_map__fd(obj->maps.hist_map); - while (1) { - sleep(env.interval); - printf("\n"); - - if (env.timestamp) { - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - printf("%-8s\n", ts); - } - - if (env.runqocc) - print_runq_occupancy(hist_fd); - else - print_linear_hists(hist_fd); - - if (exiting || --env.times == 0) - break; - } - -cleanup: - for (i = 0; i < nr_cpus; i++) - bpf_link__destroy(links[i]); - runqlen_bpf__destroy(obj); - - return err != 0; -} diff --git a/source/tools/monitor/sched/runqlen/runqlen.h b/source/tools/monitor/sched/runqlen/runqlen.h deleted file mode 100644 index 60527289..00000000 --- a/source/tools/monitor/sched/runqlen/runqlen.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -#ifndef __RUNQLEN_H -#define __RUNQLEN_H - -#define MAX_CPU_NR 128 -#define MAX_SLOTS 32 - -struct hist { - __u32 slots[MAX_SLOTS]; -}; - -#endif /* __RUNQLEN_H */ diff --git a/source/tools/monitor/sched/runqlen/trace_helpers.c b/source/tools/monitor/sched/runqlen/trace_helpers.c deleted file mode 100644 index 6dc755f0..00000000 --- a/source/tools/monitor/sched/runqlen/trace_helpers.c +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -// Copyright (c) 2020 Wenbo Zhang -// -// Based on ksyms improvements from Andrii Nakryiko, add more helpers. -// 28-Feb-2020 Wenbo Zhang Created this. -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "trace_helpers.h" -//#include "uprobe_helpers.h" -#define min(x, y) ({ \ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) - -static void print_stars(unsigned int val, unsigned int val_max, int width) -{ - int num_stars, num_spaces, i; - bool need_plus; - - num_stars = min(val, val_max) * width / val_max; - num_spaces = width - num_stars; - need_plus = val > val_max; - - for (i = 0; i < num_stars; i++) - printf("*"); - for (i = 0; i < num_spaces; i++) - printf(" "); - if (need_plus) - printf("+"); -} - -void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, - unsigned int step, const char *val_type) -{ - int i, stars_max = 40, idx_min = -1, idx_max = -1; - unsigned int val, val_max = 0; - - for (i = 0; i < vals_size; i++) { - val = vals[i]; - if (val > 0) { - idx_max = i; - if (idx_min < 0) - idx_min = i; - } - if (val > val_max) - val_max = val; - } - - if (idx_max < 0) - return; - - printf(" %-13s : count distribution\n", val_type); - for (i = idx_min; i <= idx_max; i++) { - val = vals[i]; - printf(" %-10d : %-8d |", base + i * step, val); - print_stars(val, val_max, stars_max); - printf("|\n"); - } -} diff --git a/source/tools/monitor/sched/runqlen/trace_helpers.h b/source/tools/monitor/sched/runqlen/trace_helpers.h deleted file mode 100644 index 98fd640f..00000000 --- a/source/tools/monitor/sched/runqlen/trace_helpers.h +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -#ifndef __TRACE_HELPERS_H -#define __TRACE_HELPERS_H - -#include - -#define NSEC_PER_SEC 1000000000ULL - -struct ksym { - const char *name; - unsigned long addr; -}; - -struct ksyms; - -struct ksyms *ksyms__load(void); -void ksyms__free(struct ksyms *ksyms); -const struct ksym *ksyms__map_addr(const struct ksyms *ksyms, - unsigned long addr); -const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms, - const char *name); - -struct sym { - const char *name; - unsigned long start; - unsigned long size; -}; - -struct syms; - -struct syms *syms__load_pid(int tgid); -struct syms *syms__load_file(const char *fname); -void syms__free(struct syms *syms); -const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr); - -struct syms_cache; - -struct syms_cache *syms_cache__new(int nr); -struct syms *syms_cache__get_syms(struct syms_cache *syms_cache, int tgid); -void syms_cache__free(struct syms_cache *syms_cache); - -struct partition { - char *name; - unsigned int dev; -}; - -struct partitions; - -struct partitions *partitions__load(void); -void partitions__free(struct partitions *partitions); -const struct partition * -partitions__get_by_dev(const struct partitions *partitions, unsigned int dev); -const struct partition * -partitions__get_by_name(const struct partitions *partitions, const char *name); - -void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type); -void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, - unsigned int step, const char *val_type); - -unsigned long long get_ktime_ns(void); - -bool is_kernel_module(const char *name); - -/* - * When attempting to use kprobe/kretprobe, please check out new fentry/fexit - * probes, as they provide better performance and usability. But in some - * situations we have to fallback to kprobe/kretprobe probes. This helper - * is used to detect fentry/fexit support for the specified kernel function. - * - * 1. A gap between kernel versions, kernel BTF is exposed - * starting from 5.4 kernel. but fentry/fexit is actually - * supported starting from 5.5. - * 2. Whether kernel supports module BTF or not - * - * *name* is the name of a kernel function to be attached to, which can be - * from vmlinux or a kernel module. - * *mod* is a hint that indicates the *name* may reside in module BTF, - * if NULL, it means *name* belongs to vmlinux. - */ -bool fentry_exists(const char *name, const char *mod); - -/* - * The name of a kernel function to be attached to may be changed between - * kernel releases. This helper is used to confirm whether the target kernel - * uses a certain function name before attaching. - * - * It is achieved by scaning - * /sys/kernel/debug/tracing/available_filter_functions - * If this file does not exist, it fallbacks to parse /proc/kallsyms, - * which is slower. - */ -bool kprobe_exists(const char *name); - -bool vmlinux_btf_exists(void); -bool module_btf_exists(const char *mod); - -#endif /* __TRACE_HELPERS_H */ diff --git a/source/tools/monitor/sched/runqlen/uprobe_helpers.h b/source/tools/monitor/sched/runqlen/uprobe_helpers.h deleted file mode 100644 index 47f77bb2..00000000 --- a/source/tools/monitor/sched/runqlen/uprobe_helpers.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* Copyright (c) 2021 Google LLC. */ -#ifndef __UPROBE_HELPERS_H -#define __UPROBE_HELPERS_H - -#include -#include -#include - -int get_pid_binary_path(pid_t pid, char *path, size_t path_sz); -int get_pid_lib_path(pid_t pid, const char *lib, char *path, size_t path_sz); -int resolve_binary_path(const char *binary, pid_t pid, char *path, size_t path_sz); -off_t get_elf_func_offset(const char *path, const char *func); -Elf *open_elf(const char *path, int *fd_close); -Elf *open_elf_by_fd(int fd); -void close_elf(Elf *e, int fd_close); - -#endif /* __UPROBE_HELPERS_H */ -- Gitee From 1835b2435bff893552de152cad0a64e192846565 Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 11:34:48 +0800 Subject: [PATCH 04/10] Revert "sched/runqlen: Add README doc" This reverts commit fd07a2cf49c6a1441376b97b2f868fe68663d607. --- source/tools/monitor/sched/runqlen/README.txt | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 source/tools/monitor/sched/runqlen/README.txt diff --git a/source/tools/monitor/sched/runqlen/README.txt b/source/tools/monitor/sched/runqlen/README.txt deleted file mode 100644 index c1f84e68..00000000 --- a/source/tools/monitor/sched/runqlen/README.txt +++ /dev/null @@ -1,55 +0,0 @@ -1 What is runqlen? -Summarize scheduler run queue length as a histogram. - - -2 Usage of runqlen -USAGE: runqlen [--help] [-C] [-O] [-T] [-f FREQUENCY] [interval] [count] - -EXAMPLES: - runqlen # summarize run queue length as a histogram - runqlen 1 10 # print 1 second summaries, 10 times - runqlen -T 1 # 1s summaries and timestamps - runqlen -O # report run queue occupancy - runqlen -C # show each CPU separately - runqlen -f 199 # sample at 199HZ - - -C, --cpus Print output for each CPU separately - -f, --frequency=FREQUENCY Sample with a certain frequency - -O, --runqocc Report run queue occupancy - -T, --timestamp Include timestamp on output - -v, --verbose Verbose debug output - -?, --help Give this help list - --usage Give a short usage message - -V, --version Print program version - -3 Example -3.1 perf the run queue occupancy 2 times every 5 seconds -sudo sysak runqlen 5 2 -C -T -O - -16:06:54 -runqocc, CPU 0 0.00%, AVGlen 0 -runqocc, CPU 1 0.00%, AVGlen 0 -runqocc, CPU 2 0.00%, AVGlen 0 -runqocc, CPU 3 0.00%, AVGlen 0 - -16:06:55 -runqocc, CPU 0 0.00%, AVGlen 0 -runqocc, CPU 1 0.00%, AVGlen 0 -runqocc, CPU 2 0.00%, AVGlen 0 -runqocc, CPU 3 0.00%, AVGlen 0 - -3.2 perf the run queue histogram 1 times every 5 seconds -sudo sysak runqlen 5 2 -C -T -O -16:34:56 -cpu = 0 - runqlen : count distribution - 0 : 495 |****************************************| -cpu = 1 - runqlen : count distribution - 0 : 495 |****************************************| -cpu = 2 - runqlen : count distribution - 0 : 495 |****************************************| -cpu = 3 - runqlen : count distribution - 0 : 495 |****************************************| -- Gitee From d039b0c233eb7bb9d6f87cd9acf8ee7b3837d9c9 Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 11:58:39 +0800 Subject: [PATCH 05/10] runlatency: Refactoring the code and directory structure Combine the json_dump and sh into one directory. Signed-off-by: Hailong Liu --- .../tools/monitor/sched/runlatency/Makefile | 8 +- .../{json_dump/src => }/json_dump.c | 31 +++-- .../sched/runlatency/json_dump/Makefile | 1 - .../runlatency/json_dump/include/parser.h | 6 - .../sched/runlatency/json_dump/src/Makefile | 7 - .../runlatency/{json_dump/src => }/parser.c | 35 +++-- .../tools/monitor/sched/runlatency/parser.h | 7 + .../monitor/sched/runlatency/runlatency.c | 130 ++++++++++++++++++ .../monitor/sched/runlatency/sh/Makefile | 4 - .../monitor/sched/runlatency/sh/runlatency.sh | 67 --------- 10 files changed, 189 insertions(+), 107 deletions(-) rename source/tools/monitor/sched/runlatency/{json_dump/src => }/json_dump.c (60%) delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/Makefile delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/include/parser.h delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/src/Makefile rename source/tools/monitor/sched/runlatency/{json_dump/src => }/parser.c (85%) create mode 100644 source/tools/monitor/sched/runlatency/parser.h create mode 100644 source/tools/monitor/sched/runlatency/runlatency.c delete mode 100644 source/tools/monitor/sched/runlatency/sh/Makefile delete mode 100755 source/tools/monitor/sched/runlatency/sh/runlatency.sh diff --git a/source/tools/monitor/sched/runlatency/Makefile b/source/tools/monitor/sched/runlatency/Makefile index 6a58b3a5..d1fd7933 100644 --- a/source/tools/monitor/sched/runlatency/Makefile +++ b/source/tools/monitor/sched/runlatency/Makefile @@ -1 +1,7 @@ -include $(SRC)/mk/sub.mk +target := runlatency +DEPEND := "prev{-e modin};post{-d modun}" +mods := runlatency.o json_dump.o parser.o +EXTRA_CFLAGS += -I ./include +EXTRA_LDFLAGS += -lsysak + +include $(SRC)/mk/csrc.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c b/source/tools/monitor/sched/runlatency/json_dump.c similarity index 60% rename from source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c rename to source/tools/monitor/sched/runlatency/json_dump.c index 011d0d34..904666c1 100644 --- a/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c +++ b/source/tools/monitor/sched/runlatency/json_dump.c @@ -5,11 +5,12 @@ #include #include #include +#include #include "parser.h" -#define IRQOFF_FILE "/proc/runlatency/irqoff/latency" -#define NOSCH_FILE "/proc/runlatency/nosch/stack_trace" -#define RUNQ_FILE "/proc/runlatency/runqlat/runqlat" +#define IRQOFF_FILE "/proc/sysak/runlatency/irqoff/latency" +#define NOSCH_FILE "/proc/sysak/runlatency/nosch/stack_trace" +#define RUNQ_FILE "/proc/sysak/runlatency/runqlat/runqlat" #define STREAM_SIZE (128 * 1024) @@ -19,6 +20,8 @@ int read_file(char* path, char* s) int size; if (fd < 0) { + fprintf(stderr, "%s :open %s\n", + strerror(errno), path); return fd; } @@ -33,6 +36,8 @@ int clear_file(char *path) int size; if (fd < 0) { + fprintf(stderr, "%s :open %s\n", + strerror(errno), path); return fd; } @@ -41,29 +46,35 @@ int clear_file(char *path) return size; } -int main(void) +int pasre_dump(char *file) { char *s; int ret; + FILE *outf = NULL; s = malloc(STREAM_SIZE); if (s == NULL) { return -ENOMEM; } - + if (file) { + outf = fopen(file, "a+"); + if (!outf) + fprintf(stderr, "%s :fopen %s\n", + strerror(errno), file); + } ret = read_file(IRQOFF_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_irqoff(s, ret); + parser_irqoff(s, ret, outf); ret = read_file(NOSCH_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_nosch(s, ret); + parser_nosch(s, ret, outf); clear_file(NOSCH_FILE); ret = read_file(RUNQ_FILE, s); @@ -71,13 +82,17 @@ int main(void) goto failed; } s[ret] = '\0'; - parser_runq(s, ret); + parser_runq(s, ret, outf); clear_file(RUNQ_FILE); free(s); + if (outf) + fclose(outf); return 0; failed: free(s); + if (outf) + fclose(outf); return ret; } diff --git a/source/tools/monitor/sched/runlatency/json_dump/Makefile b/source/tools/monitor/sched/runlatency/json_dump/Makefile deleted file mode 100644 index 6a58b3a5..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(SRC)/mk/sub.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/include/parser.h b/source/tools/monitor/sched/runlatency/json_dump/include/parser.h deleted file mode 100644 index 199be029..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/include/parser.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PARSER_H -#define _PARSER_H -int parser_irqoff(char *stream, int size); -int parser_nosch(char *stream, int size); -int parser_runq(char *stream, int size); -#endif diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/Makefile b/source/tools/monitor/sched/runlatency/json_dump/src/Makefile deleted file mode 100644 index ee4f7386..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -target := rt_json_dump -mods := json_dump.o parser.o - -EXTRA_CFLAGS += -I ../include -EXTRA_LDFLAGS += -lsysak - -include $(SRC)/mk/csrc.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/parser.c b/source/tools/monitor/sched/runlatency/parser.c similarity index 85% rename from source/tools/monitor/sched/runlatency/json_dump/src/parser.c rename to source/tools/monitor/sched/runlatency/parser.c index 9bd749b3..971dd248 100644 --- a/source/tools/monitor/sched/runlatency/json_dump/src/parser.c +++ b/source/tools/monitor/sched/runlatency/parser.c @@ -157,7 +157,7 @@ static char* stack_get(char* beg, cJSON *parent) return s + 1; // enter + 1 } -static char* body_irqoff(char* beg, enum IRQOFF stat) +static char* body_irqoff(char* beg, enum IRQOFF stat, FILE *file) { char *s; cJSON *root; @@ -178,13 +178,16 @@ static char* body_irqoff(char* beg, enum IRQOFF stat) s = stack_get(s, root); out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_irqoff(char *stream, int size) +int parser_irqoff(char *stream, int size, FILE *file) { char *sBeg, *sCursor; enum IRQOFF stat = HARD_IRQ; @@ -195,18 +198,18 @@ int parser_irqoff(char *stream, int size) sBeg = sCursor; while (sBeg[1] != 's') { - sBeg = body_irqoff(sBeg, stat); + sBeg = body_irqoff(sBeg, stat, file); } stat = SOFT_IRQ; sBeg = accept(sBeg, '\n'); while (sBeg[0] != '\0') { - sBeg = body_irqoff(sBeg, stat); + sBeg = body_irqoff(sBeg, stat, file); } return 0; } -static char* body_nosch(char* beg) +static char* body_nosch(char* beg, FILE *file) { char *s; cJSON *root; @@ -219,24 +222,27 @@ static char* body_nosch(char* beg) s = stack_get(s, root); out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_nosch(char *stream, int size) +int parser_nosch(char *stream, int size, FILE *file) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_nosch(sBeg); + sBeg = body_nosch(sBeg, file); } return 0; } -static char* body_runq(char* beg) +static char* body_runq(char* beg, FILE *file) { char *s = beg; cJSON *root, *arr; @@ -255,19 +261,22 @@ static char* body_runq(char* beg) } out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s + 1; } -int parser_runq(char *stream, int size) +int parser_runq(char *stream, int size, FILE *file) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_runq(sBeg); + sBeg = body_runq(sBeg, file); } return 0; } diff --git a/source/tools/monitor/sched/runlatency/parser.h b/source/tools/monitor/sched/runlatency/parser.h new file mode 100644 index 00000000..57baa7bc --- /dev/null +++ b/source/tools/monitor/sched/runlatency/parser.h @@ -0,0 +1,7 @@ +#ifndef _PARSER_H +#define _PARSER_H +int parser_irqoff(char *stream, int size, FILE *file); +int parser_nosch(char *stream, int size, FILE *file); +int parser_runq(char *stream, int size, FILE *file); +int pasre_dump(char *file); +#endif diff --git a/source/tools/monitor/sched/runlatency/runlatency.c b/source/tools/monitor/sched/runlatency/runlatency.c new file mode 100644 index 00000000..e319568d --- /dev/null +++ b/source/tools/monitor/sched/runlatency/runlatency.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include "parser.h" + +#define OPT_MASK 0x7 +#define OPT_IRQ 0x1 +#define OPT_SCH 0x2 +#define OPT_LAT 0x4 +#define MAX_CMD 3 +#define MAX_CMD_LEN 128 + +char *firq = "/proc/sysak/runlatency/irqoff/enable"; +char *fsch = "/proc/sysak/runlatency/nosch/enable"; +char *flat = "/proc/sysak/runlatency/runqlat/pid"; + +static void usage(char *prog) +{ + const char *str = + " Usage: %s [OPTIONS]\n" + " Options:\n" + " -f the output file\n" + " -r read the result to file or stdio\n" + " -d disable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" + " -e enable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" + "\n"; + + fprintf(stderr, str, prog); + exit(EXIT_FAILURE); +} + +char *cmdstr[3]; + +int switch_func(int opt, int enable, int arg) +{ + FILE *fp; + int param[3], ret, index = 0; + int optalign; + char cmd[MAX_CMD_LEN] = {0}; + + + optalign = opt & OPT_MASK; + + if (optalign & OPT_LAT) + param[2] = arg; + else + param[2] = enable; + + param[0] = param[1] = enable; + while (index < MAX_CMD) { + if (optalign & (1 << index)) { + snprintf(cmd, MAX_CMD_LEN, "echo %d > %s",param[index], cmdstr[index]); + /* fprintf(stderr, "debug_cmd:%s\n", cmd); */ + fp = popen(cmd, "r"); + if (!fp) { + ret = errno; + perror(cmd); + return ret; + } + optalign = optalign; + index++; + } + } +} + +int main(int argc, char *argv[]) +{ + char *refile = NULL; + int pid = -1, ret = 0, i, will_switch, enable; + int c, option_index, en_opt, dis_opt; + + opterr = 0; + dis_opt = en_opt = OPT_MASK; + + cmdstr[0] = firq; + cmdstr[1] = fsch; + cmdstr[2] = flat; + for (i = 0; i < MAX_CMD; i++) { + if (access(cmdstr[i], F_OK)) { + ret = errno; + fprintf(stderr, "%s:access() %s\n", + strerror(errno), cmdstr[i]); + return ret; + } + } + for (;;) { + c = getopt_long(argc, argv, "f:p:e::d::hr", + NULL /*long_options*/, &option_index); + + if (c == -1) + break; + switch (c) { + case 'f': + refile = optarg; + break; + case 'r': + pasre_dump(refile);//do something + break; + case 'p': + pid = atoi(optarg); + fprintf(stderr, "debug_p_pid=%d\n", pid); + break; + case 'e': + if (optarg) + en_opt = atoi(optarg); + fprintf(stderr, "debug_e_pid=%d\n", pid); + will_switch = 1; + enable = 1; + break; + case 'd': + if (optarg) + dis_opt = atoi(optarg); + will_switch = 1; + enable = 0; + break; + case 'h': + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } + if (will_switch) + ret = switch_func(dis_opt, enable, pid); + + return ret; +} diff --git a/source/tools/monitor/sched/runlatency/sh/Makefile b/source/tools/monitor/sched/runlatency/sh/Makefile deleted file mode 100644 index 255d37a6..00000000 --- a/source/tools/monitor/sched/runlatency/sh/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -target := runlatency -DEPEND := "prev{-e modin};post{-d modun}" - -include $(SRC)/mk/sh.mk diff --git a/source/tools/monitor/sched/runlatency/sh/runlatency.sh b/source/tools/monitor/sched/runlatency/sh/runlatency.sh deleted file mode 100755 index 5c6d9625..00000000 --- a/source/tools/monitor/sched/runlatency/sh/runlatency.sh +++ /dev/null @@ -1,67 +0,0 @@ -WORK_PATH=`dirname $0`/ -pid=-1 - -runlatency_enable() { - echo 1 > /proc/sysak/runlatency/irqoff/enable - echo 1 > /proc/sysak/runlatency/nosch/enable - echo $pid > /proc/sysak/runlatency/runqlat/pid -} - -runlatency_disable() { - echo 0 > /proc/sysak/runlatency/irqoff/enable - echo 0 > /proc/sysak/runlatency/nosch/enable - echo -1 > /proc/sysak/runlatency/runqlat/pid -} - -runlatency_report() { - - if [ -z "$outfile" ]; then - $WORK_PATH/rt_json_dump - else - $WORK_PATH/rt_json_dump >>$outfile - fi -} - -usage() { - echo "$0 -e|d" - echo " -e, enable" - echo " -d, disable" - echo " -r, report, default stdout if no outfile specified" - echo " -f, outfile for report" -} - -while getopts 'p:f:edrh' OPT; do - case $OPT in - "h") - usage - exit 0 - ;; - "p") - pid=$OPTARG - ;; - "e") - runlatency_enable - exit 0 - ;; - "d") - runlatency_disable - exit 0 - ;; - "r") - report="true" - ;; - "f") - outfile=$OPTARG - ;; - *) - echo this - usage - exit -1 - ;; - esac -done - -if [ $report = "true" ];then - runlatency_report -fi - -- Gitee From b2fbec9f86256f985026d92e6682b340920e3f2d Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 12:00:14 +0800 Subject: [PATCH 06/10] Revert "runlatency: Refactoring the code and directory structure" This reverts commit d039b0c233eb7bb9d6f87cd9acf8ee7b3837d9c9. --- .../tools/monitor/sched/runlatency/Makefile | 8 +- .../sched/runlatency/json_dump/Makefile | 1 + .../runlatency/json_dump/include/parser.h | 6 + .../sched/runlatency/json_dump/src/Makefile | 7 + .../{ => json_dump/src}/json_dump.c | 31 ++--- .../runlatency/{ => json_dump/src}/parser.c | 35 ++--- .../tools/monitor/sched/runlatency/parser.h | 7 - .../monitor/sched/runlatency/runlatency.c | 130 ------------------ .../monitor/sched/runlatency/sh/Makefile | 4 + .../monitor/sched/runlatency/sh/runlatency.sh | 67 +++++++++ 10 files changed, 107 insertions(+), 189 deletions(-) create mode 100644 source/tools/monitor/sched/runlatency/json_dump/Makefile create mode 100644 source/tools/monitor/sched/runlatency/json_dump/include/parser.h create mode 100644 source/tools/monitor/sched/runlatency/json_dump/src/Makefile rename source/tools/monitor/sched/runlatency/{ => json_dump/src}/json_dump.c (60%) rename source/tools/monitor/sched/runlatency/{ => json_dump/src}/parser.c (85%) delete mode 100644 source/tools/monitor/sched/runlatency/parser.h delete mode 100644 source/tools/monitor/sched/runlatency/runlatency.c create mode 100644 source/tools/monitor/sched/runlatency/sh/Makefile create mode 100755 source/tools/monitor/sched/runlatency/sh/runlatency.sh diff --git a/source/tools/monitor/sched/runlatency/Makefile b/source/tools/monitor/sched/runlatency/Makefile index d1fd7933..6a58b3a5 100644 --- a/source/tools/monitor/sched/runlatency/Makefile +++ b/source/tools/monitor/sched/runlatency/Makefile @@ -1,7 +1 @@ -target := runlatency -DEPEND := "prev{-e modin};post{-d modun}" -mods := runlatency.o json_dump.o parser.o -EXTRA_CFLAGS += -I ./include -EXTRA_LDFLAGS += -lsysak - -include $(SRC)/mk/csrc.mk +include $(SRC)/mk/sub.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/Makefile b/source/tools/monitor/sched/runlatency/json_dump/Makefile new file mode 100644 index 00000000..6a58b3a5 --- /dev/null +++ b/source/tools/monitor/sched/runlatency/json_dump/Makefile @@ -0,0 +1 @@ +include $(SRC)/mk/sub.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/include/parser.h b/source/tools/monitor/sched/runlatency/json_dump/include/parser.h new file mode 100644 index 00000000..199be029 --- /dev/null +++ b/source/tools/monitor/sched/runlatency/json_dump/include/parser.h @@ -0,0 +1,6 @@ +#ifndef _PARSER_H +#define _PARSER_H +int parser_irqoff(char *stream, int size); +int parser_nosch(char *stream, int size); +int parser_runq(char *stream, int size); +#endif diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/Makefile b/source/tools/monitor/sched/runlatency/json_dump/src/Makefile new file mode 100644 index 00000000..ee4f7386 --- /dev/null +++ b/source/tools/monitor/sched/runlatency/json_dump/src/Makefile @@ -0,0 +1,7 @@ +target := rt_json_dump +mods := json_dump.o parser.o + +EXTRA_CFLAGS += -I ../include +EXTRA_LDFLAGS += -lsysak + +include $(SRC)/mk/csrc.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump.c b/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c similarity index 60% rename from source/tools/monitor/sched/runlatency/json_dump.c rename to source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c index 904666c1..011d0d34 100644 --- a/source/tools/monitor/sched/runlatency/json_dump.c +++ b/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c @@ -5,12 +5,11 @@ #include #include #include -#include #include "parser.h" -#define IRQOFF_FILE "/proc/sysak/runlatency/irqoff/latency" -#define NOSCH_FILE "/proc/sysak/runlatency/nosch/stack_trace" -#define RUNQ_FILE "/proc/sysak/runlatency/runqlat/runqlat" +#define IRQOFF_FILE "/proc/runlatency/irqoff/latency" +#define NOSCH_FILE "/proc/runlatency/nosch/stack_trace" +#define RUNQ_FILE "/proc/runlatency/runqlat/runqlat" #define STREAM_SIZE (128 * 1024) @@ -20,8 +19,6 @@ int read_file(char* path, char* s) int size; if (fd < 0) { - fprintf(stderr, "%s :open %s\n", - strerror(errno), path); return fd; } @@ -36,8 +33,6 @@ int clear_file(char *path) int size; if (fd < 0) { - fprintf(stderr, "%s :open %s\n", - strerror(errno), path); return fd; } @@ -46,35 +41,29 @@ int clear_file(char *path) return size; } -int pasre_dump(char *file) +int main(void) { char *s; int ret; - FILE *outf = NULL; s = malloc(STREAM_SIZE); if (s == NULL) { return -ENOMEM; } - if (file) { - outf = fopen(file, "a+"); - if (!outf) - fprintf(stderr, "%s :fopen %s\n", - strerror(errno), file); - } + ret = read_file(IRQOFF_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_irqoff(s, ret, outf); + parser_irqoff(s, ret); ret = read_file(NOSCH_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_nosch(s, ret, outf); + parser_nosch(s, ret); clear_file(NOSCH_FILE); ret = read_file(RUNQ_FILE, s); @@ -82,17 +71,13 @@ int pasre_dump(char *file) goto failed; } s[ret] = '\0'; - parser_runq(s, ret, outf); + parser_runq(s, ret); clear_file(RUNQ_FILE); free(s); - if (outf) - fclose(outf); return 0; failed: free(s); - if (outf) - fclose(outf); return ret; } diff --git a/source/tools/monitor/sched/runlatency/parser.c b/source/tools/monitor/sched/runlatency/json_dump/src/parser.c similarity index 85% rename from source/tools/monitor/sched/runlatency/parser.c rename to source/tools/monitor/sched/runlatency/json_dump/src/parser.c index 971dd248..9bd749b3 100644 --- a/source/tools/monitor/sched/runlatency/parser.c +++ b/source/tools/monitor/sched/runlatency/json_dump/src/parser.c @@ -157,7 +157,7 @@ static char* stack_get(char* beg, cJSON *parent) return s + 1; // enter + 1 } -static char* body_irqoff(char* beg, enum IRQOFF stat, FILE *file) +static char* body_irqoff(char* beg, enum IRQOFF stat) { char *s; cJSON *root; @@ -178,16 +178,13 @@ static char* body_irqoff(char* beg, enum IRQOFF stat, FILE *file) s = stack_get(s, root); out = cJSON_Print(root); - if (!file) - printf("%s\n", out); - else - fprintf(file, "%s\n", out); + printf("%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_irqoff(char *stream, int size, FILE *file) +int parser_irqoff(char *stream, int size) { char *sBeg, *sCursor; enum IRQOFF stat = HARD_IRQ; @@ -198,18 +195,18 @@ int parser_irqoff(char *stream, int size, FILE *file) sBeg = sCursor; while (sBeg[1] != 's') { - sBeg = body_irqoff(sBeg, stat, file); + sBeg = body_irqoff(sBeg, stat); } stat = SOFT_IRQ; sBeg = accept(sBeg, '\n'); while (sBeg[0] != '\0') { - sBeg = body_irqoff(sBeg, stat, file); + sBeg = body_irqoff(sBeg, stat); } return 0; } -static char* body_nosch(char* beg, FILE *file) +static char* body_nosch(char* beg) { char *s; cJSON *root; @@ -222,27 +219,24 @@ static char* body_nosch(char* beg, FILE *file) s = stack_get(s, root); out = cJSON_Print(root); - if (!file) - printf("%s\n", out); - else - fprintf(file, "%s\n", out); + printf("%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_nosch(char *stream, int size, FILE *file) +int parser_nosch(char *stream, int size) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_nosch(sBeg, file); + sBeg = body_nosch(sBeg); } return 0; } -static char* body_runq(char* beg, FILE *file) +static char* body_runq(char* beg) { char *s = beg; cJSON *root, *arr; @@ -261,22 +255,19 @@ static char* body_runq(char* beg, FILE *file) } out = cJSON_Print(root); - if (!file) - printf("%s\n", out); - else - fprintf(file, "%s\n", out); + printf("%s\n", out); free(out); cJSON_Delete(root); return s + 1; } -int parser_runq(char *stream, int size, FILE *file) +int parser_runq(char *stream, int size) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_runq(sBeg, file); + sBeg = body_runq(sBeg); } return 0; } diff --git a/source/tools/monitor/sched/runlatency/parser.h b/source/tools/monitor/sched/runlatency/parser.h deleted file mode 100644 index 57baa7bc..00000000 --- a/source/tools/monitor/sched/runlatency/parser.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _PARSER_H -#define _PARSER_H -int parser_irqoff(char *stream, int size, FILE *file); -int parser_nosch(char *stream, int size, FILE *file); -int parser_runq(char *stream, int size, FILE *file); -int pasre_dump(char *file); -#endif diff --git a/source/tools/monitor/sched/runlatency/runlatency.c b/source/tools/monitor/sched/runlatency/runlatency.c deleted file mode 100644 index e319568d..00000000 --- a/source/tools/monitor/sched/runlatency/runlatency.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "parser.h" - -#define OPT_MASK 0x7 -#define OPT_IRQ 0x1 -#define OPT_SCH 0x2 -#define OPT_LAT 0x4 -#define MAX_CMD 3 -#define MAX_CMD_LEN 128 - -char *firq = "/proc/sysak/runlatency/irqoff/enable"; -char *fsch = "/proc/sysak/runlatency/nosch/enable"; -char *flat = "/proc/sysak/runlatency/runqlat/pid"; - -static void usage(char *prog) -{ - const char *str = - " Usage: %s [OPTIONS]\n" - " Options:\n" - " -f the output file\n" - " -r read the result to file or stdio\n" - " -d disable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" - " -e enable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" - "\n"; - - fprintf(stderr, str, prog); - exit(EXIT_FAILURE); -} - -char *cmdstr[3]; - -int switch_func(int opt, int enable, int arg) -{ - FILE *fp; - int param[3], ret, index = 0; - int optalign; - char cmd[MAX_CMD_LEN] = {0}; - - - optalign = opt & OPT_MASK; - - if (optalign & OPT_LAT) - param[2] = arg; - else - param[2] = enable; - - param[0] = param[1] = enable; - while (index < MAX_CMD) { - if (optalign & (1 << index)) { - snprintf(cmd, MAX_CMD_LEN, "echo %d > %s",param[index], cmdstr[index]); - /* fprintf(stderr, "debug_cmd:%s\n", cmd); */ - fp = popen(cmd, "r"); - if (!fp) { - ret = errno; - perror(cmd); - return ret; - } - optalign = optalign; - index++; - } - } -} - -int main(int argc, char *argv[]) -{ - char *refile = NULL; - int pid = -1, ret = 0, i, will_switch, enable; - int c, option_index, en_opt, dis_opt; - - opterr = 0; - dis_opt = en_opt = OPT_MASK; - - cmdstr[0] = firq; - cmdstr[1] = fsch; - cmdstr[2] = flat; - for (i = 0; i < MAX_CMD; i++) { - if (access(cmdstr[i], F_OK)) { - ret = errno; - fprintf(stderr, "%s:access() %s\n", - strerror(errno), cmdstr[i]); - return ret; - } - } - for (;;) { - c = getopt_long(argc, argv, "f:p:e::d::hr", - NULL /*long_options*/, &option_index); - - if (c == -1) - break; - switch (c) { - case 'f': - refile = optarg; - break; - case 'r': - pasre_dump(refile);//do something - break; - case 'p': - pid = atoi(optarg); - fprintf(stderr, "debug_p_pid=%d\n", pid); - break; - case 'e': - if (optarg) - en_opt = atoi(optarg); - fprintf(stderr, "debug_e_pid=%d\n", pid); - will_switch = 1; - enable = 1; - break; - case 'd': - if (optarg) - dis_opt = atoi(optarg); - will_switch = 1; - enable = 0; - break; - case 'h': - usage(argv[0]); - break; - default: - usage(argv[0]); - } - } - if (will_switch) - ret = switch_func(dis_opt, enable, pid); - - return ret; -} diff --git a/source/tools/monitor/sched/runlatency/sh/Makefile b/source/tools/monitor/sched/runlatency/sh/Makefile new file mode 100644 index 00000000..255d37a6 --- /dev/null +++ b/source/tools/monitor/sched/runlatency/sh/Makefile @@ -0,0 +1,4 @@ +target := runlatency +DEPEND := "prev{-e modin};post{-d modun}" + +include $(SRC)/mk/sh.mk diff --git a/source/tools/monitor/sched/runlatency/sh/runlatency.sh b/source/tools/monitor/sched/runlatency/sh/runlatency.sh new file mode 100755 index 00000000..5c6d9625 --- /dev/null +++ b/source/tools/monitor/sched/runlatency/sh/runlatency.sh @@ -0,0 +1,67 @@ +WORK_PATH=`dirname $0`/ +pid=-1 + +runlatency_enable() { + echo 1 > /proc/sysak/runlatency/irqoff/enable + echo 1 > /proc/sysak/runlatency/nosch/enable + echo $pid > /proc/sysak/runlatency/runqlat/pid +} + +runlatency_disable() { + echo 0 > /proc/sysak/runlatency/irqoff/enable + echo 0 > /proc/sysak/runlatency/nosch/enable + echo -1 > /proc/sysak/runlatency/runqlat/pid +} + +runlatency_report() { + + if [ -z "$outfile" ]; then + $WORK_PATH/rt_json_dump + else + $WORK_PATH/rt_json_dump >>$outfile + fi +} + +usage() { + echo "$0 -e|d" + echo " -e, enable" + echo " -d, disable" + echo " -r, report, default stdout if no outfile specified" + echo " -f, outfile for report" +} + +while getopts 'p:f:edrh' OPT; do + case $OPT in + "h") + usage + exit 0 + ;; + "p") + pid=$OPTARG + ;; + "e") + runlatency_enable + exit 0 + ;; + "d") + runlatency_disable + exit 0 + ;; + "r") + report="true" + ;; + "f") + outfile=$OPTARG + ;; + *) + echo this + usage + exit -1 + ;; + esac +done + +if [ $report = "true" ];then + runlatency_report +fi + -- Gitee From 22c6980ced577f21c87fe613ddfbad803ad6a8fe Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 13:08:39 +0800 Subject: [PATCH 07/10] lkm: fix compile error for proc.h When use lkm, we get some errors as follows: source/lib/internal/kernel_module/common/proc.h:126:2: error: #endif without #if #endif ^~~~~ Fix it. Signed-off-by: Hailong Liu --- source/lib/internal/kernel_module/common/proc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/lib/internal/kernel_module/common/proc.h b/source/lib/internal/kernel_module/common/proc.h index fdc0e523..cbf17a99 100644 --- a/source/lib/internal/kernel_module/common/proc.h +++ b/source/lib/internal/kernel_module/common/proc.h @@ -106,7 +106,6 @@ int __weak kstrtobool_from_user(const char __user *s, size_t count, bool *res) #define DEFINE_PROC_ATTRIBUTE_RO(name) \ DEFINE_PROC_ATTRIBUTE(name, NULL) #endif -#endif extern struct proc_dir_entry *sysak_proc_mkdir(const char *name); @@ -123,4 +122,4 @@ extern int sysak_remove_proc_subtree(const char *name); extern int sysak_proc_init(void); extern void sysak_proc_exit(void); -#endif \ No newline at end of file +#endif -- Gitee From 563d82ead4ec6a5efc7e47515b761c957cc493ba Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Thu, 24 Feb 2022 11:58:39 +0800 Subject: [PATCH 08/10] runlatency: Refactoring the code and directory structure Combine the json_dump and sh into one directory. Signed-off-by: Hailong Liu --- .../tools/monitor/sched/runlatency/Makefile | 8 +- .../{json_dump/src => }/json_dump.c | 31 +++-- .../sched/runlatency/json_dump/Makefile | 1 - .../runlatency/json_dump/include/parser.h | 6 - .../sched/runlatency/json_dump/src/Makefile | 7 - .../runlatency/{json_dump/src => }/parser.c | 35 +++-- .../tools/monitor/sched/runlatency/parser.h | 7 + .../monitor/sched/runlatency/runlatency.c | 130 ++++++++++++++++++ .../monitor/sched/runlatency/sh/Makefile | 4 - .../monitor/sched/runlatency/sh/runlatency.sh | 67 --------- 10 files changed, 189 insertions(+), 107 deletions(-) rename source/tools/monitor/sched/runlatency/{json_dump/src => }/json_dump.c (60%) delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/Makefile delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/include/parser.h delete mode 100644 source/tools/monitor/sched/runlatency/json_dump/src/Makefile rename source/tools/monitor/sched/runlatency/{json_dump/src => }/parser.c (85%) create mode 100644 source/tools/monitor/sched/runlatency/parser.h create mode 100644 source/tools/monitor/sched/runlatency/runlatency.c delete mode 100644 source/tools/monitor/sched/runlatency/sh/Makefile delete mode 100755 source/tools/monitor/sched/runlatency/sh/runlatency.sh diff --git a/source/tools/monitor/sched/runlatency/Makefile b/source/tools/monitor/sched/runlatency/Makefile index 6a58b3a5..d1fd7933 100644 --- a/source/tools/monitor/sched/runlatency/Makefile +++ b/source/tools/monitor/sched/runlatency/Makefile @@ -1 +1,7 @@ -include $(SRC)/mk/sub.mk +target := runlatency +DEPEND := "prev{-e modin};post{-d modun}" +mods := runlatency.o json_dump.o parser.o +EXTRA_CFLAGS += -I ./include +EXTRA_LDFLAGS += -lsysak + +include $(SRC)/mk/csrc.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c b/source/tools/monitor/sched/runlatency/json_dump.c similarity index 60% rename from source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c rename to source/tools/monitor/sched/runlatency/json_dump.c index 011d0d34..904666c1 100644 --- a/source/tools/monitor/sched/runlatency/json_dump/src/json_dump.c +++ b/source/tools/monitor/sched/runlatency/json_dump.c @@ -5,11 +5,12 @@ #include #include #include +#include #include "parser.h" -#define IRQOFF_FILE "/proc/runlatency/irqoff/latency" -#define NOSCH_FILE "/proc/runlatency/nosch/stack_trace" -#define RUNQ_FILE "/proc/runlatency/runqlat/runqlat" +#define IRQOFF_FILE "/proc/sysak/runlatency/irqoff/latency" +#define NOSCH_FILE "/proc/sysak/runlatency/nosch/stack_trace" +#define RUNQ_FILE "/proc/sysak/runlatency/runqlat/runqlat" #define STREAM_SIZE (128 * 1024) @@ -19,6 +20,8 @@ int read_file(char* path, char* s) int size; if (fd < 0) { + fprintf(stderr, "%s :open %s\n", + strerror(errno), path); return fd; } @@ -33,6 +36,8 @@ int clear_file(char *path) int size; if (fd < 0) { + fprintf(stderr, "%s :open %s\n", + strerror(errno), path); return fd; } @@ -41,29 +46,35 @@ int clear_file(char *path) return size; } -int main(void) +int pasre_dump(char *file) { char *s; int ret; + FILE *outf = NULL; s = malloc(STREAM_SIZE); if (s == NULL) { return -ENOMEM; } - + if (file) { + outf = fopen(file, "a+"); + if (!outf) + fprintf(stderr, "%s :fopen %s\n", + strerror(errno), file); + } ret = read_file(IRQOFF_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_irqoff(s, ret); + parser_irqoff(s, ret, outf); ret = read_file(NOSCH_FILE, s); if (ret < 0) { goto failed; } s[ret] = '\0'; - parser_nosch(s, ret); + parser_nosch(s, ret, outf); clear_file(NOSCH_FILE); ret = read_file(RUNQ_FILE, s); @@ -71,13 +82,17 @@ int main(void) goto failed; } s[ret] = '\0'; - parser_runq(s, ret); + parser_runq(s, ret, outf); clear_file(RUNQ_FILE); free(s); + if (outf) + fclose(outf); return 0; failed: free(s); + if (outf) + fclose(outf); return ret; } diff --git a/source/tools/monitor/sched/runlatency/json_dump/Makefile b/source/tools/monitor/sched/runlatency/json_dump/Makefile deleted file mode 100644 index 6a58b3a5..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(SRC)/mk/sub.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/include/parser.h b/source/tools/monitor/sched/runlatency/json_dump/include/parser.h deleted file mode 100644 index 199be029..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/include/parser.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PARSER_H -#define _PARSER_H -int parser_irqoff(char *stream, int size); -int parser_nosch(char *stream, int size); -int parser_runq(char *stream, int size); -#endif diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/Makefile b/source/tools/monitor/sched/runlatency/json_dump/src/Makefile deleted file mode 100644 index ee4f7386..00000000 --- a/source/tools/monitor/sched/runlatency/json_dump/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -target := rt_json_dump -mods := json_dump.o parser.o - -EXTRA_CFLAGS += -I ../include -EXTRA_LDFLAGS += -lsysak - -include $(SRC)/mk/csrc.mk diff --git a/source/tools/monitor/sched/runlatency/json_dump/src/parser.c b/source/tools/monitor/sched/runlatency/parser.c similarity index 85% rename from source/tools/monitor/sched/runlatency/json_dump/src/parser.c rename to source/tools/monitor/sched/runlatency/parser.c index 9bd749b3..971dd248 100644 --- a/source/tools/monitor/sched/runlatency/json_dump/src/parser.c +++ b/source/tools/monitor/sched/runlatency/parser.c @@ -157,7 +157,7 @@ static char* stack_get(char* beg, cJSON *parent) return s + 1; // enter + 1 } -static char* body_irqoff(char* beg, enum IRQOFF stat) +static char* body_irqoff(char* beg, enum IRQOFF stat, FILE *file) { char *s; cJSON *root; @@ -178,13 +178,16 @@ static char* body_irqoff(char* beg, enum IRQOFF stat) s = stack_get(s, root); out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_irqoff(char *stream, int size) +int parser_irqoff(char *stream, int size, FILE *file) { char *sBeg, *sCursor; enum IRQOFF stat = HARD_IRQ; @@ -195,18 +198,18 @@ int parser_irqoff(char *stream, int size) sBeg = sCursor; while (sBeg[1] != 's') { - sBeg = body_irqoff(sBeg, stat); + sBeg = body_irqoff(sBeg, stat, file); } stat = SOFT_IRQ; sBeg = accept(sBeg, '\n'); while (sBeg[0] != '\0') { - sBeg = body_irqoff(sBeg, stat); + sBeg = body_irqoff(sBeg, stat, file); } return 0; } -static char* body_nosch(char* beg) +static char* body_nosch(char* beg, FILE *file) { char *s; cJSON *root; @@ -219,24 +222,27 @@ static char* body_nosch(char* beg) s = stack_get(s, root); out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s; } -int parser_nosch(char *stream, int size) +int parser_nosch(char *stream, int size, FILE *file) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_nosch(sBeg); + sBeg = body_nosch(sBeg, file); } return 0; } -static char* body_runq(char* beg) +static char* body_runq(char* beg, FILE *file) { char *s = beg; cJSON *root, *arr; @@ -255,19 +261,22 @@ static char* body_runq(char* beg) } out = cJSON_Print(root); - printf("%s\n", out); + if (!file) + printf("%s\n", out); + else + fprintf(file, "%s\n", out); free(out); cJSON_Delete(root); return s + 1; } -int parser_runq(char *stream, int size) +int parser_runq(char *stream, int size, FILE *file) { char *sBeg; sBeg = stream; while (sBeg[0] != '\0') { - sBeg = body_runq(sBeg); + sBeg = body_runq(sBeg, file); } return 0; } diff --git a/source/tools/monitor/sched/runlatency/parser.h b/source/tools/monitor/sched/runlatency/parser.h new file mode 100644 index 00000000..57baa7bc --- /dev/null +++ b/source/tools/monitor/sched/runlatency/parser.h @@ -0,0 +1,7 @@ +#ifndef _PARSER_H +#define _PARSER_H +int parser_irqoff(char *stream, int size, FILE *file); +int parser_nosch(char *stream, int size, FILE *file); +int parser_runq(char *stream, int size, FILE *file); +int pasre_dump(char *file); +#endif diff --git a/source/tools/monitor/sched/runlatency/runlatency.c b/source/tools/monitor/sched/runlatency/runlatency.c new file mode 100644 index 00000000..e319568d --- /dev/null +++ b/source/tools/monitor/sched/runlatency/runlatency.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include "parser.h" + +#define OPT_MASK 0x7 +#define OPT_IRQ 0x1 +#define OPT_SCH 0x2 +#define OPT_LAT 0x4 +#define MAX_CMD 3 +#define MAX_CMD_LEN 128 + +char *firq = "/proc/sysak/runlatency/irqoff/enable"; +char *fsch = "/proc/sysak/runlatency/nosch/enable"; +char *flat = "/proc/sysak/runlatency/runqlat/pid"; + +static void usage(char *prog) +{ + const char *str = + " Usage: %s [OPTIONS]\n" + " Options:\n" + " -f the output file\n" + " -r read the result to file or stdio\n" + " -d disable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" + " -e enable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" + "\n"; + + fprintf(stderr, str, prog); + exit(EXIT_FAILURE); +} + +char *cmdstr[3]; + +int switch_func(int opt, int enable, int arg) +{ + FILE *fp; + int param[3], ret, index = 0; + int optalign; + char cmd[MAX_CMD_LEN] = {0}; + + + optalign = opt & OPT_MASK; + + if (optalign & OPT_LAT) + param[2] = arg; + else + param[2] = enable; + + param[0] = param[1] = enable; + while (index < MAX_CMD) { + if (optalign & (1 << index)) { + snprintf(cmd, MAX_CMD_LEN, "echo %d > %s",param[index], cmdstr[index]); + /* fprintf(stderr, "debug_cmd:%s\n", cmd); */ + fp = popen(cmd, "r"); + if (!fp) { + ret = errno; + perror(cmd); + return ret; + } + optalign = optalign; + index++; + } + } +} + +int main(int argc, char *argv[]) +{ + char *refile = NULL; + int pid = -1, ret = 0, i, will_switch, enable; + int c, option_index, en_opt, dis_opt; + + opterr = 0; + dis_opt = en_opt = OPT_MASK; + + cmdstr[0] = firq; + cmdstr[1] = fsch; + cmdstr[2] = flat; + for (i = 0; i < MAX_CMD; i++) { + if (access(cmdstr[i], F_OK)) { + ret = errno; + fprintf(stderr, "%s:access() %s\n", + strerror(errno), cmdstr[i]); + return ret; + } + } + for (;;) { + c = getopt_long(argc, argv, "f:p:e::d::hr", + NULL /*long_options*/, &option_index); + + if (c == -1) + break; + switch (c) { + case 'f': + refile = optarg; + break; + case 'r': + pasre_dump(refile);//do something + break; + case 'p': + pid = atoi(optarg); + fprintf(stderr, "debug_p_pid=%d\n", pid); + break; + case 'e': + if (optarg) + en_opt = atoi(optarg); + fprintf(stderr, "debug_e_pid=%d\n", pid); + will_switch = 1; + enable = 1; + break; + case 'd': + if (optarg) + dis_opt = atoi(optarg); + will_switch = 1; + enable = 0; + break; + case 'h': + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } + if (will_switch) + ret = switch_func(dis_opt, enable, pid); + + return ret; +} diff --git a/source/tools/monitor/sched/runlatency/sh/Makefile b/source/tools/monitor/sched/runlatency/sh/Makefile deleted file mode 100644 index 255d37a6..00000000 --- a/source/tools/monitor/sched/runlatency/sh/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -target := runlatency -DEPEND := "prev{-e modin};post{-d modun}" - -include $(SRC)/mk/sh.mk diff --git a/source/tools/monitor/sched/runlatency/sh/runlatency.sh b/source/tools/monitor/sched/runlatency/sh/runlatency.sh deleted file mode 100755 index 5c6d9625..00000000 --- a/source/tools/monitor/sched/runlatency/sh/runlatency.sh +++ /dev/null @@ -1,67 +0,0 @@ -WORK_PATH=`dirname $0`/ -pid=-1 - -runlatency_enable() { - echo 1 > /proc/sysak/runlatency/irqoff/enable - echo 1 > /proc/sysak/runlatency/nosch/enable - echo $pid > /proc/sysak/runlatency/runqlat/pid -} - -runlatency_disable() { - echo 0 > /proc/sysak/runlatency/irqoff/enable - echo 0 > /proc/sysak/runlatency/nosch/enable - echo -1 > /proc/sysak/runlatency/runqlat/pid -} - -runlatency_report() { - - if [ -z "$outfile" ]; then - $WORK_PATH/rt_json_dump - else - $WORK_PATH/rt_json_dump >>$outfile - fi -} - -usage() { - echo "$0 -e|d" - echo " -e, enable" - echo " -d, disable" - echo " -r, report, default stdout if no outfile specified" - echo " -f, outfile for report" -} - -while getopts 'p:f:edrh' OPT; do - case $OPT in - "h") - usage - exit 0 - ;; - "p") - pid=$OPTARG - ;; - "e") - runlatency_enable - exit 0 - ;; - "d") - runlatency_disable - exit 0 - ;; - "r") - report="true" - ;; - "f") - outfile=$OPTARG - ;; - *) - echo this - usage - exit -1 - ;; - esac -done - -if [ $report = "true" ];then - runlatency_report -fi - -- Gitee From 741f14b70a459e39f535d8c98d133cf2a9219485 Mon Sep 17 00:00:00 2001 From: "suiya.lhl" Date: Fri, 19 Nov 2021 09:44:28 +0800 Subject: [PATCH 09/10] runlatency: remove some debug output info Signed-off-by: suiya.lhl --- source/tools/monitor/sched/runlatency/runlatency.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/tools/monitor/sched/runlatency/runlatency.c b/source/tools/monitor/sched/runlatency/runlatency.c index e319568d..6c0cd34a 100644 --- a/source/tools/monitor/sched/runlatency/runlatency.c +++ b/source/tools/monitor/sched/runlatency/runlatency.c @@ -101,12 +101,10 @@ int main(int argc, char *argv[]) break; case 'p': pid = atoi(optarg); - fprintf(stderr, "debug_p_pid=%d\n", pid); break; case 'e': if (optarg) en_opt = atoi(optarg); - fprintf(stderr, "debug_e_pid=%d\n", pid); will_switch = 1; enable = 1; break; -- Gitee From 6071fe512b54e17bd361c351d4e211284bfee3db Mon Sep 17 00:00:00 2001 From: Hailong Liu Date: Mon, 27 Dec 2021 17:52:49 +0800 Subject: [PATCH 10/10] trace_runqlat: Don't check modules when show help info Currently, when use '-h' for help info, the app require *enable* first, which is not reasonable. Fix it so that users can get help info comfortable. Signed-off-by: Hailong Liu --- .../monitor/sched/runlatency/runlatency.c | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/source/tools/monitor/sched/runlatency/runlatency.c b/source/tools/monitor/sched/runlatency/runlatency.c index 6c0cd34a..26403ba0 100644 --- a/source/tools/monitor/sched/runlatency/runlatency.c +++ b/source/tools/monitor/sched/runlatency/runlatency.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "parser.h" #define OPT_MASK 0x7 @@ -23,10 +24,10 @@ static void usage(char *prog) " Usage: %s [OPTIONS]\n" " Options:\n" " -f the output file\n" - " -r read the result to file or stdio\n" - " -d disable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" - " -e enable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat\n" - "\n"; + " -r read the result to file or stdout, default stdout\n" + " -d disable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat, default=7\n" + " -e enable the monitor, 7-all, 1-irq, 2-nosched, 4-runlat, default=7\n" + ; fprintf(stderr, str, prog); exit(EXIT_FAILURE); @@ -66,6 +67,25 @@ int switch_func(int opt, int enable, int arg) } } +bool ready[MAX_CMD] = {false}; +int retno[MAX_CMD] = {0}; + +static int not_ready(bool ready[], int retno[]) +{ + int i, ret = MAX_CMD; + + for (i = 0; i < MAX_CMD; i++) { + if (ready[i]) { + ret--; + } else { + fprintf(stderr, "%s: access() %s\n", + strerror(retno[i]), cmdstr[i]); + } + } + + return ret; +} + int main(int argc, char *argv[]) { char *refile = NULL; @@ -80,10 +100,11 @@ int main(int argc, char *argv[]) cmdstr[2] = flat; for (i = 0; i < MAX_CMD; i++) { if (access(cmdstr[i], F_OK)) { - ret = errno; - fprintf(stderr, "%s:access() %s\n", - strerror(errno), cmdstr[i]); - return ret; + retno[i] = errno; + ready[i] = false; + } else { + retno[i] = 0; + ready[i] = true; } } for (;;) { @@ -97,28 +118,34 @@ int main(int argc, char *argv[]) refile = optarg; break; case 'r': + if (!not_ready(ready, retno)) + return -1; pasre_dump(refile);//do something break; case 'p': pid = atoi(optarg); break; case 'e': + if (!not_ready(ready, retno)) + return -1; if (optarg) en_opt = atoi(optarg); will_switch = 1; enable = 1; break; case 'd': + if (!not_ready(ready, retno)) + return -1; if (optarg) dis_opt = atoi(optarg); will_switch = 1; enable = 0; break; case 'h': - usage(argv[0]); + usage("sysak runlatency"); break; default: - usage(argv[0]); + usage("sysak runlatency"); } } if (will_switch) -- Gitee