From a9d2edfddcb0367f188c044cebf8bd5721d5d609 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Mishra Date: Wed, 3 Mar 2021 20:04:21 +0530 Subject: [PATCH] tools/sched_tp: Update sched_tp module to latest update sched_tp module to include new events as provided by Qais.Yousef@arm.com removed 0001-sched-add-a-module-to-convert-tp-into-events.patch update build_module and claen_module as per Makefile change --- tools/kmodules/build_module | 6 +- tools/kmodules/clean_module | 2 +- ...d-a-module-to-convert-tp-into-events.patch | 493 ------------------ tools/kmodules/sched_tp/Makefile | 24 + tools/kmodules/sched_tp/sched_events.h | 97 ++++ tools/kmodules/sched_tp/sched_tp.c | 51 +- tools/kmodules/sched_tp/sched_tp_helpers.h | 164 ++++++ tools/kmodules/sched_tp/vmlinux.txt | 7 + tools/kmodules/sched_tp/vmlinux_deps.txt | 10 + 9 files changed, 344 insertions(+), 510 deletions(-) delete mode 100644 tools/kmodules/sched_tp/0001-sched-add-a-module-to-convert-tp-into-events.patch create mode 100644 tools/kmodules/sched_tp/sched_tp_helpers.h create mode 100644 tools/kmodules/sched_tp/vmlinux.txt create mode 100644 tools/kmodules/sched_tp/vmlinux_deps.txt diff --git a/tools/kmodules/build_module b/tools/kmodules/build_module index 8cd1fcc6e..21d137a53 100755 --- a/tools/kmodules/build_module +++ b/tools/kmodules/build_module @@ -7,7 +7,7 @@ INSTALL_MOD_PATH=${3:-`dirname "$0"`} export INSTALL_MOD_PATH=`realpath "$INSTALL_MOD_PATH"` export ARCH=${ARCH:-arm64} - +#$(info $ARCH) case "$ARCH" in arm64) @@ -24,5 +24,5 @@ case "$ARCH" in ;; esac -make -C "$KERNEL_SRC" M="$MODULE_SRC" modules -make -C "$KERNEL_SRC" M="$MODULE_SRC" modules_install +KERNEL_SRC="$KERNEL_SRC" make -C "$MODULE_SRC" +KERNEL_SRC="$KERNEL_SRC" make -C "$MODULE_SRC" install diff --git a/tools/kmodules/clean_module b/tools/kmodules/clean_module index d6c10fbe9..6b181eb33 100755 --- a/tools/kmodules/clean_module +++ b/tools/kmodules/clean_module @@ -22,4 +22,4 @@ case "$ARCH" in ;; esac -make -C "$KERNEL_SRC" M="$MODULE_SRC" clean +KERNEL_SRC="$KERNEL_SRC" make -C "$MODULE_SRC" clean diff --git a/tools/kmodules/sched_tp/0001-sched-add-a-module-to-convert-tp-into-events.patch b/tools/kmodules/sched_tp/0001-sched-add-a-module-to-convert-tp-into-events.patch deleted file mode 100644 index 50a45a2b9..000000000 --- a/tools/kmodules/sched_tp/0001-sched-add-a-module-to-convert-tp-into-events.patch +++ /dev/null @@ -1,493 +0,0 @@ -From 766ef215effed5e92c14aafd07ce1dcc32025e4a Mon Sep 17 00:00:00 2001 -From: Qais Yousef -Date: Fri, 24 May 2019 15:10:46 +0100 -Subject: [PATCH] sched: add a module to convert tp into events - -The module is always compiled as built-in except for !CONFIG_SMP -where the targeted tracepoints don't exist/make sense. - -It creates a set of sched events in tracefs that are required to run -Lisa tests. - -Signed-off-by: Qais Yousef ---- - include/trace/events/sched.h | 7 ++ - kernel/sched/Makefile | 3 + - kernel/sched/core.c | 2 + - kernel/sched/fair.c | 6 + - kernel/sched/sched_events.h | 209 +++++++++++++++++++++++++++++++++++ - kernel/sched/sched_tp.c | 170 ++++++++++++++++++++++++++++ - 6 files changed, 397 insertions(+) - create mode 100644 kernel/sched/sched_events.h - create mode 100644 kernel/sched/sched_tp.c - -diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h -index 420e80e56e55..9c35f992dab0 100644 ---- a/include/trace/events/sched.h -+++ b/include/trace/events/sched.h -@@ -335,6 +335,13 @@ TRACE_EVENT(sched_process_exec, - __entry->pid, __entry->old_pid) - ); - -+DECLARE_TRACE(sched_util_est_cfs_tp, -+ TP_PROTO(struct cfs_rq *cfs_rq), -+ TP_ARGS(cfs_rq)); -+ -+DECLARE_TRACE(sched_util_est_se_tp, -+ TP_PROTO(struct sched_entity *se), -+ TP_ARGS(se)); - - #ifdef CONFIG_SCHEDSTATS - #define DEFINE_EVENT_SCHEDSTAT DEFINE_EVENT -diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile -index 21fb5a5662b5..dbcb46d51509 100644 ---- a/kernel/sched/Makefile -+++ b/kernel/sched/Makefile -@@ -20,6 +20,9 @@ obj-y += core.o loadavg.o clock.o cputime.o - obj-y += idle.o fair.o rt.o deadline.o - obj-y += wait.o wait_bit.o swait.o completion.o - -+obj-$(CONFIG_SMP) += sched_tp.o -+CFLAGS_sched_tp.o := -I$(src) -+ - obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o topology.o stop_task.o pelt.o - obj-$(CONFIG_SCHED_AUTOGROUP) += autogroup.o - obj-$(CONFIG_SCHEDSTATS) += stats.o -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index dd05a378631a..0db413eccaee 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -33,6 +33,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_dl_tp); - EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_irq_tp); - EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_se_tp); - EXPORT_TRACEPOINT_SYMBOL_GPL(sched_overutilized_tp); -+EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_cfs_tp); -+EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_se_tp); - - DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 83ab35e2374f..af29a272c7ab 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -3718,6 +3718,8 @@ static inline void util_est_enqueue(struct cfs_rq *cfs_rq, - enqueued = cfs_rq->avg.util_est.enqueued; - enqueued += _task_util_est(p); - WRITE_ONCE(cfs_rq->avg.util_est.enqueued, enqueued); -+ -+ trace_sched_util_est_cfs_tp(cfs_rq); - } - - /* -@@ -3748,6 +3750,8 @@ util_est_dequeue(struct cfs_rq *cfs_rq, struct task_struct *p, bool task_sleep) - ue.enqueued -= min_t(unsigned int, ue.enqueued, _task_util_est(p)); - WRITE_ONCE(cfs_rq->avg.util_est.enqueued, ue.enqueued); - -+ trace_sched_util_est_cfs_tp(cfs_rq); -+ - /* - * Skip update of task's estimated utilization when the task has not - * yet completed an activation, e.g. being migrated. -@@ -3801,6 +3805,8 @@ util_est_dequeue(struct cfs_rq *cfs_rq, struct task_struct *p, bool task_sleep) - ue.ewma += last_ewma_diff; - ue.ewma >>= UTIL_EST_WEIGHT_SHIFT; - WRITE_ONCE(p->se.avg.util_est, ue); -+ -+ trace_sched_util_est_se_tp(&p->se); - } - - static inline int task_fits_capacity(struct task_struct *p, long capacity) -diff --git a/kernel/sched/sched_events.h b/kernel/sched/sched_events.h -new file mode 100644 -index 000000000000..03c5467c9567 ---- /dev/null -+++ b/kernel/sched/sched_events.h -@@ -0,0 +1,209 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM sched -+ -+#define MAX_SPAN_SIZE 128 -+ -+#if !defined(_SCHED_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _SCHED_EVENTS_H -+ -+#define PATH_SIZE 64 -+#define __SPAN_SIZE (round_up(NR_CPUS, 4)/4) -+#define SPAN_SIZE (__SPAN_SIZE > MAX_SPAN_SIZE ? MAX_SPAN_SIZE : __SPAN_SIZE) -+ -+#include -+#include -+ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(5,6,0) -+#define RBL_LOAD_ENTRY rbl_load -+#define RBL_LOAD_MEMBER runnable_load_avg -+#define RBL_LOAD_STR "rbl_load" -+#else -+#define RBL_LOAD_ENTRY runnable -+#define RBL_LOAD_MEMBER runnable_avg -+#define RBL_LOAD_STR "runnable" -+#endif -+ -+TRACE_EVENT(sched_pelt_cfs, -+ -+ TP_PROTO(int cpu, char *path, const struct sched_avg *avg), -+ -+ TP_ARGS(cpu, path, avg), -+ -+ TP_STRUCT__entry( -+ __field( int, cpu ) -+ __array( char, path, PATH_SIZE ) -+ __field( unsigned long, load ) -+ __field( unsigned long, RBL_LOAD_ENTRY ) -+ __field( unsigned long, util ) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ strlcpy(__entry->path, path, PATH_SIZE); -+ __entry->load = avg->load_avg; -+ __entry->RBL_LOAD_ENTRY = avg->RBL_LOAD_MEMBER; -+ __entry->util = avg->util_avg; -+ ), -+ -+ TP_printk("cpu=%d path=%s load=%lu " RBL_LOAD_STR "=%lu util=%lu", -+ __entry->cpu, __entry->path, __entry->load, -+ __entry->RBL_LOAD_ENTRY,__entry->util) -+); -+ -+DECLARE_EVENT_CLASS(sched_pelt_rq_template, -+ -+ TP_PROTO(int cpu, const struct sched_avg *avg), -+ -+ TP_ARGS(cpu, avg), -+ -+ TP_STRUCT__entry( -+ __field( int, cpu ) -+ __field( unsigned long, load ) -+ __field( unsigned long, RBL_LOAD_ENTRY ) -+ __field( unsigned long, util ) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ __entry->load = avg->load_avg; -+ __entry->RBL_LOAD_ENTRY = avg->RBL_LOAD_MEMBER; -+ __entry->util = avg->util_avg; -+ ), -+ -+ TP_printk("cpu=%d load=%lu " RBL_LOAD_STR "=%lu util=%lu", -+ __entry->cpu, __entry->load, -+ __entry->RBL_LOAD_ENTRY,__entry->util) -+); -+ -+DEFINE_EVENT(sched_pelt_rq_template, sched_pelt_rt, -+ TP_PROTO(int cpu, const struct sched_avg *avg), -+ TP_ARGS(cpu, avg)); -+ -+DEFINE_EVENT(sched_pelt_rq_template, sched_pelt_dl, -+ TP_PROTO(int cpu, const struct sched_avg *avg), -+ TP_ARGS(cpu, avg)); -+ -+DEFINE_EVENT(sched_pelt_rq_template, sched_pelt_irq, -+ TP_PROTO(int cpu, const struct sched_avg *avg), -+ TP_ARGS(cpu, avg)); -+ -+TRACE_EVENT(sched_pelt_se, -+ -+ TP_PROTO(int cpu, char *path, char *comm, int pid, const struct sched_avg *avg), -+ -+ TP_ARGS(cpu, path, comm, pid, avg), -+ -+ TP_STRUCT__entry( -+ __field( int, cpu ) -+ __array( char, path, PATH_SIZE ) -+ __array( char, comm, TASK_COMM_LEN ) -+ __field( int, pid ) -+ __field( unsigned long, load ) -+ __field( unsigned long, RBL_LOAD_ENTRY ) -+ __field( unsigned long, util ) -+ __field( unsigned long long, update_time ) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ strlcpy(__entry->path, path, PATH_SIZE); -+ strlcpy(__entry->comm, comm, TASK_COMM_LEN); -+ __entry->pid = pid; -+ __entry->load = avg->load_avg; -+ __entry->RBL_LOAD_ENTRY = avg->RBL_LOAD_MEMBER; -+ __entry->util = avg->util_avg; -+ __entry->update_time = avg->last_update_time; -+ ), -+ -+ TP_printk("cpu=%d path=%s comm=%s pid=%d load=%lu " RBL_LOAD_STR "=%lu util=%lu update_time=%llu", -+ __entry->cpu, __entry->path, __entry->comm, __entry->pid, -+ __entry->load, __entry->RBL_LOAD_ENTRY,__entry->util, __entry->update_time) -+); -+ -+TRACE_EVENT(sched_overutilized, -+ -+ TP_PROTO(int overutilized, char *span), -+ -+ TP_ARGS(overutilized, span), -+ -+ TP_STRUCT__entry( -+ __field( int, overutilized ) -+ __array( char, span, SPAN_SIZE ) -+ ), -+ -+ TP_fast_assign( -+ __entry->overutilized = overutilized; -+ strlcpy(__entry->span, span, SPAN_SIZE); -+ ), -+ -+ TP_printk("overutilized=%d span=0x%s", -+ __entry->overutilized, __entry->span) -+); -+ -+TRACE_EVENT(sched_util_est_se, -+ -+ TP_PROTO(int cpu, char *path, char *comm, int pid, -+ const struct sched_avg *avg), -+ -+ TP_ARGS(cpu, path, comm, pid, avg), -+ -+ TP_STRUCT__entry( -+ __field( int, cpu ) -+ __array( char, path, PATH_SIZE ) -+ __array( char, comm, TASK_COMM_LEN ) -+ __field( int, pid ) -+ __field( unsigned int, enqueued ) -+ __field( unsigned int, ewma ) -+ __field( unsigned long, util ) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ strlcpy(__entry->path, path, PATH_SIZE); -+ strlcpy(__entry->comm, comm, TASK_COMM_LEN); -+ __entry->pid = pid; -+ __entry->enqueued = avg->util_est.enqueued; -+ __entry->ewma = avg->util_est.ewma; -+ __entry->util = avg->util_avg; -+ ), -+ -+ TP_printk("cpu=%d path=%s comm=%s pid=%d enqueued=%u ewma=%u util=%lu", -+ __entry->cpu, __entry->path, __entry->comm, __entry->pid, -+ __entry->enqueued, __entry->ewma, __entry->util) -+); -+ -+TRACE_EVENT(sched_util_est_cfs, -+ -+ TP_PROTO(int cpu, char *path, const struct sched_avg *avg), -+ -+ TP_ARGS(cpu, path, avg), -+ -+ TP_STRUCT__entry( -+ __field( int, cpu ) -+ __array( char, path, PATH_SIZE ) -+ __field( unsigned int, enqueued ) -+ __field( unsigned int, ewma ) -+ __field( unsigned long, util ) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ strlcpy(__entry->path, path, PATH_SIZE); -+ __entry->enqueued = avg->util_est.enqueued; -+ __entry->ewma = avg->util_est.ewma; -+ __entry->util = avg->util_avg; -+ ), -+ -+ TP_printk("cpu=%d path=%s enqueued=%u ewma=%u util=%lu", -+ __entry->cpu, __entry->path, __entry->enqueued, -+ __entry->ewma, __entry->util) -+); -+ -+#endif /* _SCHED_EVENTS_H */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_FILE sched_events -+#include -diff --git a/kernel/sched/sched_tp.c b/kernel/sched/sched_tp.c -new file mode 100644 -index 000000000000..9fff885ba022 ---- /dev/null -+++ b/kernel/sched/sched_tp.c -@@ -0,0 +1,170 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#include -+ -+#include -+#include -+ -+#define CREATE_TRACE_POINTS -+#include "sched_events.h" -+ -+static inline struct cfs_rq *get_group_cfs_rq(struct sched_entity *se) -+{ -+#ifdef CONFIG_FAIR_GROUP_SCHED -+ return se->my_q; -+#else -+ return NULL; -+#endif -+} -+ -+static inline struct cfs_rq *get_se_cfs_rq(struct sched_entity *se) -+{ -+#ifdef CONFIG_FAIR_GROUP_SCHED -+ return se->cfs_rq; -+#else -+ return NULL; -+#endif -+} -+ -+static inline void _trace_cfs(struct cfs_rq *cfs_rq, -+ void (*trace_event)(int, char*, -+ const struct sched_avg*)) -+{ -+ const struct sched_avg *avg; -+ char path[PATH_SIZE]; -+ int cpu; -+ -+ avg = sched_trace_cfs_rq_avg(cfs_rq); -+ sched_trace_cfs_rq_path(cfs_rq, path, PATH_SIZE); -+ cpu = sched_trace_cfs_rq_cpu(cfs_rq); -+ -+ trace_event(cpu, path, avg); -+ } -+ -+static inline void _trace_se(struct sched_entity *se, -+ void (*trace_event)(int, char*, char*, int, -+ const struct sched_avg*)) -+{ -+ void *gcfs_rq = get_group_cfs_rq(se); -+ void *cfs_rq = get_se_cfs_rq(se); -+ struct task_struct *p; -+ char path[PATH_SIZE]; -+ char *comm; -+ pid_t pid; -+ int cpu; -+ -+ sched_trace_cfs_rq_path(gcfs_rq, path, PATH_SIZE); -+ cpu = sched_trace_cfs_rq_cpu(cfs_rq); -+ -+ p = gcfs_rq ? NULL : container_of(se, struct task_struct, se); -+ comm = p ? p->comm : "(null)"; -+ pid = p ? p->pid : -1; -+ -+ trace_event(cpu, path, comm, pid, &se->avg); -+} -+ -+static void sched_pelt_cfs(void *data, struct cfs_rq *cfs_rq) -+{ -+ if (trace_sched_pelt_cfs_enabled()) -+ _trace_cfs(cfs_rq, trace_sched_pelt_cfs); -+} -+ -+static void sched_pelt_rt(void *data, struct rq *rq) -+{ -+ if (trace_sched_pelt_rt_enabled()) { -+ const struct sched_avg *avg = sched_trace_rq_avg_rt(rq); -+ int cpu = sched_trace_rq_cpu(rq); -+ -+ if (!avg) -+ return; -+ -+ trace_sched_pelt_rt(cpu, avg); -+ } -+} -+ -+static void sched_pelt_dl(void *data, struct rq *rq) -+{ -+ if (trace_sched_pelt_dl_enabled()) { -+ const struct sched_avg *avg = sched_trace_rq_avg_dl(rq); -+ int cpu = sched_trace_rq_cpu(rq); -+ -+ if (!avg) -+ return; -+ -+ trace_sched_pelt_dl(cpu, avg); -+ } -+} -+ -+static void sched_pelt_irq(void *data, struct rq *rq) -+{ -+ if (trace_sched_pelt_irq_enabled()){ -+ const struct sched_avg *avg = sched_trace_rq_avg_irq(rq); -+ int cpu = sched_trace_rq_cpu(rq); -+ -+ if (!avg) -+ return; -+ -+ trace_sched_pelt_irq(cpu, avg); -+ } -+} -+ -+static void sched_pelt_se(void *data, struct sched_entity *se) -+{ -+ if (trace_sched_pelt_se_enabled()) { -+ _trace_se(se, trace_sched_pelt_se); -+ } -+} -+ -+static void sched_overutilized(void *data, struct root_domain *rd, bool overutilized) -+{ -+ if (trace_sched_overutilized_enabled()) { -+ char span[SPAN_SIZE]; -+ -+ cpumap_print_to_pagebuf(false, span, sched_trace_rd_span(rd)); -+ -+ trace_sched_overutilized(overutilized, span); -+ } -+} -+ -+static void sched_util_est_cfs(void *data, struct cfs_rq *cfs_rq) -+{ -+ if (trace_sched_util_est_cfs_enabled()) -+ _trace_cfs(cfs_rq, trace_sched_util_est_cfs); -+} -+ -+static void sched_util_est_se(void *data, struct sched_entity *se) -+{ -+ if (trace_sched_util_est_se_enabled()) -+ _trace_se(se, trace_sched_util_est_se); -+} -+ -+static int sched_tp_init(void) -+{ -+ register_trace_pelt_cfs_tp(sched_pelt_cfs, NULL); -+ register_trace_pelt_rt_tp(sched_pelt_rt, NULL); -+ register_trace_pelt_dl_tp(sched_pelt_dl, NULL); -+ register_trace_pelt_irq_tp(sched_pelt_irq, NULL); -+ register_trace_pelt_se_tp(sched_pelt_se, NULL); -+ register_trace_sched_overutilized_tp(sched_overutilized, NULL); -+ register_trace_sched_util_est_cfs_tp(sched_util_est_cfs, NULL); -+ register_trace_sched_util_est_se_tp(sched_util_est_se, NULL); -+ -+ return 0; -+} -+ -+static void sched_tp_finish(void) -+{ -+ unregister_trace_pelt_cfs_tp(sched_pelt_cfs, NULL); -+ unregister_trace_pelt_rt_tp(sched_pelt_rt, NULL); -+ unregister_trace_pelt_dl_tp(sched_pelt_dl, NULL); -+ unregister_trace_pelt_irq_tp(sched_pelt_irq, NULL); -+ unregister_trace_pelt_se_tp(sched_pelt_se, NULL); -+ unregister_trace_sched_overutilized_tp(sched_overutilized, NULL); -+ unregister_trace_sched_util_est_cfs_tp(sched_util_est_cfs, NULL); -+ unregister_trace_sched_util_est_se_tp(sched_util_est_se, NULL); -+} -+ -+ -+module_init(sched_tp_init); -+module_exit(sched_tp_finish); -+ -+MODULE_LICENSE("GPL"); --- -2.17.1 - diff --git a/tools/kmodules/sched_tp/Makefile b/tools/kmodules/sched_tp/Makefile index 4f28de506..3ea0b1c42 100644 --- a/tools/kmodules/sched_tp/Makefile +++ b/tools/kmodules/sched_tp/Makefile @@ -1,3 +1,27 @@ obj-m += sched_tp.o EXTRA_CFLAGS = -I$(src) + +VMLINUX_DEPS_H = vmlinux_deps.h +VMLINUX_H = vmlinux.h + +VMLINUX_DEPS_TXT = vmlinux_deps.txt +VMLINUX_TXT = vmlinux.txt + +VMLINUX = $(KERNEL_SRC)/vmlinux + +all: $(VMLINUX_H) + make -C $(KERNEL_SRC) M=$(PWD) modules + +install: + make -C $(KERNEL_SRC) M=$(PWD) modules_install + +clean: + make -C $(KERNEL_SRC) M=$(PWD) clean + rm -f $(VMLINUX_H) $(VMLINUX_DEPS_H) + +$(VMLINUX_DEPS_H): $(VMLINUX_DEPS_TXT) $(VMLINUX) + pahole -C file://$(VMLINUX_DEPS_TXT) $(VMLINUX) > $@ + +$(VMLINUX_H): $(VMLINUX_DEPS_H) $(VMLINUX_TXT) $(VMLINUX) + pahole -C file://$(VMLINUX_TXT) $(VMLINUX) > $@ diff --git a/tools/kmodules/sched_tp/sched_events.h b/tools/kmodules/sched_tp/sched_events.h index 03c5467c9..d2179b8a7 100644 --- a/tools/kmodules/sched_tp/sched_events.h +++ b/tools/kmodules/sched_tp/sched_events.h @@ -11,9 +11,12 @@ #define __SPAN_SIZE (round_up(NR_CPUS, 4)/4) #define SPAN_SIZE (__SPAN_SIZE > MAX_SPAN_SIZE ? MAX_SPAN_SIZE : __SPAN_SIZE) +#include #include #include +#include "sched_tp_helpers.h" + #if LINUX_VERSION_CODE <= KERNEL_VERSION(5,6,0) #define RBL_LOAD_ENTRY rbl_load #define RBL_LOAD_MEMBER runnable_load_avg @@ -141,6 +144,27 @@ TRACE_EVENT(sched_overutilized, __entry->overutilized, __entry->span) ); +TRACE_EVENT(sched_update_nr_running, + + TP_PROTO(int cpu, int change, unsigned int nr_running), + + TP_ARGS(cpu, change, nr_running), + + TP_STRUCT__entry( + __field( int, cpu ) + __field( int, change ) + __field(unsigned int, nr_running ) + ), + + TP_fast_assign( + __entry->cpu = cpu; + __entry->change = change; + __entry->nr_running = nr_running; + ), + + TP_printk("cpu=%d change=%d nr_running=%d", __entry->cpu, __entry->change, __entry->nr_running) + ); + TRACE_EVENT(sched_util_est_se, TP_PROTO(int cpu, char *path, char *comm, int pid, @@ -200,6 +224,79 @@ TRACE_EVENT(sched_util_est_cfs, __entry->ewma, __entry->util) ); +#ifdef CONFIG_UCLAMP_TASK + +TRACE_EVENT_CONDITION(uclamp_util_se, + + TP_PROTO(bool is_task, struct task_struct *p, struct rq *rq), + + TP_ARGS(is_task, p, rq), + + TP_CONDITION(is_task), + + TP_STRUCT__entry( + __field( pid_t, pid ) + __array( char, comm, TASK_COMM_LEN ) + __field( int, cpu ) + __field(unsigned long, util_avg ) + __field(unsigned long, uclamp_avg ) + __field(unsigned long, uclamp_min ) + __field(unsigned long, uclamp_max ) + ), + + TP_fast_assign( + __entry->pid = p->pid; + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->cpu = sched_tp_rq_cpu(rq); + __entry->util_avg = p->se.avg.util_avg; + __entry->uclamp_avg = uclamp_rq_util_with(rq, p->se.avg.util_avg, NULL); + __entry->uclamp_min = rq->uclamp[UCLAMP_MIN].value; + __entry->uclamp_max = rq->uclamp[UCLAMP_MAX].value; + ), + + TP_printk("pid=%d comm=%s cpu=%d util_avg=%lu uclamp_avg=%lu " + "uclamp_min=%lu uclamp_max=%lu", + __entry->pid, __entry->comm, __entry->cpu, + __entry->util_avg, __entry->uclamp_avg, + __entry->uclamp_min, __entry->uclamp_max) +); + +TRACE_EVENT_CONDITION(uclamp_util_cfs, + + TP_PROTO(bool is_root, struct rq *rq, struct cfs_rq *cfs_rq), + + TP_ARGS(is_root, rq, cfs_rq), + + TP_CONDITION(is_root), + + TP_STRUCT__entry( + __field( int, cpu ) + __field(unsigned long, util_avg ) + __field(unsigned long, uclamp_avg ) + __field(unsigned long, uclamp_min ) + __field(unsigned long, uclamp_max ) + ), + + TP_fast_assign( + __entry->cpu = sched_tp_rq_cpu(rq); + __entry->util_avg = cfs_rq->avg.util_avg; + __entry->uclamp_avg = uclamp_rq_util_with(rq, cfs_rq->avg.util_avg, NULL); + __entry->uclamp_min = rq->uclamp[UCLAMP_MIN].value; + __entry->uclamp_max = rq->uclamp[UCLAMP_MAX].value; + ), + + TP_printk("cpu=%d util_avg=%lu uclamp_avg=%lu " + "uclamp_min=%lu uclamp_max=%lu", + __entry->cpu, __entry->util_avg, __entry->uclamp_avg, + __entry->uclamp_min, __entry->uclamp_max) +); +#else +#define trace_uclamp_util_se(is_task, p, rq) while(false) {} +#define trace_uclamp_util_se_enabled() false +#define trace_uclamp_util_cfs(is_root, cpu, cfs_rq) while(false) {} +#define trace_uclamp_util_cfs_enabled() false +#endif /* CONFIG_UCLAMP_TASK */ + #endif /* _SCHED_EVENTS_H */ /* This part must be outside protection */ diff --git a/tools/kmodules/sched_tp/sched_tp.c b/tools/kmodules/sched_tp/sched_tp.c index 9fff885ba..c9aceae2f 100644 --- a/tools/kmodules/sched_tp/sched_tp.c +++ b/tools/kmodules/sched_tp/sched_tp.c @@ -33,9 +33,9 @@ static inline void _trace_cfs(struct cfs_rq *cfs_rq, char path[PATH_SIZE]; int cpu; - avg = sched_trace_cfs_rq_avg(cfs_rq); - sched_trace_cfs_rq_path(cfs_rq, path, PATH_SIZE); - cpu = sched_trace_cfs_rq_cpu(cfs_rq); + avg = sched_tp_cfs_rq_avg(cfs_rq); + sched_tp_cfs_rq_path(cfs_rq, path, PATH_SIZE); + cpu = sched_tp_cfs_rq_cpu(cfs_rq); trace_event(cpu, path, avg); } @@ -52,8 +52,8 @@ static inline void _trace_se(struct sched_entity *se, pid_t pid; int cpu; - sched_trace_cfs_rq_path(gcfs_rq, path, PATH_SIZE); - cpu = sched_trace_cfs_rq_cpu(cfs_rq); + sched_tp_cfs_rq_path(gcfs_rq, path, PATH_SIZE); + cpu = sched_tp_cfs_rq_cpu(cfs_rq); p = gcfs_rq ? NULL : container_of(se, struct task_struct, se); comm = p ? p->comm : "(null)"; @@ -66,13 +66,19 @@ static void sched_pelt_cfs(void *data, struct cfs_rq *cfs_rq) { if (trace_sched_pelt_cfs_enabled()) _trace_cfs(cfs_rq, trace_sched_pelt_cfs); + + if (trace_uclamp_util_cfs_enabled()) { + bool __maybe_unused is_root_rq = (&rq_of(cfs_rq)->cfs == cfs_rq); + + trace_uclamp_util_cfs(is_root_rq, rq_of(cfs_rq), cfs_rq); + } } static void sched_pelt_rt(void *data, struct rq *rq) { if (trace_sched_pelt_rt_enabled()) { - const struct sched_avg *avg = sched_trace_rq_avg_rt(rq); - int cpu = sched_trace_rq_cpu(rq); + const struct sched_avg *avg = sched_tp_rq_avg_rt(rq); + int cpu = sched_tp_rq_cpu(rq); if (!avg) return; @@ -84,8 +90,8 @@ static void sched_pelt_rt(void *data, struct rq *rq) static void sched_pelt_dl(void *data, struct rq *rq) { if (trace_sched_pelt_dl_enabled()) { - const struct sched_avg *avg = sched_trace_rq_avg_dl(rq); - int cpu = sched_trace_rq_cpu(rq); + const struct sched_avg *avg = sched_tp_rq_avg_dl(rq); + int cpu = sched_tp_rq_cpu(rq); if (!avg) return; @@ -97,8 +103,8 @@ static void sched_pelt_dl(void *data, struct rq *rq) static void sched_pelt_irq(void *data, struct rq *rq) { if (trace_sched_pelt_irq_enabled()){ - const struct sched_avg *avg = sched_trace_rq_avg_irq(rq); - int cpu = sched_trace_rq_cpu(rq); + const struct sched_avg *avg = sched_tp_rq_avg_irq(rq); + int cpu = sched_tp_rq_cpu(rq); if (!avg) return; @@ -109,8 +115,15 @@ static void sched_pelt_irq(void *data, struct rq *rq) static void sched_pelt_se(void *data, struct sched_entity *se) { - if (trace_sched_pelt_se_enabled()) { + if (trace_sched_pelt_se_enabled()) _trace_se(se, trace_sched_pelt_se); + + if (trace_uclamp_util_se_enabled()) { + struct cfs_rq __maybe_unused *cfs_rq = get_se_cfs_rq(se); + + trace_uclamp_util_se(entity_is_task(se), + container_of(se, struct task_struct, se), + rq_of(cfs_rq)); } } @@ -119,12 +132,22 @@ static void sched_overutilized(void *data, struct root_domain *rd, bool overutil if (trace_sched_overutilized_enabled()) { char span[SPAN_SIZE]; - cpumap_print_to_pagebuf(false, span, sched_trace_rd_span(rd)); + cpumap_print_to_pagebuf(false, span, sched_tp_rd_span(rd)); trace_sched_overutilized(overutilized, span); } } +static void sched_update_nr_running(void *data, struct rq *rq, int change) +{ + if (trace_sched_update_nr_running_enabled()) { + int cpu = sched_tp_rq_cpu(rq); + int nr_running = sched_tp_rq_nr_running(rq); + + trace_sched_update_nr_running(cpu, change, nr_running); + } +} + static void sched_util_est_cfs(void *data, struct cfs_rq *cfs_rq) { if (trace_sched_util_est_cfs_enabled()) @@ -145,6 +168,7 @@ static int sched_tp_init(void) register_trace_pelt_irq_tp(sched_pelt_irq, NULL); register_trace_pelt_se_tp(sched_pelt_se, NULL); register_trace_sched_overutilized_tp(sched_overutilized, NULL); + register_trace_sched_update_nr_running_tp(sched_update_nr_running, NULL); register_trace_sched_util_est_cfs_tp(sched_util_est_cfs, NULL); register_trace_sched_util_est_se_tp(sched_util_est_se, NULL); @@ -159,6 +183,7 @@ static void sched_tp_finish(void) unregister_trace_pelt_irq_tp(sched_pelt_irq, NULL); unregister_trace_pelt_se_tp(sched_pelt_se, NULL); unregister_trace_sched_overutilized_tp(sched_overutilized, NULL); + unregister_trace_sched_update_nr_running_tp(sched_update_nr_running, NULL); unregister_trace_sched_util_est_cfs_tp(sched_util_est_cfs, NULL); unregister_trace_sched_util_est_se_tp(sched_util_est_se, NULL); } diff --git a/tools/kmodules/sched_tp/sched_tp_helpers.h b/tools/kmodules/sched_tp/sched_tp_helpers.h new file mode 100644 index 000000000..f7002d75a --- /dev/null +++ b/tools/kmodules/sched_tp/sched_tp_helpers.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef SCHED_TP_HELPERS_H +#define SCHED_TP_HELPERS_H + +/* Required for struct irq_work which is defined in struct root_domain */ +#include + +#include + +#include "vmlinux_deps.h" +#include "vmlinux.h" + + +#ifdef CONFIG_FAIR_GROUP_SCHED +static inline struct rq *rq_of(struct cfs_rq *cfs_rq) +{ + return cfs_rq->rq; +} +#define entity_is_task(se) (!se->my_q) +#else +static inline struct rq *rq_of(struct cfs_rq *cfs_rq) +{ + return container_of(cfs_rq, struct rq, cfs); +} +#define entity_is_task(se) 1 +#endif + +static inline int cpu_of(struct rq *rq) +{ +#ifdef CONFIG_SMP + return rq->cpu; +#else + return 0; +#endif +} + +static inline bool task_group_is_autogroup(struct task_group *tg) +{ + return !!tg->autogroup; +} + +int autogroup_path(struct task_group *tg, char *buf, int buflen) +{ + if (!task_group_is_autogroup(tg)) + return 0; + + return snprintf(buf, buflen, "%s-%ld", "/autogroup", tg->autogroup->id); +} + +static inline void cfs_rq_tg_path(struct cfs_rq *cfs_rq, char *path, int len) +{ + if (!path) + return; + + if (cfs_rq && task_group_is_autogroup(cfs_rq->tg)) + autogroup_path(cfs_rq->tg, path, len); + else if (cfs_rq && cfs_rq->tg->css.cgroup) + cgroup_path(cfs_rq->tg->css.cgroup, path, len); + else + strlcpy(path, "(null)", len); +} + +/* A cut down version of the original. @p MUST be NULL */ +static __always_inline +unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util, + struct task_struct *p) +{ + unsigned long min_util; + unsigned long max_util; + + min_util = READ_ONCE(rq->uclamp[UCLAMP_MIN].value); + max_util = READ_ONCE(rq->uclamp[UCLAMP_MAX].value); + + if (unlikely(min_util >= max_util)) + return min_util; + + return clamp(util, min_util, max_util); +} + +static inline const struct sched_avg *sched_tp_cfs_rq_avg(struct cfs_rq *cfs_rq) +{ +#ifdef CONFIG_SMP + return cfs_rq ? &cfs_rq->avg : NULL; +#else + return NULL; +#endif +} + +static inline char *sched_tp_cfs_rq_path(struct cfs_rq *cfs_rq, char *str, int len) +{ + if (!cfs_rq) { + if (str) + strlcpy(str, "(null)", len); + else + return NULL; + } + + cfs_rq_tg_path(cfs_rq, str, len); + return str; +} + +static inline int sched_tp_cfs_rq_cpu(struct cfs_rq *cfs_rq) +{ + return cfs_rq ? cpu_of(rq_of(cfs_rq)) : -1; +} + +static inline const struct sched_avg *sched_tp_rq_avg_rt(struct rq *rq) +{ +#ifdef CONFIG_SMP + return rq ? &rq->avg_rt : NULL; +#else + return NULL; +#endif +} + +static inline const struct sched_avg *sched_tp_rq_avg_dl(struct rq *rq) +{ +#ifdef CONFIG_SMP + return rq ? &rq->avg_dl : NULL; +#else + return NULL; +#endif +} + +static inline const struct sched_avg *sched_tp_rq_avg_irq(struct rq *rq) +{ +#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_SCHED_AVG_IRQ) + return rq ? &rq->avg_irq : NULL; +#else + return NULL; +#endif +} + +static inline int sched_tp_rq_cpu(struct rq *rq) +{ + return rq ? cpu_of(rq) : -1; +} + +static inline int sched_tp_rq_cpu_capacity(struct rq *rq) +{ + return rq ? +#ifdef CONFIG_SMP + rq->cpu_capacity +#else + SCHED_CAPACITY_SCALE +#endif + : -1; +} + +static inline const struct cpumask *sched_tp_rd_span(struct root_domain *rd) +{ +#ifdef CONFIG_SMP + return rd ? rd->span : NULL; +#else + return NULL; +#endif +} + +static inline int sched_tp_rq_nr_running(struct rq *rq) +{ + return rq ? rq->nr_running : -1; +} + +#endif /* SCHED_TP_HELPERS */ diff --git a/tools/kmodules/sched_tp/vmlinux.txt b/tools/kmodules/sched_tp/vmlinux.txt new file mode 100644 index 000000000..654e29854 --- /dev/null +++ b/tools/kmodules/sched_tp/vmlinux.txt @@ -0,0 +1,7 @@ +cpupri +cfs_bandwidth +cfs_rq +rq +root_domain +task_group +autogroup diff --git a/tools/kmodules/sched_tp/vmlinux_deps.txt b/tools/kmodules/sched_tp/vmlinux_deps.txt new file mode 100644 index 000000000..cde396541 --- /dev/null +++ b/tools/kmodules/sched_tp/vmlinux_deps.txt @@ -0,0 +1,10 @@ +uclamp_bucket +uclamp_rq +rt_prio_array +rt_rq +dl_rq +cpu_stop_fn_t +cpu_stop_work +dl_bw +cpudl +cpupri_vec -- GitLab