diff options
| author | Mark Brown <broonie@kernel.org> | 2026-11-13 16:40:27 +0000 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-11-13 16:40:27 +0000 |
| commit | 454bafaa24b135ac6800a997d10a7627ea823ca1 (patch) | |
| tree | 054c03f04f07af3eadca055f9cc0a3bdc93aeae1 | |
| parent | f9117be53eaa3ccf6efe9d9e694bd341c1ee1fc0 (diff) | |
| parent | 8be14e18e0f3a4b144efe8e1013b739be19dff78 (diff) | |
| download | linux-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.c | 22 | ||||
| -rw-r--r-- | kernel/cgroup/cpuset.c | 118 | ||||
| -rw-r--r-- | kernel/cgroup/legacy_freezer.c | 40 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/lib/cgroup_util.c | 36 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/lib/include/cgroup_util.h | 32 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_core.c | 36 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_cpu.c | 48 | ||||
| -rwxr-xr-x | tools/testing/selftests/cgroup/test_cpuset_prs.sh | 41 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_freezer.c | 88 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_hugetlb_memcg.c | 26 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_kmem.c | 62 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_memcontrol.c | 183 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_pids.c | 6 | ||||
| -rw-r--r-- | tools/testing/selftests/cgroup/test_zswap.c | 81 |
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 *)¶m)) 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 *)¶m)) 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 *)¶m)) 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); |
