* [PATCH v4 0/2] Exposing nice CPU usage to userspace
@ 2024-10-02 18:47 Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 1/2] cgroup/rstat: Tracking cgroup-level niced CPU time Joshua Hahn
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Joshua Hahn @ 2024-10-02 18:47 UTC (permalink / raw)
To: tj, mkoutny
Cc: cgroups, hannes, linux-kernel, linux-kselftest, lizefan.x, shuah
Changes in v4
- Removed unnecessary forking from selftest.
- Style changes in rstat.c (fallthrough & indents)
- Fixed a selftest bug that raised false negatives, caused by
cputime_adjust sometimes adjusting utime below ntime.
- Reworded cover letter for clarity & motivation
Changes in v3
- Signed-off-by & renamed subject for clarity.
Changes in v2
- Edited commit messages for clarity.
Niced CPU usage is a metric reported in host-level /proc/stat, but is
not currently reported in cgroup-level statistics. Thus, even if one
can observe that a fracion of the host's CPU time is spent on (non-)nice
tasks, the distribution of the CPU usage across cgroups is not readily
available to the user.
This patch introduces cgroup-level niced CPU utilization to cpu.stat.
Exposing this metric will allow users to accurately probe the niced CPU
metric for each workload, and make more informed decisions when
directing higher priority tasks. For instance, service routers will be
able to probe cgroups in the host to determine CPU time spent on niced
processes in each cgroup, and direct more traffic to cgroups with lower
non-nice CPU utilization.
Signed-off-by Joshua Hahn <joshua.hahnjy@gmail.com>
Joshua Hahn (2):
Tracking cgroup-level niced CPU time
Selftests for niced CPU statistics
include/linux/cgroup-defs.h | 1 +
kernel/cgroup/rstat.c | 19 ++++--
tools/testing/selftests/cgroup/test_cpu.c | 75 +++++++++++++++++++++++
3 files changed, 90 insertions(+), 5 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v4 1/2] cgroup/rstat: Tracking cgroup-level niced CPU time
2024-10-02 18:47 [PATCH v4 0/2] Exposing nice CPU usage to userspace Joshua Hahn
@ 2024-10-02 18:47 ` Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 2/2] cgroup/rstat: Selftests for niced CPU statistics Joshua Hahn
2024-10-08 18:51 ` [PATCH v4 0/2] Exposing nice CPU usage to userspace Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: Joshua Hahn @ 2024-10-02 18:47 UTC (permalink / raw)
To: tj, mkoutny
Cc: cgroups, hannes, linux-kernel, linux-kselftest, lizefan.x, shuah
From: Joshua Hahn <joshua.hahn6@gmail.com>
Cgroup-level CPU statistics currently include time spent on
user/system processes, but do not include niced CPU time (despite
already being tracked). This patch exposes niced CPU time to the
userspace, allowing users to get a better understanding of their
hardware limits and can facilitate more informed workload distribution.
A new field 'ntime' is added to struct cgroup_base_stat as opposed to
struct task_cputime to minimize footprint.
Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
---
include/linux/cgroup-defs.h | 1 +
kernel/cgroup/rstat.c | 19 ++++++++++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index ae04035b6cbe..a2fcb3db6c52 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -315,6 +315,7 @@ struct cgroup_base_stat {
#ifdef CONFIG_SCHED_CORE
u64 forceidle_sum;
#endif
+ u64 ntime;
};
/*
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
index a06b45272411..5877974ece92 100644
--- a/kernel/cgroup/rstat.c
+++ b/kernel/cgroup/rstat.c
@@ -444,6 +444,7 @@ static void cgroup_base_stat_add(struct cgroup_base_stat *dst_bstat,
#ifdef CONFIG_SCHED_CORE
dst_bstat->forceidle_sum += src_bstat->forceidle_sum;
#endif
+ dst_bstat->ntime += src_bstat->ntime;
}
static void cgroup_base_stat_sub(struct cgroup_base_stat *dst_bstat,
@@ -455,6 +456,7 @@ static void cgroup_base_stat_sub(struct cgroup_base_stat *dst_bstat,
#ifdef CONFIG_SCHED_CORE
dst_bstat->forceidle_sum -= src_bstat->forceidle_sum;
#endif
+ dst_bstat->ntime -= src_bstat->ntime;
}
static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu)
@@ -534,8 +536,10 @@ void __cgroup_account_cputime_field(struct cgroup *cgrp,
rstatc = cgroup_base_stat_cputime_account_begin(cgrp, &flags);
switch (index) {
- case CPUTIME_USER:
case CPUTIME_NICE:
+ rstatc->bstat.ntime += delta_exec;
+ fallthrough;
+ case CPUTIME_USER:
rstatc->bstat.cputime.utime += delta_exec;
break;
case CPUTIME_SYSTEM:
@@ -591,6 +595,7 @@ static void root_cgroup_cputime(struct cgroup_base_stat *bstat)
#ifdef CONFIG_SCHED_CORE
bstat->forceidle_sum += cpustat[CPUTIME_FORCEIDLE];
#endif
+ bstat->ntime += cpustat[CPUTIME_NICE];
}
}
@@ -608,13 +613,14 @@ static void cgroup_force_idle_show(struct seq_file *seq, struct cgroup_base_stat
void cgroup_base_stat_cputime_show(struct seq_file *seq)
{
struct cgroup *cgrp = seq_css(seq)->cgroup;
- u64 usage, utime, stime;
+ u64 usage, utime, stime, ntime;
if (cgroup_parent(cgrp)) {
cgroup_rstat_flush_hold(cgrp);
usage = cgrp->bstat.cputime.sum_exec_runtime;
cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
&utime, &stime);
+ ntime = cgrp->bstat.ntime;
cgroup_rstat_flush_release(cgrp);
} else {
/* cgrp->bstat of root is not actually used, reuse it */
@@ -622,16 +628,19 @@ void cgroup_base_stat_cputime_show(struct seq_file *seq)
usage = cgrp->bstat.cputime.sum_exec_runtime;
utime = cgrp->bstat.cputime.utime;
stime = cgrp->bstat.cputime.stime;
+ ntime = cgrp->bstat.ntime;
}
do_div(usage, NSEC_PER_USEC);
do_div(utime, NSEC_PER_USEC);
do_div(stime, NSEC_PER_USEC);
+ do_div(ntime, NSEC_PER_USEC);
seq_printf(seq, "usage_usec %llu\n"
- "user_usec %llu\n"
- "system_usec %llu\n",
- usage, utime, stime);
+ "user_usec %llu\n"
+ "system_usec %llu\n"
+ "nice_usec %llu\n",
+ usage, utime, stime, ntime);
cgroup_force_idle_show(seq, &cgrp->bstat);
}
--
2.43.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 2/2] cgroup/rstat: Selftests for niced CPU statistics
2024-10-02 18:47 [PATCH v4 0/2] Exposing nice CPU usage to userspace Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 1/2] cgroup/rstat: Tracking cgroup-level niced CPU time Joshua Hahn
@ 2024-10-02 18:47 ` Joshua Hahn
2024-10-08 18:51 ` [PATCH v4 0/2] Exposing nice CPU usage to userspace Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: Joshua Hahn @ 2024-10-02 18:47 UTC (permalink / raw)
To: tj, mkoutny
Cc: cgroups, hannes, linux-kernel, linux-kselftest, lizefan.x, shuah
From: Joshua Hahn <joshua.hahn6@gmail.com>
Creates a cgroup with a single nice CPU hog process running.
fork() is called to generate the nice process because un-nicing is
not possible (see man nice(3)). If fork() was not used to generate
the CPU hog, we would run the rest of the cgroup selftest suite as a
nice process.
Signed-off-by: Joshua Hahn <joshua.hahnjy@gmail.com>
---
tools/testing/selftests/cgroup/test_cpu.c | 75 +++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/tools/testing/selftests/cgroup/test_cpu.c b/tools/testing/selftests/cgroup/test_cpu.c
index dad2ed82f3ef..201ce14cb422 100644
--- a/tools/testing/selftests/cgroup/test_cpu.c
+++ b/tools/testing/selftests/cgroup/test_cpu.c
@@ -8,6 +8,7 @@
#include <pthread.h>
#include <stdio.h>
#include <time.h>
+#include <unistd.h>
#include "../kselftest.h"
#include "cgroup_util.h"
@@ -229,6 +230,79 @@ static int test_cpucg_stats(const char *root)
return ret;
}
+/*
+ * Creates a nice process that consumes CPU and checks that the elapsed
+ * usertime in the cgroup is close to the expected time.
+ */
+static int test_cpucg_nice(const char *root)
+{
+ int ret = KSFT_FAIL;
+ int status;
+ long user_usec, nice_usec;
+ long usage_seconds = 2;
+ long expected_nice_usec = usage_seconds * USEC_PER_SEC;
+ char *cpucg;
+ pid_t pid;
+
+ cpucg = cg_name(root, "cpucg_test");
+ if (!cpucg)
+ goto cleanup;
+
+ if (cg_create(cpucg))
+ goto cleanup;
+
+ user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec");
+ nice_usec = cg_read_key_long(cpucg, "cpu.stat", "nice_usec");
+ if (nice_usec == -1)
+ ret = KSFT_SKIP;
+ if (user_usec != 0 || nice_usec != 0)
+ goto cleanup;
+
+ /*
+ * We fork here to create a new process that can be niced without
+ * polluting the nice value of other selftests
+ */
+ pid = fork();
+ if (pid < 0) {
+ goto cleanup;
+ } else if (pid == 0) {
+ struct cpu_hog_func_param param = {
+ .nprocs = 1,
+ .ts = {
+ .tv_sec = usage_seconds,
+ .tv_nsec = 0,
+ },
+ .clock_type = CPU_HOG_CLOCK_PROCESS,
+ };
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%d", getpid());
+ if (cg_write(cpucg, "cgroup.procs", buf))
+ goto cleanup;
+
+ /* Try to keep niced CPU usage as constrained to hog_cpu as possible */
+ nice(1);
+ hog_cpus_timed(cpucg, param);
+ exit(0);
+ } else {
+ waitpid(pid, &status, 0);
+ if (!WIFEXITED(status))
+ goto cleanup;
+
+ user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec");
+ nice_usec = cg_read_key_long(cpucg, "cpu.stat", "nice_usec");
+ if (!values_close(nice_usec, expected_nice_usec, 1))
+ goto cleanup;
+
+ ret = KSFT_PASS;
+ }
+
+cleanup:
+ cg_destroy(cpucg);
+ free(cpucg);
+
+ return ret;
+}
+
static int
run_cpucg_weight_test(
const char *root,
@@ -686,6 +760,7 @@ struct cpucg_test {
} tests[] = {
T(test_cpucg_subtree_control),
T(test_cpucg_stats),
+ T(test_cpucg_nice),
T(test_cpucg_weight_overprovisioned),
T(test_cpucg_weight_underprovisioned),
T(test_cpucg_nested_weight_overprovisioned),
--
2.43.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4 0/2] Exposing nice CPU usage to userspace
2024-10-02 18:47 [PATCH v4 0/2] Exposing nice CPU usage to userspace Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 1/2] cgroup/rstat: Tracking cgroup-level niced CPU time Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 2/2] cgroup/rstat: Selftests for niced CPU statistics Joshua Hahn
@ 2024-10-08 18:51 ` Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: Tejun Heo @ 2024-10-08 18:51 UTC (permalink / raw)
To: Joshua Hahn
Cc: mkoutny, cgroups, hannes, linux-kernel, linux-kselftest,
lizefan.x, shuah
On Wed, Oct 02, 2024 at 11:47:15AM -0700, Joshua Hahn wrote:
> Changes in v4
> - Removed unnecessary forking from selftest.
> - Style changes in rstat.c (fallthrough & indents)
> - Fixed a selftest bug that raised false negatives, caused by
> cputime_adjust sometimes adjusting utime below ntime.
> - Reworded cover letter for clarity & motivation
> Changes in v3
> - Signed-off-by & renamed subject for clarity.
> Changes in v2
> - Edited commit messages for clarity.
Applied to cgroup/for-6.13. If there are issues, let's iterate in tree.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-10-08 18:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-02 18:47 [PATCH v4 0/2] Exposing nice CPU usage to userspace Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 1/2] cgroup/rstat: Tracking cgroup-level niced CPU time Joshua Hahn
2024-10-02 18:47 ` [PATCH v4 2/2] cgroup/rstat: Selftests for niced CPU statistics Joshua Hahn
2024-10-08 18:51 ` [PATCH v4 0/2] Exposing nice CPU usage to userspace Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox