From 242434fe46d4d4e03569afe311da98a017b14eef Mon Sep 17 00:00:00 2001 From: Lingutla Chandrasekhar Date: Wed, 26 May 2021 12:23:22 +0530 Subject: [PATCH] sched: walt: support dynamic trace event registration Some trace events might not need to be enabled always, but needed for debug purpose. It is not optimal to register trace event, which is used for debug purpose only. So registering such trace events might add extra overhead in hotpaths. So add control knob for registering such trace events to trace points, which can be enabled whenever needed them. And can be unregister when not needed. To enable such event registration, write: echo 1 > /proc/sys/walt/sched_enable_tp And register sched_overutilized trace event with dynamic support, this event is copied from Qais's debug change in chrome project: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2128628 Change-Id: I8983e31d405a635b38c7c985b56c2f564855d3e6 Signed-off-by: Lingutla Chandrasekhar --- kernel/sched/walt/Makefile | 2 +- kernel/sched/walt/sysctl.c | 9 +++++++ kernel/sched/walt/trace.h | 22 +++++++++++++++ kernel/sched/walt/walt.h | 3 +++ kernel/sched/walt/walt_tp.c | 54 +++++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 kernel/sched/walt/walt_tp.c diff --git a/kernel/sched/walt/Makefile b/kernel/sched/walt/Makefile index 870d9b2fcfe3..ed35366108ed 100644 --- a/kernel/sched/walt/Makefile +++ b/kernel/sched/walt/Makefile @@ -4,7 +4,7 @@ KCOV_INSTRUMENT := n KCSAN_SANITIZE := n obj-$(CONFIG_SCHED_WALT) += sched-walt.o -sched-walt-$(CONFIG_SCHED_WALT) := walt.o boost.o sched_avg.o walt_pause.o core_ctl.o trace.o input-boost.o sysctl.o cpufreq_walt.o fixup.o walt_lb.o walt_rt.o walt_cfs.o +sched-walt-$(CONFIG_SCHED_WALT) := walt.o boost.o sched_avg.o walt_pause.o core_ctl.o trace.o input-boost.o sysctl.o cpufreq_walt.o fixup.o walt_lb.o walt_rt.o walt_cfs.o walt_tp.o obj-$(CONFIG_SCHED_WALT_DEBUG) += sched-walt-debug.o sched-walt-debug-$(CONFIG_SCHED_WALT_DEBUG) := walt_debug.o preemptirq_long.o diff --git a/kernel/sched/walt/sysctl.c b/kernel/sched/walt/sysctl.c index a005b3004413..578af892a5a8 100644 --- a/kernel/sched/walt/sysctl.c +++ b/kernel/sched/walt/sysctl.c @@ -773,6 +773,15 @@ struct ctl_table walt_table[] = { .extra1 = SYSCTL_ONE, .extra2 = SYSCTL_INT_MAX, }, + { + .procname = "sched_enable_tp", + .data = &sysctl_sched_dynamic_tp_enable, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = sched_dynamic_tp_handler, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, { } }; diff --git a/kernel/sched/walt/trace.h b/kernel/sched/walt/trace.h index 8b8780a2d97b..dad667d8a2a9 100644 --- a/kernel/sched/walt/trace.h +++ b/kernel/sched/walt/trace.h @@ -1186,6 +1186,28 @@ DEFINE_EVENT(walt_cfs_mvp_task_template, walt_cfs_mvp_wakeup_preempt, TP_PROTO(struct task_struct *p, struct walt_task_struct *wts, unsigned int limit), TP_ARGS(p, wts, limit)); +#define SPAN_SIZE (NR_CPUS/4) + +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; + strscpy(__entry->span, span, SPAN_SIZE); + ), + + TP_printk("overutilized=%d span=0x%s", + __entry->overutilized, __entry->span) +); + #endif /* _TRACE_WALT_H */ #undef TRACE_INCLUDE_PATH diff --git a/kernel/sched/walt/walt.h b/kernel/sched/walt/walt.h index b0dc1690ae15..72e7616487f3 100644 --- a/kernel/sched/walt/walt.h +++ b/kernel/sched/walt/walt.h @@ -228,6 +228,9 @@ extern unsigned int sysctl_sched_many_wakeup_threshold; extern unsigned int sysctl_walt_rtg_cfs_boost_prio; extern __read_mostly unsigned int sysctl_sched_force_lb_enable; extern const int sched_user_hint_max; +extern unsigned int sysctl_sched_dynamic_tp_enable; +extern int sched_dynamic_tp_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); extern struct list_head cluster_head; #define for_each_sched_cluster(cluster) \ diff --git a/kernel/sched/walt/walt_tp.c b/kernel/sched/walt/walt_tp.c new file mode 100644 index 000000000000..f809128fddd0 --- /dev/null +++ b/kernel/sched/walt/walt_tp.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "trace.h" + +unsigned int sysctl_sched_dynamic_tp_enable; + +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 walt_register_dynamic_tp_events(void) +{ + register_trace_sched_overutilized_tp(sched_overutilized, NULL); +} + +static void walt_unregister_dynamic_tp_events(void) +{ + unregister_trace_sched_overutilized_tp(sched_overutilized, NULL); +} + +int sched_dynamic_tp_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + static DEFINE_MUTEX(mutex); + int ret = 0, *val = (unsigned int *)table->data; + unsigned int old_val; + + mutex_lock(&mutex); + old_val = sysctl_sched_dynamic_tp_enable; + + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (ret || !write || (old_val == sysctl_sched_dynamic_tp_enable)) + goto done; + + if (*val) + walt_register_dynamic_tp_events(); + else + walt_unregister_dynamic_tp_events(); +done: + mutex_unlock(&mutex); + return ret; +}