* [PATCH RESEND v3 1/6] tools/build: Add libcpupower dependency detection
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
@ 2024-10-04 9:50 ` tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 2/6] rtla: Add optional dependency on libcpupower tglozar
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
Add the ability to detect the presence of libcpupower on a system to
the Makefiles in tools/build.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
tools/build/Makefile.feature | 1 +
tools/build/feature/Makefile | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 1e2ab148d5db..e4fb0a1fbddf 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -53,6 +53,7 @@ FEATURE_TESTS_BASIC := \
libslang-include-subdir \
libtraceevent \
libtracefs \
+ libcpupower \
libcrypto \
libunwind \
pthread-attr-setaffinity-np \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 489cbed7e82a..c4a78333660b 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -38,6 +38,7 @@ FILES= \
test-libslang.bin \
test-libslang-include-subdir.bin \
test-libtraceevent.bin \
+ test-libcpupower.bin \
test-libtracefs.bin \
test-libcrypto.bin \
test-libunwind.bin \
@@ -212,6 +213,9 @@ $(OUTPUT)test-libslang-include-subdir.bin:
$(OUTPUT)test-libtraceevent.bin:
$(BUILD) -ltraceevent
+$(OUTPUT)test-libcpupower.bin:
+ $(BUILD) -lcpupower
+
$(OUTPUT)test-libtracefs.bin:
$(BUILD) $(shell $(PKG_CONFIG) --cflags libtracefs 2>/dev/null) -ltracefs
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH RESEND v3 2/6] rtla: Add optional dependency on libcpupower
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 1/6] tools/build: Add libcpupower dependency detection tglozar
@ 2024-10-04 9:50 ` tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower tglozar
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
If libcpupower is present, set HAVE_LIBCPUPOWER_SUPPORT macro to allow
features depending on libcpupower in rtla.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
tools/tracing/rtla/Makefile | 2 ++
tools/tracing/rtla/Makefile.config | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
index b5878be36125..a6a7dee16622 100644
--- a/tools/tracing/rtla/Makefile
+++ b/tools/tracing/rtla/Makefile
@@ -32,8 +32,10 @@ DOCSRC := ../../../Documentation/tools/rtla/
FEATURE_TESTS := libtraceevent
FEATURE_TESTS += libtracefs
+FEATURE_TESTS += libcpupower
FEATURE_DISPLAY := libtraceevent
FEATURE_DISPLAY += libtracefs
+FEATURE_DISPLAY += libcpupower
ifeq ($(V),1)
Q =
diff --git a/tools/tracing/rtla/Makefile.config b/tools/tracing/rtla/Makefile.config
index 0b7ecfb30d19..5f6f537c9728 100644
--- a/tools/tracing/rtla/Makefile.config
+++ b/tools/tracing/rtla/Makefile.config
@@ -42,6 +42,16 @@ else
$(info libtracefs is missing. Please install libtracefs-dev/libtracefs-devel)
endif
+$(call feature_check,libcpupower)
+ifeq ($(feature-libcpupower), 1)
+ $(call detected,CONFIG_LIBCPUPOWER)
+ $(call lib_setup,cpupower)
+ CFLAGS += -DHAVE_LIBCPUPOWER_SUPPORT
+else
+ $(info libcpupower is missing, building without --deepest-idle-state support.)
+ $(info Please install libcpupower-dev/kernel-tools-libs-devel)
+endif
+
ifeq ($(STOP_ERROR),1)
$(error Please, check the errors above.)
endif
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 1/6] tools/build: Add libcpupower dependency detection tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 2/6] rtla: Add optional dependency on libcpupower tglozar
@ 2024-10-04 9:50 ` tglozar
2024-10-10 20:06 ` Steven Rostedt
2024-10-04 9:50 ` [PATCH RESEND v3 4/6] rtla/timerlat: Add --deepest-idle-state for top tglozar
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
Add functions to utils.c to disable idle states through functions of
libcpupower. This will serve as the basis for disabling idle states
per cpu when running timerlat.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
tools/tracing/rtla/src/utils.c | 150 +++++++++++++++++++++++++++++++++
tools/tracing/rtla/src/utils.h | 13 +++
2 files changed, 163 insertions(+)
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 9ac71a66840c..6ae084fdedf9 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -4,6 +4,9 @@
*/
#define _GNU_SOURCE
+#ifdef HAVE_LIBCPUPOWER_SUPPORT
+#include <cpuidle.h>
+#endif /* HAVE_LIBCPUPOWER_SUPPORT */
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -519,6 +522,153 @@ int set_cpu_dma_latency(int32_t latency)
return fd;
}
+#ifdef HAVE_LIBCPUPOWER_SUPPORT
+static unsigned int **saved_cpu_idle_disable_state;
+static size_t saved_cpu_idle_disable_state_alloc_ctr;
+
+/*
+ * save_cpu_idle_state_disable - save disable for all idle states of a cpu
+ *
+ * Saves the current disable of all idle states of a cpu, to be subsequently
+ * restored via restore_cpu_idle_disable_state.
+ *
+ * Return: idle state count on success, negative on error
+ */
+int save_cpu_idle_disable_state(unsigned int cpu)
+{
+ unsigned int nr_states;
+ unsigned int state;
+ int disabled;
+ int nr_cpus;
+
+ nr_states = cpuidle_state_count(cpu);
+
+ if (nr_states == 0)
+ return 0;
+
+ if (saved_cpu_idle_disable_state == NULL) {
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+ saved_cpu_idle_disable_state = calloc(nr_cpus, sizeof(unsigned int *));
+ if (!saved_cpu_idle_disable_state)
+ return -1;
+ }
+
+ saved_cpu_idle_disable_state[cpu] = calloc(nr_states, sizeof(unsigned int));
+ if (!saved_cpu_idle_disable_state[cpu])
+ return -1;
+ saved_cpu_idle_disable_state_alloc_ctr++;
+
+ for (state = 0; state < nr_states; state++) {
+ disabled = cpuidle_is_state_disabled(cpu, state);
+ if (disabled < 0)
+ return disabled;
+ saved_cpu_idle_disable_state[cpu][state] = disabled;
+ }
+
+ return nr_states;
+}
+
+/*
+ * restore_cpu_idle_disable_state - restore disable for all idle states of a cpu
+ *
+ * Restores the current disable state of all idle states of a cpu that was
+ * previously saved by save_cpu_idle_disable_state.
+ *
+ * Return: idle state count on success, negative on error
+ */
+int restore_cpu_idle_disable_state(unsigned int cpu)
+{
+ unsigned int nr_states;
+ unsigned int state;
+ int disabled;
+ int result;
+
+ if (!saved_cpu_idle_disable_state)
+ return -1;
+
+ nr_states = cpuidle_state_count(cpu);
+
+ if (nr_states == 0)
+ return 0;
+
+ for (state = 0; state < nr_states; state++) {
+ if (!saved_cpu_idle_disable_state[cpu])
+ return -1;
+ disabled = saved_cpu_idle_disable_state[cpu][state];
+ result = cpuidle_state_disable(cpu, state, disabled);
+ if (result < 0)
+ return result;
+ }
+
+ free(saved_cpu_idle_disable_state[cpu]);
+ saved_cpu_idle_disable_state[cpu] = NULL;
+ saved_cpu_idle_disable_state_alloc_ctr--;
+ if (saved_cpu_idle_disable_state_alloc_ctr == 0) {
+ free(saved_cpu_idle_disable_state);
+ saved_cpu_idle_disable_state = NULL;
+ }
+
+ return nr_states;
+}
+
+/*
+ * free_cpu_idle_disable_states - free saved idle state disable for all cpus
+ *
+ * Frees the memory used for storing cpu idle state disable for all cpus
+ * and states.
+ *
+ * Normally, the memory is freed automatically in
+ * restore_cpu_idle_disable_state; this is mostly for cleaning up after an
+ * error.
+ */
+void free_cpu_idle_disable_states(void)
+{
+ int cpu;
+ int nr_cpus;
+
+ if (!saved_cpu_idle_disable_state)
+ return;
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ for (cpu = 0; cpu < nr_cpus; cpu++) {
+ free(saved_cpu_idle_disable_state[cpu]);
+ saved_cpu_idle_disable_state[cpu] = NULL;
+ }
+
+ free(saved_cpu_idle_disable_state);
+ saved_cpu_idle_disable_state = NULL;
+}
+
+/*
+ * set_deepest_cpu_idle_state - limit idle state of cpu
+ *
+ * Disables all idle states deeper than the one given in
+ * deepest_state (assuming states with higher number are deeper).
+ *
+ * This is used to reduce the exit from idle latency. Unlike
+ * set_cpu_dma_latency, it can disable idle states per cpu.
+ *
+ * Return: idle state count on success, negative on error
+ */
+int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int deepest_state)
+{
+ unsigned int nr_states;
+ unsigned int state;
+ int result;
+
+ nr_states = cpuidle_state_count(cpu);
+
+ for (state = deepest_state + 1; state < nr_states; state++) {
+ result = cpuidle_state_disable(cpu, state, 1);
+ if (result < 0)
+ return result;
+ }
+
+ return nr_states;
+}
+#endif /* HAVE_LIBCPUPOWER_SUPPORT */
+
#define _STR(x) #x
#define STR(x) _STR(x)
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index d44513e6c66a..e439db7fc848 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -64,6 +64,19 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
int set_comm_cgroup(const char *comm_prefix, const char *cgroup);
int set_pid_cgroup(pid_t pid, const char *cgroup);
int set_cpu_dma_latency(int32_t latency);
+#ifdef HAVE_LIBCPUPOWER_SUPPORT
+int save_cpu_idle_disable_state(unsigned int cpu);
+int restore_cpu_idle_disable_state(unsigned int cpu);
+void free_cpu_idle_disable_states(void);
+int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int state);
+static inline int have_libcpupower_support(void) { return 1; }
+#else
+static inline int save_cpu_idle_disable_state(unsigned int cpu) { return -1; }
+static inline int restore_cpu_idle_disable_state(unsigned int cpu) { return -1; }
+static inline void free_cpu_idle_disable_states(void) { }
+static inline int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int state) { return -1; }
+static inline int have_libcpupower_support(void) { return 0; }
+#endif /* HAVE_LIBCPUPOWER_SUPPORT */
int auto_house_keeping(cpu_set_t *monitored_cpus);
#define ns_to_usf(x) (((double)x/1000))
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower
2024-10-04 9:50 ` [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower tglozar
@ 2024-10-10 20:06 ` Steven Rostedt
2024-10-11 10:46 ` Tomas Glozar
0 siblings, 1 reply; 9+ messages in thread
From: Steven Rostedt @ 2024-10-10 20:06 UTC (permalink / raw)
To: tglozar; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur
On Fri, 4 Oct 2024 11:50:11 +0200
tglozar@redhat.com wrote:
> From: Tomas Glozar <tglozar@redhat.com>
>
> Add functions to utils.c to disable idle states through functions of
> libcpupower. This will serve as the basis for disabling idle states
> per cpu when running timerlat.
>
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
> tools/tracing/rtla/src/utils.c | 150 +++++++++++++++++++++++++++++++++
> tools/tracing/rtla/src/utils.h | 13 +++
> 2 files changed, 163 insertions(+)
>
> diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
> index 9ac71a66840c..6ae084fdedf9 100644
> --- a/tools/tracing/rtla/src/utils.c
> +++ b/tools/tracing/rtla/src/utils.c
> @@ -4,6 +4,9 @@
> */
>
> #define _GNU_SOURCE
> +#ifdef HAVE_LIBCPUPOWER_SUPPORT
> +#include <cpuidle.h>
> +#endif /* HAVE_LIBCPUPOWER_SUPPORT */
> #include <dirent.h>
> #include <stdarg.h>
> #include <stdlib.h>
> @@ -519,6 +522,153 @@ int set_cpu_dma_latency(int32_t latency)
> return fd;
> }
>
> +#ifdef HAVE_LIBCPUPOWER_SUPPORT
> +static unsigned int **saved_cpu_idle_disable_state;
> +static size_t saved_cpu_idle_disable_state_alloc_ctr;
> +
> +/*
> + * save_cpu_idle_state_disable - save disable for all idle states of a cpu
> + *
> + * Saves the current disable of all idle states of a cpu, to be subsequently
> + * restored via restore_cpu_idle_disable_state.
> + *
> + * Return: idle state count on success, negative on error
> + */
> +int save_cpu_idle_disable_state(unsigned int cpu)
> +{
> + unsigned int nr_states;
> + unsigned int state;
> + int disabled;
> + int nr_cpus;
> +
> + nr_states = cpuidle_state_count(cpu);
> +
> + if (nr_states == 0)
> + return 0;
If nr_states is zero, this returns 0 without ever allocating
saved_cpu_idle_disable_state.
> +
> + if (saved_cpu_idle_disable_state == NULL) {
> + nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> + saved_cpu_idle_disable_state = calloc(nr_cpus, sizeof(unsigned int *));
> + if (!saved_cpu_idle_disable_state)
> + return -1;
> + }
> +
> + saved_cpu_idle_disable_state[cpu] = calloc(nr_states, sizeof(unsigned int));
> + if (!saved_cpu_idle_disable_state[cpu])
> + return -1;
> + saved_cpu_idle_disable_state_alloc_ctr++;
> +
> + for (state = 0; state < nr_states; state++) {
> + disabled = cpuidle_is_state_disabled(cpu, state);
> + if (disabled < 0)
> + return disabled;
> + saved_cpu_idle_disable_state[cpu][state] = disabled;
> + }
> +
> + return nr_states;
> +}
> +
> +/*
> + * restore_cpu_idle_disable_state - restore disable for all idle states of a cpu
> + *
> + * Restores the current disable state of all idle states of a cpu that was
> + * previously saved by save_cpu_idle_disable_state.
> + *
> + * Return: idle state count on success, negative on error
> + */
> +int restore_cpu_idle_disable_state(unsigned int cpu)
> +{
> + unsigned int nr_states;
> + unsigned int state;
> + int disabled;
> + int result;
> +
> + if (!saved_cpu_idle_disable_state)
> + return -1;
This returns -1 even if nr_states is zero. That is,
save_cpu_idle_disable_state() can return success, but this restore will
return failure.
-- Steve
> +
> + nr_states = cpuidle_state_count(cpu);
> +
> + if (nr_states == 0)
> + return 0;
> +
> + for (state = 0; state < nr_states; state++) {
> + if (!saved_cpu_idle_disable_state[cpu])
> + return -1;
> + disabled = saved_cpu_idle_disable_state[cpu][state];
> + result = cpuidle_state_disable(cpu, state, disabled);
> + if (result < 0)
> + return result;
> + }
> +
> + free(saved_cpu_idle_disable_state[cpu]);
> + saved_cpu_idle_disable_state[cpu] = NULL;
> + saved_cpu_idle_disable_state_alloc_ctr--;
> + if (saved_cpu_idle_disable_state_alloc_ctr == 0) {
> + free(saved_cpu_idle_disable_state);
> + saved_cpu_idle_disable_state = NULL;
> + }
> +
> + return nr_states;
> +}
> +
> +/*
> + * free_cpu_idle_disable_states - free saved idle state disable for all cpus
> + *
> + * Frees the memory used for storing cpu idle state disable for all cpus
> + * and states.
> + *
> + * Normally, the memory is freed automatically in
> + * restore_cpu_idle_disable_state; this is mostly for cleaning up after an
> + * error.
> + */
> +void free_cpu_idle_disable_states(void)
> +{
> + int cpu;
> + int nr_cpus;
> +
> + if (!saved_cpu_idle_disable_state)
> + return;
> +
> + nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> +
> + for (cpu = 0; cpu < nr_cpus; cpu++) {
> + free(saved_cpu_idle_disable_state[cpu]);
> + saved_cpu_idle_disable_state[cpu] = NULL;
> + }
> +
> + free(saved_cpu_idle_disable_state);
> + saved_cpu_idle_disable_state = NULL;
> +}
> +
> +/*
> + * set_deepest_cpu_idle_state - limit idle state of cpu
> + *
> + * Disables all idle states deeper than the one given in
> + * deepest_state (assuming states with higher number are deeper).
> + *
> + * This is used to reduce the exit from idle latency. Unlike
> + * set_cpu_dma_latency, it can disable idle states per cpu.
> + *
> + * Return: idle state count on success, negative on error
> + */
> +int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int deepest_state)
> +{
> + unsigned int nr_states;
> + unsigned int state;
> + int result;
> +
> + nr_states = cpuidle_state_count(cpu);
> +
> + for (state = deepest_state + 1; state < nr_states; state++) {
> + result = cpuidle_state_disable(cpu, state, 1);
> + if (result < 0)
> + return result;
> + }
> +
> + return nr_states;
> +}
> +#endif /* HAVE_LIBCPUPOWER_SUPPORT */
> +
> #define _STR(x) #x
> #define STR(x) _STR(x)
>
> diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
> index d44513e6c66a..e439db7fc848 100644
> --- a/tools/tracing/rtla/src/utils.h
> +++ b/tools/tracing/rtla/src/utils.h
> @@ -64,6 +64,19 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
> int set_comm_cgroup(const char *comm_prefix, const char *cgroup);
> int set_pid_cgroup(pid_t pid, const char *cgroup);
> int set_cpu_dma_latency(int32_t latency);
> +#ifdef HAVE_LIBCPUPOWER_SUPPORT
> +int save_cpu_idle_disable_state(unsigned int cpu);
> +int restore_cpu_idle_disable_state(unsigned int cpu);
> +void free_cpu_idle_disable_states(void);
> +int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int state);
> +static inline int have_libcpupower_support(void) { return 1; }
> +#else
> +static inline int save_cpu_idle_disable_state(unsigned int cpu) { return -1; }
> +static inline int restore_cpu_idle_disable_state(unsigned int cpu) { return -1; }
> +static inline void free_cpu_idle_disable_states(void) { }
> +static inline int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int state) { return -1; }
> +static inline int have_libcpupower_support(void) { return 0; }
> +#endif /* HAVE_LIBCPUPOWER_SUPPORT */
> int auto_house_keeping(cpu_set_t *monitored_cpus);
>
> #define ns_to_usf(x) (((double)x/1000))
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower
2024-10-10 20:06 ` Steven Rostedt
@ 2024-10-11 10:46 ` Tomas Glozar
0 siblings, 0 replies; 9+ messages in thread
From: Tomas Glozar @ 2024-10-11 10:46 UTC (permalink / raw)
To: Steven Rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur
čt 10. 10. 2024 v 22:06 odesílatel Steven Rostedt <rostedt@goodmis.org> napsal:
>
> If nr_states is zero, this returns 0 without ever allocating
> saved_cpu_idle_disable_state.
>
>> ...
>
> This returns -1 even if nr_states is zero. That is,
> save_cpu_idle_disable_state() can return success, but this restore will
> return failure.
>
> -- Steve
Oh I see: there might be no idle states to save,
saved_cpu_idle_disable_state doesn't get allocated at all, and then
restore_cpu_idle_disable_state behaves as the saves weren't saved
before. Checking for nr_state should fix that; I'll send a v3.
Tomas
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH RESEND v3 4/6] rtla/timerlat: Add --deepest-idle-state for top
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
` (2 preceding siblings ...)
2024-10-04 9:50 ` [PATCH RESEND v3 3/6] rtla/utils: Add idle state disabling via libcpupower tglozar
@ 2024-10-04 9:50 ` tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 5/6] rtla/timerlat: Add --deepest-idle-state for hist tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 6/6] rtla: Documentation: Mention --deepest-idle-state tglozar
5 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
Add option to limit deepest idle state on CPUs where timerlat is running
for the duration of the workload.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
tools/tracing/rtla/src/timerlat_top.c | 42 ++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 8c16419fe22a..56adb86898f2 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -48,6 +48,7 @@ struct timerlat_top_params {
int pretty_output;
int warmup;
int buffer_size;
+ int deepest_idle_state;
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;
@@ -447,7 +448,7 @@ static void timerlat_top_usage(char *usage)
"",
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
" [[-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
- " [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u|-k] [--warm-up s]",
+ " [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u|-k] [--warm-up s] [--deepest-idle-state n]",
"",
" -h/--help: print this menu",
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -481,6 +482,7 @@ static void timerlat_top_usage(char *usage)
" -U/--user-load: enable timerlat for user-defined user-space workload",
" --warm-up s: let the workload run for s seconds before collecting data",
" --trace-buffer-size kB: set the per-cpu trace buffer size in kB",
+ " --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
NULL,
};
@@ -518,6 +520,9 @@ static struct timerlat_top_params
/* disabled by default */
params->dma_latency = -1;
+ /* disabled by default */
+ params->deepest_idle_state = -2;
+
/* display data in microseconds */
params->output_divisor = 1000;
@@ -550,6 +555,7 @@ static struct timerlat_top_params
{"aa-only", required_argument, 0, '5'},
{"warm-up", required_argument, 0, '6'},
{"trace-buffer-size", required_argument, 0, '7'},
+ {"deepest-idle-state", required_argument, 0, '8'},
{0, 0, 0, 0}
};
@@ -726,6 +732,9 @@ static struct timerlat_top_params
case '7':
params->buffer_size = get_llong_from_str(optarg);
break;
+ case '8':
+ params->deepest_idle_state = get_llong_from_str(optarg);
+ break;
default:
timerlat_top_usage("Invalid option");
}
@@ -922,6 +931,7 @@ int timerlat_top_main(int argc, char *argv[])
int return_value = 1;
char *max_lat;
int retval;
+ int nr_cpus, i;
params = timerlat_top_parse_args(argc, argv);
if (!params)
@@ -971,6 +981,28 @@ int timerlat_top_main(int argc, char *argv[])
}
}
+ if (params->deepest_idle_state >= -1) {
+ if (!have_libcpupower_support()) {
+ err_msg("rtla built without libcpupower, --deepest-idle-state is not supported\n");
+ goto out_free;
+ }
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, ¶ms->monitored_cpus))
+ continue;
+ if (save_cpu_idle_disable_state(i) < 0) {
+ err_msg("Could not save cpu idle state.\n");
+ goto out_free;
+ }
+ if (set_deepest_cpu_idle_state(i, params->deepest_idle_state) < 0) {
+ err_msg("Could not set deepest cpu idle state.\n");
+ goto out_free;
+ }
+ }
+ }
+
if (params->trace_output) {
record = osnoise_init_trace_tool("timerlat");
if (!record) {
@@ -1125,6 +1157,13 @@ int timerlat_top_main(int argc, char *argv[])
timerlat_aa_destroy();
if (dma_latency_fd >= 0)
close(dma_latency_fd);
+ if (params->deepest_idle_state >= -1) {
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, ¶ms->monitored_cpus))
+ continue;
+ restore_cpu_idle_disable_state(i);
+ }
+ }
trace_events_destroy(&record->trace, params->events);
params->events = NULL;
out_free:
@@ -1134,6 +1173,7 @@ int timerlat_top_main(int argc, char *argv[])
osnoise_destroy_tool(record);
osnoise_destroy_tool(top);
free(params);
+ free_cpu_idle_disable_states();
out_exit:
exit(return_value);
}
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH RESEND v3 5/6] rtla/timerlat: Add --deepest-idle-state for hist
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
` (3 preceding siblings ...)
2024-10-04 9:50 ` [PATCH RESEND v3 4/6] rtla/timerlat: Add --deepest-idle-state for top tglozar
@ 2024-10-04 9:50 ` tglozar
2024-10-04 9:50 ` [PATCH RESEND v3 6/6] rtla: Documentation: Mention --deepest-idle-state tglozar
5 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
Support limiting deepest idle state also for timerlat-hist.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
tools/tracing/rtla/src/timerlat_hist.c | 42 +++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index a3907c390d67..99176951c414 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -55,6 +55,7 @@ struct timerlat_hist_params {
int entries;
int warmup;
int buffer_size;
+ int deepest_idle_state;
};
struct timerlat_hist_cpu {
@@ -655,7 +656,7 @@ static void timerlat_hist_usage(char *usage)
" [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
" [--no-index] [--with-zeros] [--dma-latency us] [-C[=cgroup_name]] [--no-aa] [--dump-task] [-u|-k]",
- " [--warm-up s]",
+ " [--warm-up s] [--deepest-idle-state n]",
"",
" -h/--help: print this menu",
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -695,6 +696,7 @@ static void timerlat_hist_usage(char *usage)
" -U/--user-load: enable timerlat for user-defined user-space workload",
" --warm-up s: let the workload run for s seconds before collecting data",
" --trace-buffer-size kB: set the per-cpu trace buffer size in kB",
+ " --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
NULL,
};
@@ -732,6 +734,9 @@ static struct timerlat_hist_params
/* disabled by default */
params->dma_latency = -1;
+ /* disabled by default */
+ params->deepest_idle_state = -2;
+
/* display data in microseconds */
params->output_divisor = 1000;
params->bucket_size = 1;
@@ -772,6 +777,7 @@ static struct timerlat_hist_params
{"dump-task", no_argument, 0, '\1'},
{"warm-up", required_argument, 0, '\2'},
{"trace-buffer-size", required_argument, 0, '\3'},
+ {"deepest-idle-state", required_argument, 0, '\4'},
{0, 0, 0, 0}
};
@@ -960,6 +966,9 @@ static struct timerlat_hist_params
case '\3':
params->buffer_size = get_llong_from_str(optarg);
break;
+ case '\4':
+ params->deepest_idle_state = get_llong_from_str(optarg);
+ break;
default:
timerlat_hist_usage("Invalid option");
}
@@ -1152,6 +1161,7 @@ int timerlat_hist_main(int argc, char *argv[])
int return_value = 1;
pthread_t timerlat_u;
int retval;
+ int nr_cpus, i;
params = timerlat_hist_parse_args(argc, argv);
if (!params)
@@ -1201,6 +1211,28 @@ int timerlat_hist_main(int argc, char *argv[])
}
}
+ if (params->deepest_idle_state >= -1) {
+ if (!have_libcpupower_support()) {
+ err_msg("rtla built without libcpupower, --deepest-idle-state is not supported\n");
+ goto out_free;
+ }
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, ¶ms->monitored_cpus))
+ continue;
+ if (save_cpu_idle_disable_state(i) < 0) {
+ err_msg("Could not save cpu idle state.\n");
+ goto out_free;
+ }
+ if (set_deepest_cpu_idle_state(i, params->deepest_idle_state) < 0) {
+ err_msg("Could not set deepest cpu idle state.\n");
+ goto out_free;
+ }
+ }
+ }
+
if (params->trace_output) {
record = osnoise_init_trace_tool("timerlat");
if (!record) {
@@ -1332,6 +1364,13 @@ int timerlat_hist_main(int argc, char *argv[])
timerlat_aa_destroy();
if (dma_latency_fd >= 0)
close(dma_latency_fd);
+ if (params->deepest_idle_state >= -1) {
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, ¶ms->monitored_cpus))
+ continue;
+ restore_cpu_idle_disable_state(i);
+ }
+ }
trace_events_destroy(&record->trace, params->events);
params->events = NULL;
out_free:
@@ -1340,6 +1379,7 @@ int timerlat_hist_main(int argc, char *argv[])
osnoise_destroy_tool(record);
osnoise_destroy_tool(tool);
free(params);
+ free_cpu_idle_disable_states();
out_exit:
exit(return_value);
}
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH RESEND v3 6/6] rtla: Documentation: Mention --deepest-idle-state
2024-10-04 9:50 [PATCH RESEND v3 0/6] rtla: Support idle state disabling via libcpupower in timerlat tglozar
` (4 preceding siblings ...)
2024-10-04 9:50 ` [PATCH RESEND v3 5/6] rtla/timerlat: Add --deepest-idle-state for hist tglozar
@ 2024-10-04 9:50 ` tglozar
5 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-10-04 9:50 UTC (permalink / raw)
To: rostedt; +Cc: linux-trace-kernel, linux-kernel, jwyatt, jkacur, Tomas Glozar
From: Tomas Glozar <tglozar@redhat.com>
Add --deepest-idle-state to manpage and mention libcpupower dependency
in README.txt.
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
Documentation/tools/rtla/common_timerlat_options.rst | 8 ++++++++
tools/tracing/rtla/README.txt | 4 ++++
2 files changed, 12 insertions(+)
diff --git a/Documentation/tools/rtla/common_timerlat_options.rst b/Documentation/tools/rtla/common_timerlat_options.rst
index cef6651f1435..10dc802f8d65 100644
--- a/Documentation/tools/rtla/common_timerlat_options.rst
+++ b/Documentation/tools/rtla/common_timerlat_options.rst
@@ -31,6 +31,14 @@
*cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
similar results.
+**--deepest-idle-state** *n*
+ Disable idle states higher than *n* for cpus that are running timerlat threads to
+ reduce exit from idle latencies. If *n* is -1, all idle states are disabled.
+ On exit from timerlat, the idle state setting is restored to its original state
+ before running timerlat.
+
+ Requires rtla to be built with libcpupower.
+
**-k**, **--kernel-threads**
Use timerlat kernel-space threads, in contrast of **-u**.
diff --git a/tools/tracing/rtla/README.txt b/tools/tracing/rtla/README.txt
index 4af3fd40f171..dd5621038c55 100644
--- a/tools/tracing/rtla/README.txt
+++ b/tools/tracing/rtla/README.txt
@@ -11,6 +11,7 @@ RTLA depends on the following libraries and tools:
- libtracefs
- libtraceevent
+ - libcpupower (optional, for --deepest-idle-state)
It also depends on python3-docutils to compile man pages.
@@ -26,6 +27,9 @@ For development, we suggest the following steps for compiling rtla:
$ make
$ sudo make install
$ cd ..
+ $ cd $libcpupower_src
+ $ make
+ $ sudo make install
$ cd $rtla_src
$ make
$ sudo make install
--
2.46.2
^ permalink raw reply related [flat|nested] 9+ messages in thread