linux-trace-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat
@ 2024-06-12 14:54 tglozar
  2024-06-12 14:54 ` [PATCH 1/5] rtla: Add dependency on libcpupower tglozar
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, Tomas Glozar

From: Tomas Glozar <tglozar@redhat.com>

rtla-timerlat allows reducing latency on wake up from idle by setting
/dev/cpu_dma_latency during the timerlat measurement. This has an effect on
the idle states of all CPUs, including those which are not used by timerlat.

Add option --disable-idle-states that disables all idle states only on
the CPUs where timerlat measurements are running.

libcpupower is used to do the disabling of idle states via the corresponding
sysfs interface.

Tomas Glozar (5):
  rtla: Add dependency on libcpupower
  rtla/utils: Add idle state disabling via libcpupower
  rtla/timerlat: Add --disable-idle-states for top
  rtla/timerlat: Add --disable-idle-states for hist
  rtla: Documentation: Add --disable-idle-states

 .../tools/rtla/common_timerlat_options.rst    |   6 +
 tools/build/Makefile.feature                  |   1 +
 tools/build/feature/Makefile                  |   4 +
 tools/build/feature/test-libcpupower.c        |   8 ++
 tools/tracing/rtla/Makefile                   |   2 +
 tools/tracing/rtla/Makefile.config            |   9 ++
 tools/tracing/rtla/README.txt                 |   4 +
 tools/tracing/rtla/src/timerlat_hist.c        |  35 ++++-
 tools/tracing/rtla/src/timerlat_top.c         |  35 ++++-
 tools/tracing/rtla/src/utils.c                | 133 ++++++++++++++++++
 tools/tracing/rtla/src/utils.h                |   4 +
 11 files changed, 239 insertions(+), 2 deletions(-)
 create mode 100644 tools/build/feature/test-libcpupower.c

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] rtla: Add dependency on libcpupower
  2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
@ 2024-06-12 14:54 ` tglozar
  2024-06-21  8:46   ` Daniel Bristot de Oliveira
  2024-06-12 14:54 ` [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower tglozar
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, Tomas Glozar

From: Tomas Glozar <tglozar@redhat.com>

Add a test for libcpupower into feature tests and use it to add a
dependency on libcpupower to rtla.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 tools/build/Makefile.feature           | 1 +
 tools/build/feature/Makefile           | 4 ++++
 tools/build/feature/test-libcpupower.c | 8 ++++++++
 tools/tracing/rtla/Makefile            | 2 ++
 tools/tracing/rtla/Makefile.config     | 9 +++++++++
 5 files changed, 24 insertions(+)
 create mode 100644 tools/build/feature/test-libcpupower.c

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 ed54cef450f5..c93d62afc1e8 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 libtraceevent 2>/dev/null) -ltracefs
 
diff --git a/tools/build/feature/test-libcpupower.c b/tools/build/feature/test-libcpupower.c
new file mode 100644
index 000000000000..a346aa332a71
--- /dev/null
+++ b/tools/build/feature/test-libcpupower.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <cpuidle.h>
+
+int main(void)
+{
+	int rv = cpuidle_state_count(0);
+	return rv;
+}
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..8b6bc91e5dff 100644
--- a/tools/tracing/rtla/Makefile.config
+++ b/tools/tracing/rtla/Makefile.config
@@ -42,6 +42,15 @@ 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)
+else
+  STOP_ERROR := 1
+  $(info libcpupower is missing. Please install libcpupower-dev/kernel-tools-libs-devel)
+endif
+
 ifeq ($(STOP_ERROR),1)
   $(error Please, check the errors above.)
 endif
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower
  2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
  2024-06-12 14:54 ` [PATCH 1/5] rtla: Add dependency on libcpupower tglozar
@ 2024-06-12 14:54 ` tglozar
  2024-06-21  8:46   ` Daniel Bristot de Oliveira
  2024-06-12 14:54 ` [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top tglozar
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, 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 | 133 +++++++++++++++++++++++++++++++++
 tools/tracing/rtla/src/utils.h |   4 +
 2 files changed, 137 insertions(+)

diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 9ac71a66840c..638c50f0f88e 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -4,6 +4,7 @@
  */
 
 #define _GNU_SOURCE
+#include <cpuidle.h>
 #include <dirent.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -519,6 +520,138 @@ int set_cpu_dma_latency(int32_t latency)
 	return fd;
 }
 
