From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Tomas Glozar <tglozar@redhat.com>,
Steven Rostedt <rostedt@goodmis.org>,
Sasha Levin <sashal@kernel.org>,
bristot@kernel.org, jstancek@redhat.com,
limingming890315@gmail.com, linux-trace-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.12 10/36] rtla/utils: Add idle state disabling via libcpupower
Date: Wed, 4 Dec 2024 10:45:26 -0500 [thread overview]
Message-ID: <20241204154626.2211476-10-sashal@kernel.org> (raw)
In-Reply-To: <20241204154626.2211476-1-sashal@kernel.org>
From: Tomas Glozar <tglozar@redhat.com>
[ Upstream commit 083d29d3784319e9e9fab3ac02683a7b26ae3480 ]
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.
Link: https://lore.kernel.org/20241017140914.3200454-4-tglozar@redhat.com
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
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 0735fcb827ed7..230f9fc7502dd 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;
+
+ nr_states = cpuidle_state_count(cpu);
+
+ if (nr_states == 0)
+ return 0;
+
+ if (!saved_cpu_idle_disable_state)
+ return -1;
+
+ 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 99c9cf81bcd02..101d4799a0090 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -66,6 +66,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.43.0
next prev parent reply other threads:[~2024-12-04 16:58 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-04 15:45 [PATCH AUTOSEL 6.12 01/36] pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 02/36] rtla: Fix consistency in getopt_long for timerlat_hist Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 03/36] tracing/ftrace: disable preemption in syscall probe Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 04/36] tracing: Use atomic64_inc_return() in trace_clock_counter() Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 05/36] tools/rtla: fix collision with glibc sched_attr/sched_set_attr Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 06/36] rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 07/36] rtla/timerlat: Make timerlat_hist_cpu->*_count " Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 08/36] scsi: hisi_sas: Add cond_resched() for no forced preemption model Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 09/36] scsi: hisi_sas: Create all dump files during debugfs initialization Sasha Levin
2024-12-04 15:45 ` Sasha Levin [this message]
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 11/36] ring-buffer: Limit time with disabled interrupts in rb_check_pages() Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 12/36] pinmux: Use sequential access to access desc->pinmux data Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 13/36] scsi: ufs: core: Make DMA mask configuration more flexible Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 14/36] iommu/amd: Fix corruption when mapping large pages from 0 Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 15/36] mfd: axp20x: Allow multiple regulators Sasha Levin
2024-12-07 21:34 ` Andre Przywara
2024-12-10 16:13 ` Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 16/36] bpf: put bpf_link's program when link is safe to be deallocated Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 17/36] scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 18/36] scsi: lpfc: Check SLI_ACTIVE flag in FDMI cmpl before submitting follow up FDMI Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 19/36] scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 20/36] clk: qcom: rcg2: add clk_rcg2_shared_floor_ops Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 21/36] clk: qcom: rpmh: add support for SAR2130P Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 22/36] clk: qcom: tcsrcc-sm8550: add SAR2130P support Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 23/36] clk: qcom: dispcc-sm8550: enable support for SAR2130P Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 24/36] clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574 Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 25/36] leds: class: Protect brightness_show() with led_cdev->led_access mutex Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 26/36] scsi: st: Don't modify unknown block number in MTIOCGET Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 27/36] scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 28/36] pinctrl: qcom-pmic-gpio: add support for PM8937 Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 29/36] pinctrl: qcom: spmi-mpp: Add PM8937 compatible Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 30/36] thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 31/36] nvdimm: rectify the illogical code within nd_dax_probe() Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 32/36] smb: client: memcpy() with surrounding object base address Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 33/36] tracing: Fix function name for trampoline Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 34/36] tools/rtla: Enhance argument parsing in timerlat_load.py Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 35/36] verification/dot2: Improve dot parser robustness Sasha Levin
2024-12-04 15:45 ` [PATCH AUTOSEL 6.12 36/36] mailbox: pcc: Check before sending MCTP PCC response ACK Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241204154626.2211476-10-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bristot@kernel.org \
--cc=jstancek@redhat.com \
--cc=limingming890315@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=stable@vger.kernel.org \
--cc=tglozar@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.