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 <clingutla@codeaurora.org>
This commit is contained in:
Lingutla Chandrasekhar 2021-05-26 12:23:22 +05:30 committed by Rishabh Bhatnagar
parent efabb036d0
commit 242434fe46
5 changed files with 89 additions and 1 deletions

View File

@ -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

View File

@ -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,
},
{ }
};

View File

@ -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

View File

@ -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) \

View File

@ -0,0 +1,54 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/tracepoint.h>
#include <trace/hooks/sched.h>
#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;
}