+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 *));
+	}
+
+	saved_cpu_idle_disable_state[cpu] = calloc(nr_states, sizeof(unsigned int));
+	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;
+
+	nr_states = cpuidle_state_count(cpu);
+
+	if (nr_states == 0)
+		return 0;
+
+	for (state = 0; state < nr_states; state++) {
+		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;
+
+	if (!saved_cpu_idle_disable_state)
+		return;
+
+	for (cpu = 0; cpu < sysconf(_SC_NPROCESSORS_CONF); cpu++) {
+		if (!saved_cpu_idle_disable_state[cpu])
+			continue;
+		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_cpu_idle_disable_state - set disable for all idle states of a cpu
+ *
+ * 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_cpu_idle_disable_state(unsigned int cpu, unsigned int disable)
+{
+	unsigned int nr_states;
+	unsigned int state;
+	int result;
+
+	nr_states = cpuidle_state_count(cpu);
+
+	for (state = 0; state < nr_states; state++) {
+		result = cpuidle_state_disable(cpu, state, disable);
+		if (result < 0)
+			return result;
+	}
+
+	return nr_states;
+}
+
 #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..b310ed5cd867 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -64,6 +64,10 @@ 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);
+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_cpu_idle_disable_state(unsigned int cpu, unsigned int disable);
 int auto_house_keeping(cpu_set_t *monitored_cpus);
 
 #define ns_to_usf(x) (((double)x/1000))
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top
  2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
  2024-06-12 14:54 ` [PATCH 1/5] rtla: Add dependency on libcpupower tglozar
  2024-06-12 14:54 ` [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower tglozar
@ 2024-06-12 14:54 ` tglozar
  2024-06-21  8:45   ` Daniel Bristot de Oliveira
  2024-06-12 14:54 ` [PATCH 4/5] rtla/timerlat: Add --disable-idle-states for hist tglozar
  2024-06-12 14:54 ` [PATCH 5/5] rtla: Documentation: Add --disable-idle-states tglozar
  4 siblings, 1 reply; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, Tomas Glozar

From: Tomas Glozar <tglozar@redhat.com>

Add option to disable idle states 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 | 35 ++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 8c16419fe22a..dd1e5b03d781 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			disable_idle_states;
 	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] [--disable-idle-states]",
 		"",
 		"	  -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",
+		"	     --disable-idle-states: disable all idle states for 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->disable_idle_states = 0;
+
 	/* 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'},
+			{"disable-idle-states",	no_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->disable_idle_states = 1;
+			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 i;
 
 	params = timerlat_top_parse_args(argc, argv);
 	if (!params)
@@ -971,6 +981,21 @@ int timerlat_top_main(int argc, char *argv[])
 		}
 	}
 
+	if (params->disable_idle_states) {
+		for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) {
+			if (params->cpus && !CPU_ISSET(i, &params->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_cpu_idle_disable_state(i, 1) < 0) {
+				err_msg("Could not disable cpu idle state.\n");
+				goto out_free;
+			}
+		}
+	}
+
 	if (params->trace_output) {
 		record = osnoise_init_trace_tool("timerlat");
 		if (!record) {
@@ -1125,6 +1150,13 @@ int timerlat_top_main(int argc, char *argv[])
 	timerlat_aa_destroy();
 	if (dma_latency_fd >= 0)
 		close(dma_latency_fd);
+	if (params->disable_idle_states) {
+		for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) {
+			if (params->cpus && !CPU_ISSET(i, &params->monitored_cpus))
+				continue;
+			restore_cpu_idle_disable_state(i);
+		}
+	}
 	trace_events_destroy(&record->trace, params->events);
 	params->events = NULL;
 out_free:
@@ -1134,6 +1166,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.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/5] rtla/timerlat: Add --disable-idle-states for hist
  2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
                   ` (2 preceding siblings ...)
  2024-06-12 14:54 ` [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top tglozar
@ 2024-06-12 14:54 ` tglozar
  2024-06-12 14:54 ` [PATCH 5/5] rtla: Documentation: Add --disable-idle-states tglozar
  4 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, Tomas Glozar

From: Tomas Glozar <tglozar@redhat.com>

Support disabling idle states also for timerlat-hist.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 tools/tracing/rtla/src/timerlat_hist.c | 35 +++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index a3907c390d67..69d427841d14 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			disable_idle_states;
 };
 
 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] [--disable-idle-states]",
 		"",
 		"	  -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",
+		"	     --disable-idle-states: disable all idle states for 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->disable_idle_states = 0;
+
 	/* 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'},
+			{"disable-idle-states",	no_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->disable_idle_states = 1;
+			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 i;
 
 	params = timerlat_hist_parse_args(argc, argv);
 	if (!params)
@@ -1201,6 +1211,21 @@ int timerlat_hist_main(int argc, char *argv[])
 		}
 	}
 
+	if (params->disable_idle_states) {
+		for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) {
+			if (params->cpus && !CPU_ISSET(i, &params->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_cpu_idle_disable_state(i, 1) < 0) {
+				err_msg("Could not disable cpu idle state.\n");
+				goto out_free;
+			}
+		}
+	}
+
 	if (params->trace_output) {
 		record = osnoise_init_trace_tool("timerlat");
 		if (!record) {
@@ -1332,6 +1357,13 @@ int timerlat_hist_main(int argc, char *argv[])
 	timerlat_aa_destroy();
 	if (dma_latency_fd >= 0)
 		close(dma_latency_fd);
+	if (params->disable_idle_states) {
+		for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) {
+			if (params->cpus && !CPU_ISSET(i, &params->monitored_cpus))
+				continue;
+			restore_cpu_idle_disable_state(i);
+		}
+	}
 	trace_events_destroy(&record->trace, params->events);
 	params->events = NULL;
 out_free:
@@ -1340,6 +1372,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.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/5] rtla: Documentation: Add --disable-idle-states
  2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
                   ` (3 preceding siblings ...)
  2024-06-12 14:54 ` [PATCH 4/5] rtla/timerlat: Add --disable-idle-states for hist tglozar
@ 2024-06-12 14:54 ` tglozar
  4 siblings, 0 replies; 9+ messages in thread
From: tglozar @ 2024-06-12 14:54 UTC (permalink / raw)
  To: bristot, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt, Tomas Glozar

From: Tomas Glozar <tglozar@redhat.com>

Add --disable-idle-states to manpage and mention libcpupower dependency
in README.txt.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 Documentation/tools/rtla/common_timerlat_options.rst | 6 ++++++
 tools/tracing/rtla/README.txt                        | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/Documentation/tools/rtla/common_timerlat_options.rst b/Documentation/tools/rtla/common_timerlat_options.rst
index cef6651f1435..7429e77f95ca 100644
--- a/Documentation/tools/rtla/common_timerlat_options.rst
+++ b/Documentation/tools/rtla/common_timerlat_options.rst
@@ -31,6 +31,12 @@
         *cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
         similar results.
 
+**--disable-idle-states**
+        Set the /sys/devices/system/cpu/cpu<n>/cpuidle/state*/disable files to 1 for cpus
+        that are running timerlat threads to avoid exit from idle latencies. On exit from
+        timerlat, the state*/disable setting is restored to its original value before
+        running timerlat.
+
 **-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..6617b9911c81 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
 
 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.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top
  2024-06-12 14:54 ` [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top tglozar
@ 2024-06-21  8:45   ` Daniel Bristot de Oliveira
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Bristot de Oliveira @ 2024-06-21  8:45 UTC (permalink / raw)
  To: tglozar, rostedt; +Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt

On 6/12/24 16:54, tglozar@redhat.com wrote:
> @@ -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'},
> +			{"disable-idle-states",	no_argument,		0, '8'},

Can we add an argument with a state level to set?

>  			{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->disable_idle_states = 1;
> +			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 i;
>  
>  	params = timerlat_top_parse_args(argc, argv);
>  	if (!params)
> @@ -971,6 +981,21 @@ int timerlat_top_main(int argc, char *argv[])
>  		}
>  	}
>  
> +	if (params->disable_idle_states) {
> +		for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++) {
> +			if (params->cpus && !CPU_ISSET(i, &params->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_cpu_idle_disable_state(i, 1) < 0) {

and use the argument state here?                                    ^

-- Daniel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower
  2024-06-12 14:54 ` [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower tglozar
@ 2024-06-21  8:46   ` Daniel Bristot de Oliveira
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Bristot de Oliveira @ 2024-06-21  8:46 UTC (permalink / raw)
  To: tglozar, rostedt; +Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt

On 6/12/24 16:54, tglozar@redhat.com wrote:
> +
> +	nr_states = cpuidle_state_count(cpu);
> +

Question: Is this library implemented for all archs or only
intel &| arm?

If it is restricted to few archs, it is another point to make
it optional.

-- Daniel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/5] rtla: Add dependency on libcpupower
  2024-06-12 14:54 ` [PATCH 1/5] rtla: Add dependency on libcpupower tglozar
@ 2024-06-21  8:46   ` Daniel Bristot de Oliveira
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Bristot de Oliveira @ 2024-06-21  8:46 UTC (permalink / raw)
  To: tglozar, rostedt
  Cc: linux-trace-kernel, linux-kernel, jkacur, jwyatt,
	Arnaldo Carvalho de Melo

Hi Thomas

On 6/12/24 16:54, tglozar@redhat.com wrote:
> From: Tomas Glozar <tglozar@redhat.com>

I think we can split this into two patches, this first part on tools/Build:

> Add a test for libcpupower into feature tests and use it to add a
> dependency on libcpupower to rtla.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  tools/build/Makefile.feature           | 1 +
>  tools/build/feature/Makefile           | 4 ++++
>  tools/build/feature/test-libcpupower.c | 8 ++++++++
>  tools/tracing/rtla/Makefile            | 2 ++
>  tools/tracing/rtla/Makefile.config     | 9 +++++++++
>  5 files changed, 24 insertions(+)
>  create mode 100644 tools/build/feature/test-libcpupower.c
> 
> 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 ed54cef450f5..c93d62afc1e8 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 libtraceevent 2>/dev/null) -ltracefs
>  
> diff --git a/tools/build/feature/test-libcpupower.c b/tools/build/feature/test-libcpupower.c
> new file mode 100644
> index 000000000000..a346aa332a71
> --- /dev/null
> +++ b/tools/build/feature/test-libcpupower.c
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <cpuidle.h>
> +
> +int main(void)
> +{
> +	int rv = cpuidle_state_count(0);
> +	return rv;
> +}
> diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
> index b5878be36125..a6a7dee16622 100644


And this part for rtla:

> --- 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..8b6bc91e5dff 100644
> --- a/tools/tracing/rtla/Makefile.config
> +++ b/tools/tracing/rtla/Makefile.config
> @@ -42,6 +42,15 @@ 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)
> +else

Also, it is better to make it optional: if the system has this library,
set a CONFIG_HAS_LIBCPUPOWER, otherwise no..

> +  STOP_ERROR := 1
> +  $(info libcpupower is missing. Please install libcpupower-dev/kernel-tools-libs-devel)
> +endif

Then, place your code inside this option. If the option is called
but the tool was not compiled with CONFIG_HAS_LIBCPUPOWER, just
complain saying that the option is not supported because it was
compiled without it. Then put this info there, to compile
with these options enabled.

>  ifeq ($(STOP_ERROR),1)
>    $(error Please, check the errors above.)
>  endif


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-06-21  8:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-12 14:54 [PATCH 0/5] rtla: Support idle state disabling via libcpupower in timerlat tglozar
2024-06-12 14:54 ` [PATCH 1/5] rtla: Add dependency on libcpupower tglozar
2024-06-21  8:46   ` Daniel Bristot de Oliveira
2024-06-12 14:54 ` [PATCH 2/5] rtla/utils: Add idle state disabling via libcpupower tglozar
2024-06-21  8:46   ` Daniel Bristot de Oliveira
2024-06-12 14:54 ` [PATCH 3/5] rtla/timerlat: Add --disable-idle-states for top tglozar
2024-06-21  8:45   ` Daniel Bristot de Oliveira
2024-06-12 14:54 ` [PATCH 4/5] rtla/timerlat: Add --disable-idle-states for hist tglozar
2024-06-12 14:54 ` [PATCH 5/5] rtla: Documentation: Add --disable-idle-states tglozar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).