summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-11-13 16:40:27 +0000
committerMark Brown <broonie@kernel.org>2026-11-13 16:40:27 +0000
commit454bafaa24b135ac6800a997d10a7627ea823ca1 (patch)
tree054c03f04f07af3eadca055f9cc0a3bdc93aeae1
parentf9117be53eaa3ccf6efe9d9e694bd341c1ee1fc0 (diff)
parent8be14e18e0f3a4b144efe8e1013b739be19dff78 (diff)
downloadlinux-next-454bafaa24b135ac6800a997d10a7627ea823ca1.tar.gz
linux-next-454bafaa24b135ac6800a997d10a7627ea823ca1.zip
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git
-rw-r--r--kernel/cgroup/cgroup.c22
-rw-r--r--kernel/cgroup/cpuset.c118
-rw-r--r--kernel/cgroup/legacy_freezer.c40
-rw-r--r--tools/testing/selftests/cgroup/lib/cgroup_util.c36
-rw-r--r--tools/testing/selftests/cgroup/lib/include/cgroup_util.h32
-rw-r--r--tools/testing/selftests/cgroup/test_core.c36
-rw-r--r--tools/testing/selftests/cgroup/test_cpu.c48
-rwxr-xr-xtools/testing/selftests/cgroup/test_cpuset_prs.sh41
-rw-r--r--tools/testing/selftests/cgroup/test_freezer.c88
-rw-r--r--tools/testing/selftests/cgroup/test_hugetlb_memcg.c26
-rw-r--r--tools/testing/selftests/cgroup/test_kmem.c62
-rw-r--r--tools/testing/selftests/cgroup/test_memcontrol.c183
-rw-r--r--tools/testing/selftests/cgroup/test_pids.c6
-rw-r--r--tools/testing/selftests/cgroup/test_zswap.c81
14 files changed, 498 insertions, 321 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index a284225f8dc9..b3657e72db99 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -4806,19 +4806,21 @@ void cgroup_file_notify(struct cgroup_file *cfile)
if (!READ_ONCE(cfile->kn))
return;
- last = READ_ONCE(cfile->notified_at);
- next = last + CGROUP_FILE_NOTIFY_MIN_INTV;
- if (time_in_range(jiffies, last, next)) {
- timer_reduce(&cfile->notify_timer, next);
- if (timer_pending(&cfile->notify_timer))
- return;
- }
+ if (timer_pending(&cfile->notify_timer))
+ return;
spin_lock_irqsave(&cfile->lock, flags);
if (cfile->kn) {
- kn = cfile->kn;
- kernfs_get(kn);
- WRITE_ONCE(cfile->notified_at, jiffies);
+ last = cfile->notified_at;
+ next = last + CGROUP_FILE_NOTIFY_MIN_INTV;
+
+ if (time_in_range(jiffies, last, next)) {
+ timer_reduce(&cfile->notify_timer, next);
+ } else {
+ kn = cfile->kn;
+ kernfs_get(kn);
+ cfile->notified_at = jiffies;
+ }
}
spin_unlock_irqrestore(&cfile->lock, flags);
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 3219f927c35e..8a8a424a389f 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1315,10 +1315,13 @@ static void partition_xcpus_add(int new_prs, struct cpuset *parent,
{
WARN_ON_ONCE(new_prs < 0);
lockdep_assert_held(&callback_lock);
+
+ if (cpumask_empty(xcpus))
+ return;
+
if (!parent)
parent = &top_cpuset;
-
if (parent == &top_cpuset)
cpumask_or(subpartitions_cpus, subpartitions_cpus, xcpus);
@@ -1342,6 +1345,10 @@ static void partition_xcpus_del(int old_prs, struct cpuset *parent,
{
WARN_ON_ONCE(old_prs < 0);
lockdep_assert_held(&callback_lock);
+
+ if (cpumask_empty(xcpus))
+ return;
+
if (!parent)
parent = &top_cpuset;
@@ -2016,9 +2023,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
goto write_error;
}
- /* Check newmask whether cpus are available for parent/cs */
- nocpu = tasks_nocpu_error(parent, cs, newmask);
-
/*
* partcmd_update with newmask:
*
@@ -2033,6 +2037,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
* For invalid partition:
* delmask = newmask & parent->effective_xcpus
* The partition may become valid soon.
+ *
+ * Note that the no-cpu check is not repeated here:
+ * validate_partition() has already evaluated
+ * tasks_nocpu_error() with this very mask, and a failing
+ * write is routed to partcmd_invalidate instead.
*/
if (is_partition_invalid(cs)) {
adding = false;
@@ -2056,18 +2065,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
cpumask_and(tmp->new_cpus, tmp->delmask, cpu_active_mask);
WARN_ON_ONCE(!cpumask_subset(tmp->new_cpus, parent->effective_cpus));
}
-
- /*
- * Make partition invalid if parent's effective_cpus could
- * become empty and there are tasks in the parent.
- */
- if (nocpu && (!adding ||
- !cpumask_intersects(tmp->addmask, cpu_active_mask))) {
- part_error = PERR_NOCPUS;
- deleting = false;
- adding = cpumask_and(tmp->addmask,
- cs->effective_xcpus, parent->effective_xcpus);
- }
} else {
/*
* partcmd_update w/o newmask
@@ -2097,6 +2094,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
parent->effective_xcpus);
if (!cpumask_empty(tmp->addmask))
isolated_cpus_release(cs, tmp->addmask);
+ /* Expansion of parent's effective_xcpus is handled below */
}
if (nocpu) {
part_error = PERR_NOCPUS;
@@ -2106,11 +2104,34 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
parent->effective_xcpus);
} else if ((parent_prs == PRS_ISOLATED) &&
((old_prs == PRS_ROOT) || (old_prs == -PRS_ROOT))) {
+ /* Parent partition state changed to PRS_ISOLATED */
part_error = PERR_ISOPARENT;
if (old_prs == PRS_ROOT) {
cpumask_copy(tmp->addmask, cs->effective_xcpus);
adding = true;
}
+ } else if (is_partition_valid(cs) &&
+ !cpumask_equal(tmp->delmask, cs->effective_xcpus)) {
+ /*
+ * If there is an expansion of parent's effective_xcpus,
+ * we may take more xcpus from parent. The parent's
+ * effective_cpus should still have active CPUs or nocpu
+ * should have been set. We also need to do a
+ * housekeeping check for an isolated child with root
+ * parent to make sure that it won't exhaust all the
+ * active housekeeping CPUs.
+ */
+ cpumask_andnot(tmp->addmask, cs->effective_xcpus, tmp->delmask);
+ if ((parent_prs == PRS_ROOT) && (old_prs == PRS_ISOLATED) &&
+ prstate_housekeeping_conflict(old_prs, parent_prs,
+ tmp->delmask, tmp->addmask)) {
+ adding = cpumask_and(tmp->addmask, cs->effective_xcpus,
+ tmp->delmask);
+ part_error = PERR_HKEEPING;
+ } else {
+ deleting = cpumask_andnot(tmp->delmask, tmp->delmask,
+ cs->effective_xcpus);
+ }
} else if (is_partition_invalid(cs)) {
struct cgroup_subsys_state *css;
struct cpuset *child;
@@ -2143,12 +2164,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
else
part_error = PERR_NOTEXCL;
}
- /*
- * When both cs and parent remain valid, parent's
- * compute_partition_effective_cpumask() call would have removed
- * cs's effective_xcpus from the parent's effective_cpus. So
- * there is no need to adjust parent's effective_cpus here.
- */
}
write_error:
@@ -2347,12 +2362,12 @@ get_css:
update_parent_effective_cpumask(cp, partcmd_update, NULL, tmp);
/*
* Capture current partition_root_state as it may have
- * changed. Recompute effective cpumask if changed.
+ * changed. Always recompute effective cpumask as tmp->new_cpus
+ * may be clobbered when update_sibling_cpumasks() is called
+ * within update_parent_effective_cpumask().
*/
new_prs = cp->partition_root_state;
- if (new_prs != old_prs) {
- compute_effective_cpumask(tmp->new_cpus, cp, parent);
- }
+ compute_effective_cpumask(tmp->new_cpus, cp, parent);
}
spin_lock_irq(&callback_lock);
@@ -2593,8 +2608,11 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
spin_lock_irq(&callback_lock);
cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed);
cpumask_copy(cs->effective_xcpus, trialcs->effective_xcpus);
- if ((old_prs > 0) && !is_partition_valid(cs))
+ if (old_prs && !is_partition_valid(cs)) {
reset_partition_data(cs);
+ /* effective_xcpus may be cleared, update the subtree too */
+ force = true;
+ }
spin_unlock_irq(&callback_lock);
/* effective_cpus/effective_xcpus will be updated here */
@@ -2658,8 +2676,11 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
spin_lock_irq(&callback_lock);
cpumask_copy(cs->exclusive_cpus, trialcs->exclusive_cpus);
cpumask_copy(cs->effective_xcpus, trialcs->effective_xcpus);
- if ((old_prs > 0) && !is_partition_valid(cs))
+ if (old_prs && !is_partition_valid(cs)) {
reset_partition_data(cs);
+ /* effective_xcpus may be cleared, update the subtree too */
+ force = true;
+ }
spin_unlock_irq(&callback_lock);
/*
@@ -3042,12 +3063,32 @@ static int update_prstate(struct cpuset *cs, int new_prs)
cs->effective_xcpus, NULL))
err = PERR_HKEEPING;
else if (parent_prs == PRS_ISOLATED)
- err = PERR_ISOPARENT;
+ err = PERR_ISOPARENT; /* old_prs should be isolated */
- if (!err)
- isolcpus_updated = true;
- else
+ if (err) {
disable_partition = true;
+ } else {
+ struct cgroup_subsys_state *css;
+ struct cpuset *child;
+
+ /*
+ * Need to scan child partitions, if present, and
+ * exclude their effective_xcpus from cs. In the case
+ * of switching to isolated partition with child root
+ * partitions, those child partitions will be
+ * invalidated in update_cpumasks_hier().
+ */
+ isolcpus_updated = true;
+ cpumask_copy(tmpmask.new_cpus, cs->effective_xcpus);
+ rcu_read_lock();
+ cpuset_for_each_child(child, css, cs) {
+ if (!is_partition_valid(child))
+ continue;
+ cpumask_andnot(tmpmask.new_cpus, tmpmask.new_cpus,
+ child->effective_xcpus);
+ }
+ rcu_read_unlock();
+ }
} else {
/*
* Switching back to member is always allowed even if it
@@ -3081,7 +3122,7 @@ out:
if (!is_partition_valid(cs))
reset_partition_data(cs);
else if (isolcpus_updated)
- isolated_cpus_update(old_prs, new_prs, cs->effective_xcpus);
+ isolated_cpus_update(old_prs, new_prs, tmpmask.new_cpus);
spin_unlock_irq(&callback_lock);
/* Force update if partition is disabled & update effective_xcpus */
@@ -3856,11 +3897,20 @@ static void cpuset_fork(struct task_struct *task)
rcu_read_unlock();
if (cs == oldcs) {
+ unsigned int seq;
+
if (cs == &top_cpuset)
return;
set_cpus_allowed_ptr(task, current->cpus_ptr);
- task->mems_allowed = current->mems_allowed;
+ /*
+ * A cpuset.mems update can update current->mems_allowed
+ * concurrently, so retry it again if it really happens.
+ */
+ do {
+ seq = read_mems_allowed_begin();
+ task->mems_allowed = current->mems_allowed;
+ } while (read_mems_allowed_retry(seq));
return;
}
diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c
index 8545e0d1ba3d..1792523d119a 100644
--- a/kernel/cgroup/legacy_freezer.c
+++ b/kernel/cgroup/legacy_freezer.c
@@ -265,7 +265,7 @@ static void update_if_frozen(struct cgroup_subsys_state *css)
rcu_read_unlock();
/* are all tasks frozen? */
- css_task_iter_start(css, 0, &it);
+ css_task_iter_start(css, CSS_TASK_ITER_WITH_DEAD, &it);
while ((task = css_task_iter_next(&it))) {
if (freezing(task) && !frozen(task))
@@ -309,7 +309,7 @@ static void freeze_cgroup(struct freezer *freezer)
struct css_task_iter it;
struct task_struct *task;
- css_task_iter_start(&freezer->css, 0, &it);
+ css_task_iter_start(&freezer->css, CSS_TASK_ITER_WITH_DEAD, &it);
while ((task = css_task_iter_next(&it)))
freeze_task(task);
css_task_iter_end(&it);
@@ -320,7 +320,7 @@ static void unfreeze_cgroup(struct freezer *freezer)
struct css_task_iter it;
struct task_struct *task;
- css_task_iter_start(&freezer->css, 0, &it);
+ css_task_iter_start(&freezer->css, CSS_TASK_ITER_WITH_DEAD, &it);
while ((task = css_task_iter_next(&it)))
__thaw_task(task);
css_task_iter_end(&it);
@@ -382,6 +382,24 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
* CGROUP_FREEZING_PARENT.
*/
mutex_lock(&freezer_mutex);
+
+ /*
+ * A dead cgroup must not be frozen.
+ *
+ * rmdir thaws the cgroup from freezer_css_killed(), but freezer.state
+ * stays writable until rmdir removes it a moment later. A FROZEN write
+ * in that gap would freeze the cgroup again, and nothing could thaw it
+ * after that.
+ *
+ * A freezer.state write doesn't take cgroup_mutex, but testing
+ * cgroup_is_dead() without it is safe. rmdir marks the cgroup dead
+ * before the thaw, so a write that takes freezer_mutex after the thaw
+ * sees it dead. One that takes it before the thaw may still see the
+ * cgroup alive, but the thaw then undoes its freeze.
+ */
+ if (freeze && data_race(cgroup_is_dead(freezer->css.cgroup)))
+ goto out_unlock;
+
rcu_read_lock();
css_for_each_descendant_pre(pos, &freezer->css) {
struct freezer *pos_f = css_freezer(pos);
@@ -403,10 +421,25 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
css_put(pos);
}
rcu_read_unlock();
+out_unlock:
mutex_unlock(&freezer_mutex);
cpus_read_unlock();
}
+/**
+ * freezer_css_killed - Thaw a freezer cgroup being removed
+ * @css: css being killed
+ *
+ * Exiting tasks hidden from cgroup.procs can still be in the cgroup when it is
+ * removed, and a frozen one has nothing left to thaw it once freezer.state is
+ * gone. Thaw the cgroup as a THAWED write to it would. A frozen ancestor keeps
+ * the tasks frozen through CGROUP_FREEZING_PARENT until the ancestor is thawed.
+ */
+static void freezer_css_killed(struct cgroup_subsys_state *css)
+{
+ freezer_change_state(css_freezer(css), false);
+}
+
static ssize_t freezer_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{
@@ -466,6 +499,7 @@ static struct cftype files[] = {
struct cgroup_subsys freezer_cgrp_subsys = {
.css_alloc = freezer_css_alloc,
.css_online = freezer_css_online,
+ .css_killed = freezer_css_killed,
.css_offline = freezer_css_offline,
.css_free = freezer_css_free,
.attach = freezer_attach,
diff --git a/tools/testing/selftests/cgroup/lib/cgroup_util.c b/tools/testing/selftests/cgroup/lib/cgroup_util.c
index 823b0312b2b2..273acfd5710b 100644
--- a/tools/testing/selftests/cgroup/lib/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/lib/cgroup_util.c
@@ -175,27 +175,27 @@ int cg_read_strstr(const char *cgroup, const char *control, const char *needle)
return strstr(buf, needle) ? 0 : -1;
}
-long cg_read_long(const char *cgroup, const char *control)
+s64 cg_read_s64(const char *cgroup, const char *control)
{
char buf[128];
if (cg_read(cgroup, control, buf, sizeof(buf)))
return -1;
- return atol(buf);
+ return atoll(buf);
}
-long cg_read_long_fd(int fd)
+s64 cg_read_s64_fd(int fd)
{
char buf[128];
if (pread(fd, buf, sizeof(buf), 0) <= 0)
return -1;
- return atol(buf);
+ return atoll(buf);
}
-long cg_read_key_long(const char *cgroup, const char *control, const char *key)
+s64 cg_read_key_s64(const char *cgroup, const char *control, const char *key)
{
char buf[BUF_SIZE];
char *ptr;
@@ -207,18 +207,18 @@ long cg_read_key_long(const char *cgroup, const char *control, const char *key)
if (!ptr)
return -1;
- return atol(ptr + strlen(key));
+ return atoll(ptr + strlen(key));
}
-long cg_read_key_long_poll(const char *cgroup, const char *control,
- const char *key, long expected, int retries,
- useconds_t wait_interval_us)
+s64 cg_read_key_s64_poll(const char *cgroup, const char *control,
+ const char *key, s64 expected, int retries,
+ useconds_t wait_interval_us)
{
- long val = -1;
+ s64 val = -1;
int i;
for (i = 0; i < retries; i++) {
- val = cg_read_key_long(cgroup, control, key);
+ val = cg_read_key_s64(cgroup, control, key);
if (val < 0)
return val;
@@ -270,12 +270,12 @@ int cg_open(const char *cgroup, const char *control, int flags)
return open(path, flags);
}
-int cg_write_numeric(const char *cgroup, const char *control, long value)
+int cg_write_numeric(const char *cgroup, const char *control, s64 value)
{
char buf[64];
int ret;
- ret = sprintf(buf, "%lu", value);
+ ret = sprintf(buf, "%" PRId64, value);
if (ret < 0)
return ret;
@@ -508,17 +508,17 @@ again:
}
if (options & WEXITED) {
- if (WIFEXITED(info.si_status))
- return WEXITSTATUS(info.si_status);
+ if (info.si_code == CLD_EXITED)
+ return info.si_status;
}
if (options & WSTOPPED) {
- if (WIFSTOPPED(info.si_status))
- return WSTOPSIG(info.si_status);
+ if (info.si_code == CLD_STOPPED || info.si_code == CLD_TRAPPED)
+ return info.si_status;
}
if (options & WCONTINUED) {
- if (WIFCONTINUED(info.si_status))
+ if (info.si_code == CLD_CONTINUED)
return 0;
}
diff --git a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
index 5307f3bf32a0..bc0dd25f24ee 100644
--- a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
+++ b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
@@ -1,7 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
+typedef int64_t s64;
+
#ifndef BUF_SIZE
#define BUF_SIZE 4096
#endif
@@ -27,26 +30,27 @@
/*
* Checks if two given values differ by less than err% of their sum.
*/
-static inline int values_close(long a, long b, int err)
+static inline int values_close(s64 a, s64 b, int err)
{
- return labs(a - b) <= (a + b) / 100 * err;
+ return llabs(a - b) <= (a + b) / 100 * err;
}
/*
* Checks if two given values differ by less than err% of their sum and assert
* with detailed debug info if not.
*/
-static inline int values_close_report(long a, long b, int err)
+static inline int values_close_report(s64 a, s64 b, int err)
{
- long diff = labs(a - b);
- long limit = (a + b) / 100 * err;
+ s64 diff = llabs(a - b);
+ s64 limit = (a + b) / 100 * err;
double actual_err = (a + b) ? (100.0 * diff / (a + b)) : 0.0;
int close = diff <= limit;
if (!close)
fprintf(stderr,
- "[FAIL] actual=%ld expected=%ld | diff=%ld | limit=%ld | "
- "tolerance=%d%% | actual_error=%.2f%%\n",
+ "[FAIL] actual=%" PRId64 " expected=%" PRId64
+ " | diff=%" PRId64 " | limit=%" PRId64
+ " | tolerance=%d%% | actual_error=%.2f%%\n",
a, b, diff, limit, err, actual_err);
return close;
@@ -70,16 +74,16 @@ extern int cg_read_strcmp_wait(const char *cgroup, const char *control,
const char *expected);
extern int cg_read_strstr(const char *cgroup, const char *control,
const char *needle);
-extern long cg_read_long(const char *cgroup, const char *control);
-extern long cg_read_long_fd(int fd);
-long cg_read_key_long(const char *cgroup, const char *control, const char *key);
-long cg_read_key_long_poll(const char *cgroup, const char *control,
- const char *key, long expected, int retries,
- useconds_t wait_interval_us);
+s64 cg_read_s64(const char *cgroup, const char *control);
+s64 cg_read_s64_fd(int fd);
+s64 cg_read_key_s64(const char *cgroup, const char *control, const char *key);
+s64 cg_read_key_s64_poll(const char *cgroup, const char *control,
+ const char *key, s64 expected, int retries,
+ useconds_t wait_interval_us);
extern long cg_read_lc(const char *cgroup, const char *control);
extern int cg_write(const char *cgroup, const char *control, char *buf);
extern int cg_open(const char *cgroup, const char *control, int flags);
-int cg_write_numeric(const char *cgroup, const char *control, long value);
+int cg_write_numeric(const char *cgroup, const char *control, s64 value);
extern int cg_run(const char *cgroup,
int (*fn)(const char *cgroup, void *arg),
void *arg);
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c
index 20d2b63774c3..53592bf309fa 100644
--- a/tools/testing/selftests/cgroup/test_core.c
+++ b/tools/testing/selftests/cgroup/test_core.c
@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <dirent.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
@@ -568,6 +569,39 @@ static void *dummy_thread_fn(void *arg)
}
/*
+ * Count the threads of the current process, or return -1 if any of them
+ * is not in @cgroup. Unlike reading cgroup.threads, this is not affected
+ * by other migrations happening at the same time.
+ */
+static int count_threads_in_cgroup(const char *root, const char *cgroup)
+{
+ char line[PATH_MAX];
+ struct dirent *de;
+ int cnt = 0;
+ DIR *dir;
+
+ snprintf(line, sizeof(line), CG_PATH_FORMAT, cgroup + strlen(root));
+
+ dir = opendir("/proc/self/task");
+ if (!dir)
+ return -1;
+
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.')
+ continue;
+
+ if (proc_read_strstr(atoi(de->d_name), false, "cgroup", line)) {
+ cnt = -1;
+ break;
+ }
+ cnt++;
+ }
+
+ closedir(dir);
+ return cnt;
+}
+
+/*
* Test threadgroup migration.
* All threads of a process are migrated together.
*/
@@ -597,7 +631,7 @@ static int test_cgcore_proc_migration(const char *root)
}
cg_enter_current(dst);
- if (cg_read_lc(dst, CG_THREADS_FILE) != n_threads + 1)
+ if (count_threads_in_cgroup(root, dst) != n_threads + 1)
goto cleanup;
ret = KSFT_PASS;
diff --git a/tools/testing/selftests/cgroup/test_cpu.c b/tools/testing/selftests/cgroup/test_cpu.c
index 3456e3e988c6..1db8ff3f0e5c 100644
--- a/tools/testing/selftests/cgroup/test_cpu.c
+++ b/tools/testing/selftests/cgroup/test_cpu.c
@@ -24,7 +24,7 @@ enum hog_clock_type {
struct cpu_hogger {
char *cgroup;
pid_t pid;
- long usage;
+ s64 usage;
};
struct cpu_hog_func_param {
@@ -185,7 +185,7 @@ static int hog_cpus_timed(const char *cgroup, void *arg)
static int test_cpucg_stats(const char *root)
{
int ret = KSFT_FAIL;
- long usage_usec, user_usec, system_usec;
+ s64 usage_usec, user_usec, system_usec;
long usage_seconds = 2;
long expected_usage_usec = usage_seconds * USEC_PER_SEC;
char *cpucg;
@@ -197,9 +197,9 @@ static int test_cpucg_stats(const char *root)
if (cg_create(cpucg))
goto cleanup;
- usage_usec = cg_read_key_long(cpucg, "cpu.stat", "usage_usec");
- user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec");
- system_usec = cg_read_key_long(cpucg, "cpu.stat", "system_usec");
+ usage_usec = cg_read_key_s64(cpucg, "cpu.stat", "usage_usec");
+ user_usec = cg_read_key_s64(cpucg, "cpu.stat", "user_usec");
+ system_usec = cg_read_key_s64(cpucg, "cpu.stat", "system_usec");
if (usage_usec != 0 || user_usec != 0 || system_usec != 0)
goto cleanup;
@@ -214,8 +214,8 @@ static int test_cpucg_stats(const char *root)
if (cg_run(cpucg, hog_cpus_timed, (void *)&param))
goto cleanup;
- usage_usec = cg_read_key_long(cpucg, "cpu.stat", "usage_usec");
- user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec");
+ usage_usec = cg_read_key_s64(cpucg, "cpu.stat", "usage_usec");
+ user_usec = cg_read_key_s64(cpucg, "cpu.stat", "user_usec");
if (user_usec <= 0)
goto cleanup;
@@ -239,7 +239,7 @@ static int test_cpucg_nice(const char *root)
{
int ret = KSFT_FAIL;
int status;
- long user_usec, nice_usec;
+ s64 user_usec, nice_usec;
long usage_seconds = 2;
long expected_nice_usec = usage_seconds * USEC_PER_SEC;
char *cpucg;
@@ -252,8 +252,8 @@ static int test_cpucg_nice(const char *root)
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");
+ user_usec = cg_read_key_s64(cpucg, "cpu.stat", "user_usec");
+ nice_usec = cg_read_key_s64(cpucg, "cpu.stat", "nice_usec");
if (nice_usec == -1)
ret = KSFT_SKIP;
if (user_usec != 0 || nice_usec != 0)
@@ -289,8 +289,8 @@ static int test_cpucg_nice(const char *root)
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");
+ user_usec = cg_read_key_s64(cpucg, "cpu.stat", "user_usec");
+ nice_usec = cg_read_key_s64(cpucg, "cpu.stat", "nice_usec");
if (user_usec <= 0)
goto cleanup;
if (!values_close_report(nice_usec, expected_nice_usec, 1))
@@ -357,8 +357,8 @@ run_cpucg_weight_test(
}
for (i = 0; i < ARRAY_SIZE(children); i++)
- children[i].usage = cg_read_key_long(children[i].cgroup,
- "cpu.stat", "usage_usec");
+ children[i].usage = cg_read_key_s64(children[i].cgroup,
+ "cpu.stat", "usage_usec");
if (validate(children, ARRAY_SIZE(children)))
goto cleanup;
@@ -400,7 +400,7 @@ overprovision_validate(const struct cpu_hogger *children, int num_children)
int ret = KSFT_FAIL, i;
for (i = 0; i < num_children - 1; i++) {
- long delta;
+ s64 delta;
if (children[i + 1].usage <= children[i].usage)
goto cleanup;
@@ -486,7 +486,7 @@ run_cpucg_nested_weight_test(const char *root, bool overprovisioned)
int ret = KSFT_FAIL, i;
char *parent = NULL, *child = NULL;
struct cpu_hogger leaf[3] = {};
- long nested_leaf_usage, child_usage;
+ s64 nested_leaf_usage, child_usage;
int nprocs = get_nprocs();
if (!overprovisioned) {
@@ -567,8 +567,8 @@ run_cpucg_nested_weight_test(const char *root, bool overprovisioned)
}
for (i = 0; i < ARRAY_SIZE(leaf); i++) {
- leaf[i].usage = cg_read_key_long(leaf[i].cgroup,
- "cpu.stat", "usage_usec");
+ leaf[i].usage = cg_read_key_s64(leaf[i].cgroup, "cpu.stat",
+ "usage_usec");
if (leaf[i].usage <= 0)
goto cleanup;
}
@@ -581,7 +581,7 @@ run_cpucg_nested_weight_test(const char *root, bool overprovisioned)
goto cleanup;
- child_usage = cg_read_key_long(child, "cpu.stat", "usage_usec");
+ child_usage = cg_read_key_s64(child, "cpu.stat", "usage_usec");
if (child_usage <= 0)
goto cleanup;
if (!values_close_report(child_usage, nested_leaf_usage, 1))
@@ -679,7 +679,8 @@ static int test_cpucg_max(const char *root)
long duration_seconds = 1;
long duration_usec;
- long usage_usec, n_periods, remainder_usec, expected_usage_usec;
+ long n_periods, remainder_usec, expected_usage_usec;
+ s64 usage_usec;
char *cpucg;
char quota_buf[32];
@@ -708,7 +709,7 @@ static int test_cpucg_max(const char *root)
if (cg_run(cpucg, hog_cpus_timed, (void *)&param))
goto cleanup;
- usage_usec = cg_read_key_long(cpucg, "cpu.stat", "usage_usec");
+ usage_usec = cg_read_key_s64(cpucg, "cpu.stat", "usage_usec");
if (usage_usec <= 0)
goto cleanup;
@@ -746,7 +747,8 @@ static int test_cpucg_max_nested(const char *root)
long duration_seconds = 1;
long duration_usec;
- long usage_usec, n_periods, remainder_usec, expected_usage_usec;
+ long n_periods, remainder_usec, expected_usage_usec;
+ s64 usage_usec;
char *parent, *child;
char quota_buf[32];
@@ -782,7 +784,7 @@ static int test_cpucg_max_nested(const char *root)
if (cg_run(child, hog_cpus_timed, (void *)&param))
goto cleanup;
- usage_usec = cg_read_key_long(child, "cpu.stat", "usage_usec");
+ usage_usec = cg_read_key_s64(child, "cpu.stat", "usage_usec");
if (usage_usec <= 0)
goto cleanup;
diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index 83ef6c781af3..1e9e6b4c6f7b 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -137,7 +137,8 @@ LAST_PRESENT_CPU=$(cat /sys/devices/system/cpu/present | sed -e "s/.*[,-]//")
# If isolated CPUs have been reserved at boot time (as shown in
# /sys/devices/system/cpu/isolated), these isolated CPUs should be outside of
# CPUs 0-8 that will be used by this script for testing purpose. If not, some
-# of the tests may fail incorrectly.
+# of the tests may fail incorrectly. The first boot isolated CPU should be
+# 10 or above.
#
# The current set of isolated CPUs (as shown in cpuset.cpus.isolated) should
# be the same as the boot value. If not, wait a bit and retry again just in
@@ -156,7 +157,7 @@ TEST_ISOLCPUS=
[[ -n "$BOOT_ISOLCPUS" ]] && {
FIRST_ISOLCPUS=$(echo $BOOT_ISOLCPUS | sed -e "s/[,-].*//")
echo "Boot isolated CPUs: $BOOT_ISOLCPUS"
- [[ $FIRST_ISOLCPUS -le 8 ]] &&
+ [[ $FIRST_ISOLCPUS -le 9 ]] &&
skip_test "Boot isolated CPUs overlap CPUs to be tested"
}
@@ -433,6 +434,12 @@ TEST_MATRIX=(
# cpuset.cpus is allowed, but those extra CPUs are ignored.
" C2-3:P1 C3:P1 . . . C2-4 . . 0 A1:|A2:2-3 A1:P1|A2:P1"
+ # Clearing cpuset.cpus.exclusive of an invalid partition releases its
+ # exclusive CPUs, including those of its descendants, so a sibling
+ # can claim them.
+ " CX2-3:P1 . . C3 T:O2=0:O3=0:X . . X3 0 XA1:|XB1:3 A1:P-1"
+ " CX2-3:P1 X3 . C3 T:O2=0:O3=0:X . . X3 0 XA1:|XA2:|XB1:3 A1:P-1"
+
# A child cannot recover until its exclusive CPUs are available again.
" CX1-4:P1 CX3-4:P1 . . X1-2 . . . 0 A1:1-2|A2:1-2|XA2: A1:P1|A2:P-1"
" CX1-4:P1 CX3-4:P1 . . X1-2:X1-4 . . . 0 A1:1-2|A2:3-4|XA2:3-4 A1:P1|A2:P1"
@@ -531,6 +538,31 @@ TEST_MATRIX=(
" C1-4:P1 C3-4:P2 . . T:C4-6 . . . 0 A1:5-6|A2:4 A1:P1|A2:P2 4"
" C1-4:P1 C1-2:P2 . . T:C4-6 . . . 0 A1:4-6|A2:4-6 A1:P1|A2:P-2 ."
+ # The extra CPUs gained by a child partition when its parent expands the
+ # exclusive CPUs have to be taken away from the parent.
+ " C2-6:X2-5:P1 CX4-6:P1 \
+ . . X2-6 . . . 0 A1:2-3|A2:4-6|XA2:4-6 \
+ A1:P1|A2:P1 ."
+ " C2-6:X2-5:P1 CX4-6:P2 \
+ . . X2-6 . . . 0 A1:2-3|A2:4-6|XA2:4-6 \
+ A1:P1|A2:P2 4-6"
+
+ # Both expansion and contraction of parent's effective_xcpus will be
+ # correctly handled in child partition and the child can be invalidated
+ # if a populated parent could lose all its effective_cpus.
+ " C2-6:X2-5:P1 CX3,5-6:P2 \
+ . . X4-6 . . . 0 A1:4|A2:5-6|XA2:5-6 \
+ A1:P1|A2:P2 4-6|5-6"
+ " C2-6:X2-5:P1 CX3-6:P2 \
+ . . T:X4-6 . . . 0 A1:4-6|A2:4-6 A1:P1|A2:P-2 ."
+
+ # Switch PRS state (root <=> isolated) will properly update cpuset.cpus.isolated
+ # even if child partitions are present.
+ " C1-6:P1 C3-6:P1 C5-6:P2 . . P2 . . 0 A1:1-2|A2:3-4|A3:5-6 \
+ A1:P1|A2:P2|A3:P2 3-6"
+ " C1-6:P1 C3-6:P2 C5-6:P2 . . P1 . . 0 A1:1-2|A2:3-4|A3:5-6 \
+ A1:P1|A2:P1|A3:P2 5-6"
+
#
# old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
# ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
@@ -587,6 +619,7 @@ ISOLCPUS_TEST_MATRIX=(
)
# Test matrix to be run when boot time nohz_full CPUs cover all CPUs except CPUs 0-7
+# This also means that CPU 8 is available and is a nohz_full CPU.
NOHZ_FULL_TEST_MATRIX=(
# old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
# ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
@@ -595,6 +628,10 @@ NOHZ_FULL_TEST_MATRIX=(
" C2-7:P2 . . . C0-4 . . . 0 A1:0-4 A1:P2 0-4"
" C1-7:P2 C5-7:P2 . . . . . C0:P2 0 A1:1-4|A2:5-7|B1:0
A1:P2|A2:P2|B1:P-2 1-7"
+ # An isolated child partition cannot grow to take over the last
+ # housekeeping CPU when its parent expands the exclusive CPUs.
+ " C0-8:X1-8:P1 CX0-8:P2 . . X0-7 . . . 0 A1:0-7|A2:0-7 A1:P1|A2:P-2 ."
+ " C0-8:X0-6:P1 CX0-8:P2 . . X2-8 . . . 0 A1:|A2:2-8 A1:P1|A2:P2 2-8"
)
#
diff --git a/tools/testing/selftests/cgroup/test_freezer.c b/tools/testing/selftests/cgroup/test_freezer.c
index f28bb02e9783..266b1a0f889f 100644
--- a/tools/testing/selftests/cgroup/test_freezer.c
+++ b/tools/testing/selftests/cgroup/test_freezer.c
@@ -807,10 +807,9 @@ cleanup:
/*
* Get the current frozen_usec for the cgroup.
*/
-static long cg_check_freezetime(const char *cgroup)
+static s64 cg_check_freezetime(const char *cgroup)
{
- return cg_read_key_long(cgroup, "cgroup.stat.local",
- "frozen_usec ");
+ return cg_read_key_s64(cgroup, "cgroup.stat.local", "frozen_usec ");
}
/*
@@ -820,7 +819,7 @@ static int test_cgfreezer_time_empty(const char *root)
{
int ret = KSFT_FAIL;
char *cgroup = NULL;
- long prev, curr;
+ s64 prev, curr;
cgroup = cg_name(root, "cg_time_test_empty");
if (!cgroup)
@@ -839,7 +838,7 @@ static int test_cgfreezer_time_empty(const char *root)
goto cleanup;
}
if (curr > 0) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -853,7 +852,7 @@ static int test_cgfreezer_time_empty(const char *root)
usleep(1000);
curr = cg_check_freezetime(cgroup);
if (curr < 1000) {
- debug("Expect time (%ld) to be at least 1000 us\n",
+ debug("Expect time (%" PRId64 ") to be at least 1000 us\n",
curr);
goto cleanup;
}
@@ -867,7 +866,7 @@ static int test_cgfreezer_time_empty(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -879,8 +878,8 @@ static int test_cgfreezer_time_empty(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr != prev) {
- debug("Expect time (%ld) to be unchanged from previous check (%ld)\n",
- curr, prev);
+ debug("Expect time (%" PRId64 ") to be unchanged from previous check (%"
+ PRId64 ")\n", curr, prev);
goto cleanup;
}
@@ -902,7 +901,7 @@ static int test_cgfreezer_time_simple(const char *root)
{
int ret = KSFT_FAIL;
char *cgroup = NULL;
- long prev, curr;
+ s64 prev, curr;
cgroup = cg_name(root, "cg_time_test_simple");
if (!cgroup)
@@ -920,7 +919,7 @@ static int test_cgfreezer_time_simple(const char *root)
goto cleanup;
}
if (curr > 0) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -932,7 +931,7 @@ static int test_cgfreezer_time_simple(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr > prev) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -947,7 +946,7 @@ static int test_cgfreezer_time_simple(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr < 1000) {
- debug("Expect time (%ld) to be at least 1000 us\n",
+ debug("Expect time (%" PRId64 ") to be at least 1000 us\n",
curr);
goto cleanup;
}
@@ -961,7 +960,7 @@ static int test_cgfreezer_time_simple(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -974,8 +973,8 @@ static int test_cgfreezer_time_simple(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr != prev) {
- debug("Expect time (%ld) to be unchanged from previous check (%ld)\n",
- curr, prev);
+ debug("Expect time (%" PRId64 ") to be unchanged from previous check (%"
+ PRId64 ")\n", curr, prev);
goto cleanup;
}
@@ -996,7 +995,7 @@ static int test_cgfreezer_time_populate(const char *root)
{
int ret = KSFT_FAIL;
char *cgroup = NULL;
- long prev, curr;
+ s64 prev, curr;
int i;
cgroup = cg_name(root, "cg_time_test_populate");
@@ -1012,7 +1011,7 @@ static int test_cgfreezer_time_populate(const char *root)
goto cleanup;
}
if (curr > 0) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -1025,7 +1024,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr != prev) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -1038,7 +1037,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr != prev) {
- debug("Expect time (%ld) to be 0\n", curr);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr);
goto cleanup;
}
@@ -1051,7 +1050,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -1061,7 +1060,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -1075,7 +1074,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -1089,7 +1088,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -1103,8 +1102,8 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr != prev) {
- debug("Expect time (%ld) to be unchanged from previous check (%ld)\n",
- curr, prev);
+ debug("Expect time (%" PRId64 ") to be unchanged from previous check (%"
+ PRId64 ")\n", curr, prev);
goto cleanup;
}
@@ -1119,7 +1118,7 @@ static int test_cgfreezer_time_populate(const char *root)
prev = curr;
curr = cg_check_freezetime(cgroup);
if (curr <= prev) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr, prev);
goto cleanup;
}
@@ -1140,7 +1139,7 @@ cleanup:
*/
static int test_cgfreezer_time_migrate(const char *root)
{
- long prev_A, curr_A, curr_B;
+ s64 prev_A, curr_A, curr_B;
char *cgroup[2] = {0};
int ret = KSFT_FAIL;
int pid;
@@ -1173,12 +1172,12 @@ static int test_cgfreezer_time_migrate(const char *root)
curr_A = cg_check_freezetime(cgroup[0]);
if (curr_A) {
- debug("Expect time (%ld) to be 0\n", curr_A);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr_A);
goto cleanup;
}
curr_B = cg_check_freezetime(cgroup[1]);
if (curr_B) {
- debug("Expect time (%ld) to be 0\n", curr_B);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr_B);
goto cleanup;
}
@@ -1190,7 +1189,7 @@ static int test_cgfreezer_time_migrate(const char *root)
prev_A = curr_A;
curr_A = cg_check_freezetime(cgroup[0]);
if (curr_A <= prev_A) {
- debug("Expect time (%ld) to be > 0\n", curr_A);
+ debug("Expect time (%" PRId64 ") to be > 0\n", curr_A);
goto cleanup;
}
@@ -1203,14 +1202,14 @@ static int test_cgfreezer_time_migrate(const char *root)
usleep(1000);
curr_B = cg_check_freezetime(cgroup[1]);
if (curr_B) {
- debug("Expect time (%ld) to be 0\n", curr_B);
+ debug("Expect time (%" PRId64 ") to be 0\n", curr_B);
goto cleanup;
}
prev_A = curr_A;
curr_A = cg_check_freezetime(cgroup[0]);
if (curr_A <= prev_A) {
- debug("Expect time (%ld) to be more than previous check (%ld)\n",
+ debug("Expect time (%" PRId64 ") to be more than previous check (%" PRId64 ")\n",
curr_A, prev_A);
goto cleanup;
}
@@ -1238,7 +1237,7 @@ static int test_cgfreezer_time_parent(const char *root)
{
char *parent, *child = NULL;
int ret = KSFT_FAIL;
- long ptime, ctime;
+ s64 ptime, ctime;
parent = cg_name(root, "cg_test_parent_A");
if (!parent)
@@ -1277,7 +1276,8 @@ static int test_cgfreezer_time_parent(const char *root)
ptime = cg_check_freezetime(parent);
ctime = cg_check_freezetime(child);
if (ptime <= ctime) {
- debug("Expect ptime (%ld) > ctime (%ld)\n", ptime, ctime);
+ debug("Expect ptime (%" PRId64 ") > ctime (%" PRId64 ")\n",
+ ptime, ctime);
goto cleanup;
}
@@ -1296,7 +1296,8 @@ static int test_cgfreezer_time_parent(const char *root)
ptime = cg_check_freezetime(parent);
if (ctime <= ptime) {
- debug("Expect ctime (%ld) > ptime (%ld)\n", ctime, ptime);
+ debug("Expect ctime (%" PRId64 ") > ptime (%" PRId64 ")\n",
+ ctime, ptime);
goto cleanup;
}
@@ -1321,7 +1322,7 @@ static int test_cgfreezer_time_child(const char *root)
{
char *parent, *child = NULL;
int ret = KSFT_FAIL;
- long ptime, ctime;
+ s64 ptime, ctime;
parent = cg_name(root, "cg_test_child_A");
if (!parent)
@@ -1348,12 +1349,13 @@ static int test_cgfreezer_time_child(const char *root)
ctime = cg_check_freezetime(child);
ptime = cg_check_freezetime(parent);
if (ptime != 0) {
- debug("Expect ptime (%ld) to be 0\n", ptime);
+ debug("Expect ptime (%" PRId64 ") to be 0\n", ptime);
goto cleanup;
}
if (ctime <= ptime) {
- debug("Expect ctime (%ld) > ptime (%ld)\n", ctime, ptime);
+ debug("Expect ctime (%" PRId64 ") > ptime (%" PRId64 ")\n",
+ ctime, ptime);
goto cleanup;
}
@@ -1386,7 +1388,7 @@ static int test_cgfreezer_time_nested(const char *root)
{
char *cgroup[3] = {0};
int ret = KSFT_FAIL;
- long time[3] = {0};
+ s64 time[3] = {0};
int i;
cgroup[0] = cg_name(root, "cg_test_time_A");
@@ -1440,12 +1442,14 @@ static int test_cgfreezer_time_nested(const char *root)
time[0] = cg_check_freezetime(cgroup[0]);
if (time[2] <= time[1]) {
- debug("Expect C's time (%ld) > B's time (%ld)", time[2], time[1]);
+ debug("Expect C's time (%" PRId64 ") > B's time (%" PRId64 ")",
+ time[2], time[1]);
goto cleanup;
}
if (time[1] <= time[0]) {
- debug("Expect B's time (%ld) > A's time (%ld)", time[1], time[0]);
+ debug("Expect B's time (%" PRId64 ") > A's time (%" PRId64 ")",
+ time[1], time[0]);
goto cleanup;
}
diff --git a/tools/testing/selftests/cgroup/test_hugetlb_memcg.c b/tools/testing/selftests/cgroup/test_hugetlb_memcg.c
index 8c5aced813b6..803248c496e4 100644
--- a/tools/testing/selftests/cgroup/test_hugetlb_memcg.c
+++ b/tools/testing/selftests/cgroup/test_hugetlb_memcg.c
@@ -96,16 +96,17 @@ static int hugetlb_test_program(const char *cgroup, void *arg)
{
char *test_group = (char *)arg;
void *addr;
- long old_current, expected_current, current;
+ s64 old_current, expected_current, current;
int ret = EXIT_FAILURE;
- old_current = cg_read_long(test_group, "memory.current");
+ old_current = cg_read_s64(test_group, "memory.current");
set_nr_hugepages(20);
- current = cg_read_long(test_group, "memory.current");
+ current = cg_read_s64(test_group, "memory.current");
if (current - old_current >= MB(2)) {
ksft_print_msg(
"setting nr_hugepages should not increase hugepage usage.\n");
- ksft_print_msg("before: %ld, after: %ld\n", old_current, current);
+ ksft_print_msg("before: %" PRId64 ", after: %" PRId64 "\n",
+ old_current, current);
return EXIT_FAILURE;
}
@@ -114,10 +115,11 @@ static int hugetlb_test_program(const char *cgroup, void *arg)
ksft_print_msg("fail to mmap.\n");
return EXIT_FAILURE;
}
- current = cg_read_long(test_group, "memory.current");
+ current = cg_read_s64(test_group, "memory.current");
if (current - old_current >= MB(2)) {
ksft_print_msg("mmap should not increase hugepage usage.\n");
- ksft_print_msg("before: %ld, after: %ld\n", old_current, current);
+ ksft_print_msg("before: %" PRId64 ", after: %" PRId64 "\n",
+ old_current, current);
goto out_failed_munmap;
}
old_current = current;
@@ -125,35 +127,35 @@ static int hugetlb_test_program(const char *cgroup, void *arg)
/* read the first page */
check_first(addr);
expected_current = old_current + MB(2);
- current = cg_read_long(test_group, "memory.current");
+ current = cg_read_s64(test_group, "memory.current");
if (!values_close(expected_current, current, 5)) {
ksft_print_msg("memory usage should increase by around 2MB.\n");
ksft_print_msg(
- "expected memory: %ld, actual memory: %ld\n",
+ "expected memory: %" PRId64 ", actual memory: %" PRId64 "\n",
expected_current, current);
goto out_failed_munmap;
}
/* write to the whole range */
write_data(addr);
- current = cg_read_long(test_group, "memory.current");
+ current = cg_read_s64(test_group, "memory.current");
expected_current = old_current + MB(8);
if (!values_close(expected_current, current, 5)) {
ksft_print_msg("memory usage should increase by around 8MB.\n");
ksft_print_msg(
- "expected memory: %ld, actual memory: %ld\n",
+ "expected memory: %" PRId64 ", actual memory: %" PRId64 "\n",
expected_current, current);
goto out_failed_munmap;
}
/* unmap the whole range */
munmap(addr, LENGTH);
- current = cg_read_long(test_group, "memory.current");
+ current = cg_read_s64(test_group, "memory.current");
expected_current = old_current;
if (!values_close(expected_current, current, 5)) {
ksft_print_msg("memory usage should go back down.\n");
ksft_print_msg(
- "expected memory: %ld, actual memory: %ld\n",
+ "expected memory: %" PRId64 ", actual memory: %" PRId64 "\n",
expected_current, current);
return ret;
}
diff --git a/tools/testing/selftests/cgroup/test_kmem.c b/tools/testing/selftests/cgroup/test_kmem.c
index 30af47ad6979..43a8eb094f48 100644
--- a/tools/testing/selftests/cgroup/test_kmem.c
+++ b/tools/testing/selftests/cgroup/test_kmem.c
@@ -54,7 +54,7 @@ static int test_kmem_basic(const char *root)
{
int ret = KSFT_FAIL;
char *cg = NULL;
- long slab0, slab1, current;
+ s64 slab0, slab1, current;
cg = cg_name(root, "kmem_basic_test");
if (!cg)
@@ -66,7 +66,7 @@ static int test_kmem_basic(const char *root)
if (cg_run(cg, alloc_dcache, (void *)100000))
goto cleanup;
- slab0 = cg_read_key_long(cg, "memory.stat", "slab ");
+ slab0 = cg_read_key_s64(cg, "memory.stat", "slab ");
if (slab0 < (1 << 20))
goto cleanup;
@@ -75,11 +75,11 @@ static int test_kmem_basic(const char *root)
/* wait for RCU freeing */
sleep(1);
- slab1 = cg_read_key_long(cg, "memory.stat", "slab ");
+ slab1 = cg_read_key_s64(cg, "memory.stat", "slab ");
if (slab1 < 0)
goto cleanup;
- current = cg_read_long(cg, "memory.current");
+ current = cg_read_s64(cg, "memory.current");
if (current < 0)
goto cleanup;
@@ -167,7 +167,7 @@ static int cg_run_in_subcgroups(const char *parent,
*/
static int test_kmem_memcg_deletion(const char *root)
{
- long current, anon, file, kernel, sock, sum;
+ s64 current, anon, file, kernel, sock, sum;
int ret = KSFT_FAIL;
char *parent;
@@ -184,24 +184,24 @@ static int test_kmem_memcg_deletion(const char *root)
if (cg_run_in_subcgroups(parent, alloc_kmem_smp, NULL, 100))
goto cleanup;
- current = cg_read_long(parent, "memory.current");
- anon = cg_read_key_long(parent, "memory.stat", "anon ");
- file = cg_read_key_long(parent, "memory.stat", "file ");
- kernel = cg_read_key_long(parent, "memory.stat", "kernel ");
- sock = cg_read_key_long(parent, "memory.stat", "sock ");
+ current = cg_read_s64(parent, "memory.current");
+ anon = cg_read_key_s64(parent, "memory.stat", "anon ");
+ file = cg_read_key_s64(parent, "memory.stat", "file ");
+ kernel = cg_read_key_s64(parent, "memory.stat", "kernel ");
+ sock = cg_read_key_s64(parent, "memory.stat", "sock ");
if (current < 0 || anon < 0 || file < 0 || kernel < 0 || sock < 0)
goto cleanup;
sum = anon + file + kernel + sock;
- if (labs(sum - current) < MAX_VMSTAT_ERROR) {
+ if (llabs(sum - current) < MAX_VMSTAT_ERROR) {
ret = KSFT_PASS;
} else {
- printf("memory.current = %ld\n", current);
- printf("anon + file + kernel + sock = %ld\n", sum);
- printf("anon = %ld\n", anon);
- printf("file = %ld\n", file);
- printf("kernel = %ld\n", kernel);
- printf("sock = %ld\n", sock);
+ printf("memory.current = %" PRId64 "\n", current);
+ printf("anon + file + kernel + sock = %" PRId64 "\n", sum);
+ printf("anon = %" PRId64 "\n", anon);
+ printf("file = %" PRId64 "\n", file);
+ printf("kernel = %" PRId64 "\n", kernel);
+ printf("sock = %" PRId64 "\n", sock);
}
cleanup:
@@ -248,7 +248,7 @@ static int spawn_1000_threads(const char *cgroup, void *arg)
int nr_threads = 1000;
pthread_t *tinfo;
unsigned long i;
- long stack;
+ s64 stack;
int ret = -1;
tinfo = calloc(nr_threads, sizeof(pthread_t));
@@ -263,7 +263,7 @@ static int spawn_1000_threads(const char *cgroup, void *arg)
}
}
- stack = cg_read_key_long(cgroup, "memory.stat", "kernel_stack ");
+ stack = cg_read_key_s64(cgroup, "memory.stat", "kernel_stack ");
if (stack >= 4096 * 1000)
ret = 0;
@@ -307,7 +307,7 @@ static int test_kmem_dead_cgroups(const char *root)
{
int ret = KSFT_FAIL;
char *parent;
- long dead = -1;
+ s64 dead = -1;
parent = cg_name(root, "kmem_dead_cgroups_test");
if (!parent)
@@ -328,9 +328,10 @@ static int test_kmem_dead_cgroups(const char *root)
* from a specific kernel constant, and can be adjusted if reclaim
* behavior changes in the future.
*/
- dead = cg_read_key_long_poll(parent, "cgroup.stat",
- "nr_dying_descendants ", 0, KMEM_DEAD_WAIT_RETRIES,
- DEFAULT_WAIT_INTERVAL_US);
+ dead = cg_read_key_s64_poll(parent, "cgroup.stat",
+ "nr_dying_descendants ", 0,
+ KMEM_DEAD_WAIT_RETRIES,
+ DEFAULT_WAIT_INTERVAL_US);
if (dead)
goto cleanup;
@@ -353,7 +354,7 @@ static int test_percpu_basic(const char *root)
{
int ret = KSFT_FAIL;
char *parent, *child;
- long current, percpu, slab;
+ s64 current, percpu, slab;
int i;
parent = cg_name(root, "percpu_basic_test");
@@ -381,16 +382,17 @@ static int test_percpu_basic(const char *root)
free(child);
}
- current = cg_read_long(parent, "memory.current");
- percpu = cg_read_key_long(parent, "memory.stat", "percpu ");
- slab = cg_read_key_long(parent, "memory.stat", "slab ");
+ current = cg_read_s64(parent, "memory.current");
+ percpu = cg_read_key_s64(parent, "memory.stat", "percpu ");
+ slab = cg_read_key_s64(parent, "memory.stat", "slab ");
if (current > 0 && percpu > 0 && slab >= 0 &&
- labs(current - (percpu + slab)) < MAX_VMSTAT_ERROR)
+ llabs(current - (percpu + slab)) < MAX_VMSTAT_ERROR)
ret = KSFT_PASS;
else
- printf("memory.current %ld\npercpu %ld\nslab %ld\ndelta %ld\n",
- current, percpu, slab, current - (percpu + slab));
+ printf("memory.current %" PRId64 "\npercpu %" PRId64 "\nslab %"
+ PRId64 "\ndelta %" PRId64 "\n",
+ current, percpu, slab, current - (percpu + slab));
cleanup_children:
for (i = 0; i < 1000; i++) {
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index bb673012dcf0..9ff43e7c87b4 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -195,21 +195,21 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
{
size_t size = MB(50);
char *buf;
- long anon, current;
+ s64 anon, current;
int ret = -1;
buf = alloc_and_populate_anon(size);
if (!buf)
return -1;
- current = cg_read_long(cgroup, "memory.current");
+ current = cg_read_s64(cgroup, "memory.current");
if (current < size)
goto cleanup;
if (!values_close(size, current, 3))
goto cleanup;
- anon = cg_read_key_long(cgroup, "memory.stat", "anon ");
+ anon = cg_read_key_s64(cgroup, "memory.stat", "anon ");
if (anon < 0)
goto cleanup;
@@ -226,7 +226,7 @@ static int alloc_pagecache_50M_check(const char *cgroup, void *arg)
{
size_t size = MB(50);
int ret = -1;
- long current, file;
+ s64 current, file;
int fd;
fd = get_temp_fd();
@@ -236,11 +236,11 @@ static int alloc_pagecache_50M_check(const char *cgroup, void *arg)
if (alloc_pagecache(fd, size))
goto cleanup;
- current = cg_read_long(cgroup, "memory.current");
+ current = cg_read_s64(cgroup, "memory.current");
if (current < size)
goto cleanup;
- file = cg_read_key_long(cgroup, "memory.stat", "file ");
+ file = cg_read_key_s64(cgroup, "memory.stat", "file ");
if (file < 0)
goto cleanup;
@@ -262,7 +262,8 @@ cleanup:
static int test_memcg_current_peak(const char *root)
{
int ret = KSFT_FAIL;
- long current, peak, peak_reset;
+ s64 current, peak;
+ long peak_reset;
char *memcg;
bool fd2_closed = false, fd3_closed = false, fd4_closed = false;
int peak_fd = -1, peak_fd2 = -1, peak_fd3 = -1, peak_fd4 = -1;
@@ -275,18 +276,18 @@ static int test_memcg_current_peak(const char *root)
if (cg_create(memcg))
goto cleanup;
- current = cg_read_long(memcg, "memory.current");
+ current = cg_read_s64(memcg, "memory.current");
if (current != 0)
goto cleanup;
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak != 0)
goto cleanup;
if (cg_run(memcg, alloc_anon_50M_check, NULL))
goto cleanup;
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak < MB(50))
goto cleanup;
@@ -342,7 +343,7 @@ static int test_memcg_current_peak(const char *root)
goto cleanup;
/* Make sure a completely independent read isn't affected by our FD-local reset above*/
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak < MB(50))
goto cleanup;
@@ -359,23 +360,23 @@ static int test_memcg_current_peak(const char *root)
if (peak_reset != sizeof(reset_string))
goto cleanup;
- peak = cg_read_long_fd(peak_fd);
+ peak = cg_read_s64_fd(peak_fd);
if (peak > MB(30) || peak < 0)
goto cleanup;
if (cg_run(memcg, alloc_pagecache_50M_check, NULL))
goto cleanup;
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak < MB(50))
goto cleanup;
/* Make sure everything is back to normal */
- peak = cg_read_long_fd(peak_fd);
+ peak = cg_read_s64_fd(peak_fd);
if (peak < MB(50))
goto cleanup;
- peak = cg_read_long_fd(peak_fd4);
+ peak = cg_read_s64_fd(peak_fd4);
if (peak < MB(50))
goto cleanup;
@@ -451,7 +452,7 @@ static int cg_test_proc_killed(const char *cgroup)
return -1;
}
-static bool reclaim_until(const char *memcg, long goal);
+static bool reclaim_until(const char *memcg, s64 goal);
/*
* First, this test creates the following hierarchy:
@@ -495,8 +496,8 @@ static int test_memcg_protection(const char *root, bool min)
char *parent[3] = {NULL};
char *children[4] = {NULL};
const char *attribute = min ? "memory.min" : "memory.low";
- long c[4];
- long current;
+ s64 c[4];
+ s64 current;
int i, attempts;
int fd;
@@ -519,7 +520,7 @@ static int test_memcg_protection(const char *root, bool min)
if (cg_create(parent[0]))
goto cleanup;
- if (cg_read_long(parent[0], attribute)) {
+ if (cg_read_s64(parent[0], attribute)) {
/* No memory.min on older kernels is fine */
if (min)
ret = KSFT_SKIP;
@@ -571,7 +572,7 @@ static int test_memcg_protection(const char *root, bool min)
goto cleanup;
attempts = 0;
- while (!values_close(cg_read_long(parent[1], "memory.current"),
+ while (!values_close(cg_read_s64(parent[1], "memory.current"),
MB(150), 3)) {
if (attempts++ > 5)
break;
@@ -581,11 +582,11 @@ static int test_memcg_protection(const char *root, bool min)
if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
goto cleanup;
- if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
+ if (!values_close(cg_read_s64(parent[1], "memory.current"), MB(50), 3))
goto cleanup;
for (i = 0; i < ARRAY_SIZE(children); i++)
- c[i] = cg_read_long(children[i], "memory.current");
+ c[i] = cg_read_s64(children[i], "memory.current");
if (!values_close(c[0], MB(29), 15))
goto cleanup;
@@ -606,7 +607,7 @@ static int test_memcg_protection(const char *root, bool min)
}
current = min ? MB(50) : MB(30);
- if (!values_close(cg_read_long(parent[1], "memory.current"), current, 3))
+ if (!values_close(cg_read_s64(parent[1], "memory.current"), current, 3))
goto cleanup;
if (!reclaim_until(children[0], MB(10)))
@@ -626,10 +627,10 @@ static int test_memcg_protection(const char *root, bool min)
for (i = 0; i < ARRAY_SIZE(children); i++) {
int ignore_low_events_index = has_recursiveprot ? 2 : -1;
int no_low_events_index = 1;
- long low, oom;
+ s64 low, oom;
- oom = cg_read_key_long(children[i], "memory.events", "oom ");
- low = cg_read_key_long(children[i], "memory.events", "low ");
+ oom = cg_read_key_s64(children[i], "memory.events", "oom ");
+ low = cg_read_key_s64(children[i], "memory.events", "low ");
if (oom)
goto cleanup;
@@ -678,11 +679,11 @@ static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
{
size_t size = MB(50);
int ret = -1;
- long current, high, max;
+ s64 current, high, max;
int fd;
- high = cg_read_long(cgroup, "memory.high");
- max = cg_read_long(cgroup, "memory.max");
+ high = cg_read_s64(cgroup, "memory.high");
+ max = cg_read_s64(cgroup, "memory.max");
if (high != MB(30) && max != MB(30))
return -1;
@@ -693,7 +694,7 @@ static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
if (alloc_pagecache(fd, size))
goto cleanup;
- current = cg_read_long(cgroup, "memory.current");
+ current = cg_read_s64(cgroup, "memory.current");
if (!values_close(current, MB(30), 5))
goto cleanup;
@@ -714,7 +715,7 @@ static int test_memcg_high(const char *root)
{
int ret = KSFT_FAIL;
char *memcg;
- long high;
+ s64 high;
memcg = cg_name(root, "memcg_test");
if (!memcg)
@@ -741,7 +742,7 @@ static int test_memcg_high(const char *root)
if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
goto cleanup;
- high = cg_read_key_long(memcg, "memory.events", "high ");
+ high = cg_read_key_s64(memcg, "memory.events", "high ");
if (high <= 0)
goto cleanup;
@@ -777,8 +778,8 @@ static int test_memcg_high_sync(const char *root)
{
int ret = KSFT_FAIL, pid, fd = -1;
char *memcg;
- long pre_high, pre_max;
- long post_high, post_max;
+ s64 pre_high, pre_max;
+ s64 post_high, post_max;
memcg = cg_name(root, "memcg_test");
if (!memcg)
@@ -787,8 +788,8 @@ static int test_memcg_high_sync(const char *root)
if (cg_create(memcg))
goto cleanup;
- pre_high = cg_read_key_long(memcg, "memory.events", "high ");
- pre_max = cg_read_key_long(memcg, "memory.events", "max ");
+ pre_high = cg_read_key_s64(memcg, "memory.events", "high ");
+ pre_max = cg_read_key_s64(memcg, "memory.events", "max ");
if (pre_high < 0 || pre_max < 0)
goto cleanup;
@@ -811,8 +812,8 @@ static int test_memcg_high_sync(const char *root)
cg_wait_for(fd);
- post_high = cg_read_key_long(memcg, "memory.events", "high ");
- post_max = cg_read_key_long(memcg, "memory.events", "max ");
+ post_high = cg_read_key_s64(memcg, "memory.events", "high ");
+ post_max = cg_read_key_s64(memcg, "memory.events", "max ");
if (post_high < 0 || post_max < 0)
goto cleanup;
@@ -839,7 +840,7 @@ static int test_memcg_max(const char *root)
{
int ret = KSFT_FAIL;
char *memcg;
- long current, max;
+ s64 current, max;
memcg = cg_name(root, "memcg_test");
if (!memcg)
@@ -864,11 +865,11 @@ static int test_memcg_max(const char *root)
if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
goto cleanup;
- current = cg_read_long(memcg, "memory.current");
+ current = cg_read_s64(memcg, "memory.current");
if (current > MB(30) || !current)
goto cleanup;
- max = cg_read_key_long(memcg, "memory.events", "max ");
+ max = cg_read_key_s64(memcg, "memory.events", "max ");
if (max <= 0)
goto cleanup;
@@ -896,15 +897,15 @@ cleanup:
* false if memory.reclaim's error codes do not make sense, even if
* the usage goal was satisfied.
*/
-static bool reclaim_until(const char *memcg, long goal)
+static bool reclaim_until(const char *memcg, s64 goal)
{
char buf[64];
int retries, err;
- long current, to_reclaim;
+ s64 current, to_reclaim;
bool reclaimed = false;
for (retries = 5; retries > 0; retries--) {
- current = cg_read_long(memcg, "memory.current");
+ current = cg_read_s64(memcg, "memory.current");
if (current < goal || values_close(current, goal, 3))
break;
@@ -913,7 +914,7 @@ static bool reclaim_until(const char *memcg, long goal)
return false;
to_reclaim = current - goal;
- snprintf(buf, sizeof(buf), "%ld", to_reclaim);
+ snprintf(buf, sizeof(buf), "%" PRId64, to_reclaim);
err = cg_write(memcg, "memory.reclaim", buf);
if (!err)
reclaimed = true;
@@ -933,7 +934,7 @@ static int test_memcg_reclaim(const char *root)
int fd = -1;
int retries;
char *memcg;
- long current, expected_usage;
+ s64 current, expected_usage;
memcg = cg_name(root, "memcg_test");
if (!memcg)
@@ -942,7 +943,7 @@ static int test_memcg_reclaim(const char *root)
if (cg_create(memcg))
goto cleanup;
- current = cg_read_long(memcg, "memory.current");
+ current = cg_read_s64(memcg, "memory.current");
if (current != 0)
goto cleanup;
@@ -967,14 +968,14 @@ static int test_memcg_reclaim(const char *root)
* retries).
*/
retries = 5;
- while (!values_close(cg_read_long(memcg, "memory.current"),
- expected_usage, 10)) {
+ while (!values_close(cg_read_s64(memcg, "memory.current"),
+ expected_usage, 10)) {
if (retries--) {
sleep(1);
continue;
} else {
fprintf(stderr,
- "failed to allocate %ld for memcg reclaim test\n",
+ "failed to allocate %" PRId64 " for memcg reclaim test\n",
expected_usage);
goto cleanup;
}
@@ -1001,18 +1002,18 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
long mem_max = (long)arg;
size_t size = MB(50);
char *buf;
- long mem_current, swap_current;
+ s64 mem_current, swap_current;
int ret = -1;
buf = alloc_and_populate_anon(size);
if (!buf)
return -1;
- mem_current = cg_read_long(cgroup, "memory.current");
+ mem_current = cg_read_s64(cgroup, "memory.current");
if (!mem_current || !values_close(mem_current, mem_max, 3))
goto cleanup;
- swap_current = cg_read_long(cgroup, "memory.swap.current");
+ swap_current = cg_read_s64(cgroup, "memory.swap.current");
if (!swap_current ||
!values_close(mem_current + swap_current, size, 3))
goto cleanup;
@@ -1032,7 +1033,7 @@ static int test_memcg_swap_max_peak(const char *root)
{
int ret = KSFT_FAIL;
char *memcg;
- long max, peak;
+ s64 max, peak;
struct stat ss;
int swap_peak_fd = -1, mem_peak_fd = -1;
@@ -1049,7 +1050,7 @@ static int test_memcg_swap_max_peak(const char *root)
if (cg_create(memcg))
goto cleanup;
- if (cg_read_long(memcg, "memory.swap.current")) {
+ if (cg_read_s64(memcg, "memory.swap.current")) {
ret = KSFT_SKIP;
goto cleanup;
}
@@ -1081,10 +1082,10 @@ static int test_memcg_swap_max_peak(const char *root)
if (mem_peak_fd == -1)
goto cleanup;
- if (cg_read_long(memcg, "memory.swap.peak"))
+ if (cg_read_s64(memcg, "memory.swap.peak"))
goto cleanup;
- if (cg_read_long_fd(swap_peak_fd))
+ if (cg_read_s64_fd(swap_peak_fd))
goto cleanup;
/* switch the swap and mem fds into local-peak tracking mode*/
@@ -1093,20 +1094,20 @@ static int test_memcg_swap_max_peak(const char *root)
if (peak_reset != sizeof(reset_string))
goto cleanup;
- if (cg_read_long_fd(swap_peak_fd))
+ if (cg_read_s64_fd(swap_peak_fd))
goto cleanup;
- if (cg_read_long(memcg, "memory.peak"))
+ if (cg_read_s64(memcg, "memory.peak"))
goto cleanup;
- if (cg_read_long_fd(mem_peak_fd))
+ if (cg_read_s64_fd(mem_peak_fd))
goto cleanup;
peak_reset = write(mem_peak_fd, reset_string, sizeof(reset_string));
if (peak_reset != sizeof(reset_string))
goto cleanup;
- if (cg_read_long_fd(mem_peak_fd))
+ if (cg_read_s64_fd(mem_peak_fd))
goto cleanup;
if (cg_read_strcmp(memcg, "memory.max", "max\n"))
@@ -1125,25 +1126,25 @@ static int test_memcg_swap_max_peak(const char *root)
if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
goto cleanup;
- if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
+ if (cg_read_key_s64(memcg, "memory.events", "oom ") != 1)
goto cleanup;
- if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
+ if (cg_read_key_s64(memcg, "memory.events", "oom_kill ") != 1)
goto cleanup;
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long(memcg, "memory.swap.peak");
+ peak = cg_read_s64(memcg, "memory.swap.peak");
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long_fd(mem_peak_fd);
+ peak = cg_read_s64_fd(mem_peak_fd);
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long_fd(swap_peak_fd);
+ peak = cg_read_s64_fd(swap_peak_fd);
if (peak < MB(29))
goto cleanup;
@@ -1168,7 +1169,7 @@ static int test_memcg_swap_max_peak(const char *root)
if (peak_reset != sizeof(reset_string))
goto cleanup;
- peak = cg_read_long_fd(swap_peak_fd);
+ peak = cg_read_s64_fd(swap_peak_fd);
if (peak > MB(10))
goto cleanup;
@@ -1176,36 +1177,36 @@ static int test_memcg_swap_max_peak(const char *root)
* The cgroup is now empty, but there may be a page or two associated
* with the open FD accounted to it.
*/
- peak = cg_read_long_fd(mem_peak_fd);
+ peak = cg_read_s64_fd(mem_peak_fd);
if (peak > MB(1))
goto cleanup;
- if (cg_read_long(memcg, "memory.peak") < MB(29))
+ if (cg_read_s64(memcg, "memory.peak") < MB(29))
goto cleanup;
- if (cg_read_long(memcg, "memory.swap.peak") < MB(29))
+ if (cg_read_s64(memcg, "memory.swap.peak") < MB(29))
goto cleanup;
if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30)))
goto cleanup;
- max = cg_read_key_long(memcg, "memory.events", "max ");
+ max = cg_read_key_s64(memcg, "memory.events", "max ");
if (max <= 0)
goto cleanup;
- peak = cg_read_long(memcg, "memory.peak");
+ peak = cg_read_s64(memcg, "memory.peak");
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long(memcg, "memory.swap.peak");
+ peak = cg_read_s64(memcg, "memory.swap.peak");
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long_fd(mem_peak_fd);
+ peak = cg_read_s64_fd(mem_peak_fd);
if (peak < MB(29))
goto cleanup;
- peak = cg_read_long_fd(swap_peak_fd);
+ peak = cg_read_s64_fd(swap_peak_fd);
if (peak < MB(19))
goto cleanup;
@@ -1251,10 +1252,10 @@ static int test_memcg_oom_events(const char *root)
if (cg_read_strcmp(memcg, "cgroup.procs", ""))
goto cleanup;
- if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
+ if (cg_read_key_s64(memcg, "memory.events", "oom ") != 1)
goto cleanup;
- if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
+ if (cg_read_key_s64(memcg, "memory.events", "oom_kill ") != 1)
goto cleanup;
ret = KSFT_PASS;
@@ -1339,9 +1340,9 @@ static int tcp_client(const char *cgroup, unsigned short port)
long budget = 4 * MEMCG_FLUSH_BYTES;
int rcvbuf = 64 * 1024;
int sk, ret;
- long allocated;
+ s64 allocated;
- allocated = cg_read_long(cgroup, "memory.current");
+ allocated = cg_read_s64(cgroup, "memory.current");
snprintf(servport, sizeof(servport), "%hd", port);
ret = getaddrinfo(server, servport, NULL, &ai);
if (ret)
@@ -1363,7 +1364,7 @@ static int tcp_client(const char *cgroup, unsigned short port)
ret = KSFT_FAIL;
while (budget > 0) {
uint8_t buf[0x100000];
- long current, sock;
+ s64 current, sock;
ssize_t len;
len = read(sk, buf, sizeof(buf));
@@ -1371,8 +1372,8 @@ static int tcp_client(const char *cgroup, unsigned short port)
goto close_sk;
budget -= len;
- current = cg_read_long(cgroup, "memory.current");
- sock = cg_read_key_long(cgroup, "memory.stat", "sock ");
+ current = cg_read_s64(cgroup, "memory.current");
+ sock = cg_read_key_s64(cgroup, "memory.stat", "sock ");
if (current < 0 || sock < 0)
goto close_sk;
@@ -1422,7 +1423,7 @@ static int test_memcg_sock(const char *root)
int bind_retries = 5, ret = KSFT_FAIL, pid, err;
unsigned short port;
char *memcg;
- long sock_post = -1;
+ s64 sock_post = -1;
int flush_rounds = 3;
if (memcg_sockets_disabled())
@@ -1478,7 +1479,7 @@ static int test_memcg_sock(const char *root)
if (WEXITSTATUS(err))
goto cleanup;
- if (cg_read_long(memcg, "memory.current") < 0)
+ if (cg_read_s64(memcg, "memory.current") < 0)
goto cleanup;
/* the uncharge is done, but a flush still walking the CPUs can hide it from a read */
@@ -1486,7 +1487,7 @@ static int test_memcg_sock(const char *root)
if (cg_run(memcg, alloc_anon, (void *)MEMCG_FLUSH_BYTES))
goto cleanup;
- sock_post = cg_read_key_long(memcg, "memory.stat", "sock ");
+ sock_post = cg_read_key_s64(memcg, "memory.stat", "sock ");
if (!sock_post)
break;
}
@@ -1512,7 +1513,7 @@ static int test_memcg_oom_group_leaf_events(const char *root)
{
int ret = KSFT_FAIL;
char *parent, *child;
- long parent_oom_events;
+ s64 parent_oom_events;
parent = cg_name(root, "memcg_test_0");
child = cg_name(root, "memcg_test_0/memcg_test_1");
@@ -1547,11 +1548,11 @@ static int test_memcg_oom_group_leaf_events(const char *root)
if (cg_test_proc_killed(child))
goto cleanup;
- if (cg_read_key_long(child, "memory.events", "oom_kill ") <= 0)
+ if (cg_read_key_s64(child, "memory.events", "oom_kill ") <= 0)
goto cleanup;
- parent_oom_events = cg_read_key_long(
- parent, "memory.events", "oom_kill ");
+ parent_oom_events =
+ cg_read_key_s64(parent, "memory.events", "oom_kill ");
/*
* If memory_localevents is not enabled (the default), the parent should
* count OOM events in its children groups. Otherwise, it should not
@@ -1667,7 +1668,7 @@ static int test_memcg_oom_group_score_events(const char *root)
if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
goto cleanup;
- if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 3)
+ if (cg_read_key_s64(memcg, "memory.events", "oom_kill ") != 3)
goto cleanup;
if (kill(safe_pid, SIGKILL))
diff --git a/tools/testing/selftests/cgroup/test_pids.c b/tools/testing/selftests/cgroup/test_pids.c
index e775c5510cf2..9c1cda47c73d 100644
--- a/tools/testing/selftests/cgroup/test_pids.c
+++ b/tools/testing/selftests/cgroup/test_pids.c
@@ -114,9 +114,9 @@ static int test_pids_events(const char *root)
if (kill(pid, SIGINT))
goto cleanup;
- if (cg_read_key_long(cg_child, "pids.events", "max ") != 0)
+ if (cg_read_key_s64(cg_child, "pids.events", "max ") != 0)
goto cleanup;
- if (cg_read_key_long(cg_parent, "pids.events", "max ") != 1)
+ if (cg_read_key_s64(cg_parent, "pids.events", "max ") != 1)
goto cleanup;
@@ -179,7 +179,7 @@ static int test_pids_events_notify(const char *root)
if (cg_run_nowait(cg_pids, run_success, NULL) != -1 || errno != EAGAIN)
goto cleanup;
- if (cg_read_key_long(cg_pids, "pids.events", "max ") != 1)
+ if (cg_read_key_s64(cg_pids, "pids.events", "max ") != 1)
goto cleanup;
pfd.fd = inotify_fd;
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index abe2e4954c71..751cb2286610 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -31,7 +31,7 @@ static int read_int(const char *path, size_t *value)
file = fopen(path, "r");
if (!file)
return -1;
- if (fscanf(file, "%ld", value) != 1)
+ if (fscanf(file, "%zu", value) != 1)
ret = -1;
fclose(file);
return ret;
@@ -45,7 +45,7 @@ static int set_min_free_kb(size_t value)
file = fopen("/proc/sys/vm/min_free_kbytes", "w");
if (!file)
return -1;
- ret = fprintf(file, "%ld\n", value);
+ ret = fprintf(file, "%zu\n", value);
fclose(file);
return ret;
}
@@ -60,14 +60,14 @@ static int get_zswap_stored_pages(size_t *value)
return read_int(PATH_ZSWAP_STORED_PAGES, value);
}
-static long get_cg_wb_count(const char *cg)
+static s64 get_cg_wb_count(const char *cg)
{
- return cg_read_key_long(cg, "memory.stat", "zswpwb");
+ return cg_read_key_s64(cg, "memory.stat", "zswpwb");
}
-static long get_zswpout(const char *cgroup)
+static s64 get_zswpout(const char *cgroup)
{
- return cg_read_key_long(cgroup, "memory.stat", "zswpout ");
+ return cg_read_key_s64(cgroup, "memory.stat", "zswpout ");
}
static int allocate_and_read_bytes(const char *cgroup, void *arg)
@@ -126,9 +126,10 @@ fail:
* Writeback is asynchronous; poll until at least one writeback has
* been recorded for @cg, or until @timeout_ms has elapsed.
*/
-static long wait_for_writeback(const char *cg, int timeout_ms)
+static s64 wait_for_writeback(const char *cg, int timeout_ms)
{
- long elapsed, count;
+ long elapsed;
+ s64 count;
for (elapsed = 0; elapsed < timeout_ms; elapsed += 100) {
count = get_cg_wb_count(cg);
@@ -148,7 +149,7 @@ static long wait_for_writeback(const char *cg, int timeout_ms)
*/
static int test_zswap_usage(const char *root)
{
- long zswpout_before, zswpout_after;
+ s64 zswpout_before, zswpout_after;
int ret = KSFT_FAIL;
char *test_group;
@@ -192,7 +193,7 @@ static int test_swapin_nozswap(const char *root)
{
int ret = KSFT_FAIL;
char *test_group, mem_max_buf[32];
- long swap_peak, zswpout, min_swap;
+ s64 swap_peak, zswpout, min_swap;
size_t allocation_size = page_size * 512;
min_swap = allocation_size / 4;
@@ -213,15 +214,15 @@ static int test_swapin_nozswap(const char *root)
goto out;
/* Verify that pages are swapped out, but no zswap happened */
- swap_peak = cg_read_long(test_group, "memory.swap.peak");
+ swap_peak = cg_read_s64(test_group, "memory.swap.peak");
if (swap_peak < 0) {
ksft_print_msg("failed to get cgroup's swap_peak\n");
goto out;
}
if (swap_peak < min_swap) {
- ksft_print_msg("at least %ldKB of memory should be swapped out\n",
- min_swap / 1024);
+ ksft_print_msg("at least %" PRId64 "KB of memory should be swapped out\n",
+ min_swap / 1024);
goto out;
}
@@ -249,7 +250,7 @@ static int test_zswapin(const char *root)
{
int ret = KSFT_FAIL;
char *test_group;
- long zswpin;
+ s64 zswpin;
test_group = cg_name(root, "zswapin_test");
if (!test_group)
@@ -265,7 +266,7 @@ static int test_zswapin(const char *root)
if (cg_run(test_group, allocate_and_read_bytes, (void *)MB(32)))
goto out;
- zswpin = cg_read_key_long(test_group, "memory.stat", "zswpin ");
+ zswpin = cg_read_key_s64(test_group, "memory.stat", "zswpin ");
if (zswpin < 0) {
ksft_print_msg("failed to get zswpin\n");
goto out;
@@ -300,7 +301,7 @@ static int attempt_writeback(const char *cgroup, void *arg)
{
size_t memsize = page_size * 1024;
char buf[page_size];
- long zswap_usage;
+ s64 zswap_usage;
bool wb_enabled = *(bool *) arg;
int ret = -1;
char *mem;
@@ -326,7 +327,7 @@ static int attempt_writeback(const char *cgroup, void *arg)
goto out;
}
- zswap_usage = cg_read_long(cgroup, "memory.zswap.current");
+ zswap_usage = cg_read_s64(cgroup, "memory.zswap.current");
/* zswpin */
for (int i = 0; i < memsize; i += page_size) {
@@ -365,11 +366,12 @@ out:
static int test_zswap_writeback_one(const char *cgroup, bool wb)
{
- long zswpwb_before, zswpwb_after;
+ s64 zswpwb_before, zswpwb_after;
zswpwb_before = get_cg_wb_count(cgroup);
if (zswpwb_before != 0) {
- ksft_print_msg("zswpwb_before = %ld instead of 0\n", zswpwb_before);
+ ksft_print_msg("zswpwb_before = %" PRId64 " instead of 0\n",
+ zswpwb_before);
return -1;
}
@@ -385,8 +387,8 @@ static int test_zswap_writeback_one(const char *cgroup, bool wb)
return -1;
if (wb != !!zswpwb_after) {
- ksft_print_msg("zswpwb_after is %ld while wb is %s\n",
- zswpwb_after, wb ? "enabled" : "disabled");
+ ksft_print_msg("zswpwb_after is %" PRId64 " while wb is %s\n",
+ zswpwb_after, wb ? "enabled" : "disabled");
return -1;
}
@@ -475,7 +477,7 @@ static int test_no_invasive_cgroup_shrink(const char *root)
{
int ret = KSFT_FAIL;
unsigned int off;
- long zswpwb_before, zswpwb_after, zswpwb_target;
+ s64 zswpwb_before, zswpwb_after, zswpwb_target;
size_t allocation_size = page_size * 1024;
unsigned int nr_pages = allocation_size / page_size;
char zswap_max_buf[32], mem_max_buf[32];
@@ -510,7 +512,7 @@ static int test_no_invasive_cgroup_shrink(const char *root)
memset(&zw_allocation[off], 0, page_size);
memset(&zw_allocation[off], 'a', page_size/4);
}
- if (cg_read_key_long(zw_group, "memory.stat", "zswapped") < 1)
+ if (cg_read_key_s64(zw_group, "memory.stat", "zswapped") < 1)
goto out;
/* If the shrinker is enabled, try to let the writebacks finish first */
@@ -665,12 +667,11 @@ static int test_no_kmem_bypass(const char *root)
break;
/* If memory was pushed to zswap, verify it belongs to memcg */
if (stored_pages > stored_pages_threshold) {
- long zswapped = cg_read_key_long(
- test_group, "memory.stat", "zswapped ");
- long long delta =
- (long long)stored_pages * page_size - zswapped;
- long long max_delta =
- (long long)stored_pages * page_size / 4;
+ s64 zswapped = cg_read_key_s64(test_group,
+ "memory.stat",
+ "zswapped ");
+ s64 delta = (s64)stored_pages * page_size - zswapped;
+ s64 max_delta = (s64)stored_pages * page_size / 4;
ret = (delta < max_delta) ? KSFT_PASS : KSFT_FAIL;
break;
@@ -741,9 +742,9 @@ static int allocate_random_and_wait(const char *cgroup, void *arg)
return 0;
}
-static long get_zswap_incomp(const char *cgroup)
+static s64 get_zswap_incomp(const char *cgroup)
{
- return cg_read_key_long(cgroup, "memory.stat", "zswap_incomp ");
+ return cg_read_key_s64(cgroup, "memory.stat", "zswap_incomp ");
}
/*
@@ -759,7 +760,7 @@ static int test_zswap_incompressible(const char *root)
int ret = KSFT_FAIL;
struct incomp_child_args *values;
char *test_group;
- long zswap_incomp;
+ s64 zswap_incomp;
pid_t child_pid;
int child_status;
char buf;
@@ -795,12 +796,16 @@ static int test_zswap_incompressible(const char *root)
zswap_incomp = get_zswap_incomp(test_group);
if (zswap_incomp <= 0) {
- long zswpout = get_zswpout(test_group);
- long zswapped = cg_read_key_long(test_group, "memory.stat", "zswapped ");
- long zswap_b = cg_read_key_long(test_group, "memory.stat", "zswap ");
-
- ksft_print_msg("zswap_incomp not increased: %ld\n", zswap_incomp);
- ksft_print_msg("debug: zswpout=%ld zswapped=%ld zswap_b=%ld\n",
+ s64 zswpout = get_zswpout(test_group);
+ s64 zswapped =
+ cg_read_key_s64(test_group, "memory.stat", "zswapped ");
+ s64 zswap_b =
+ cg_read_key_s64(test_group, "memory.stat", "zswap ");
+
+ ksft_print_msg("zswap_incomp not increased: %" PRId64 "\n",
+ zswap_incomp);
+ ksft_print_msg("debug: zswpout=%" PRId64 " zswapped=%" PRId64
+ " zswap_b=%" PRId64 "\n",
zswpout, zswapped, zswap_b);
ksft_print_msg("debug: madvise ret=%d errno=%d\n",
values->madvise_ret, values->madvise_errno);