Skip to content

Commit 311ead1

Browse files
Guopeng Zhanghtejun
authored andcommitted
selftests: cgroup: Add cg_read_key_long_poll() to poll a cgroup key with retries
Introduce a new helper function `cg_read_key_long_poll()` in cgroup_util.h. This function polls the specified key in a cgroup file until it matches the expected value or the retry limit is reached, with configurable wait intervals between retries. This helper is particularly useful for handling asynchronously updated cgroup statistics (e.g., memory.stat), where immediate reads may observe stale values, especially on busy systems. It allows tests and other utilities to handle such cases more flexibly. Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn> Suggested-by: Michal Koutný <mkoutny@suse.com> Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev> Acked-by: Michal Koutný <mkoutny@suse.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent 3309b63 commit 311ead1

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

tools/testing/selftests/cgroup/lib/cgroup_util.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ long cg_read_key_long(const char *cgroup, const char *control, const char *key)
168168
return atol(ptr + strlen(key));
169169
}
170170

171+
long cg_read_key_long_poll(const char *cgroup, const char *control,
172+
const char *key, long expected, int retries,
173+
useconds_t wait_interval_us)
174+
{
175+
long val = -1;
176+
int i;
177+
178+
for (i = 0; i < retries; i++) {
179+
val = cg_read_key_long(cgroup, control, key);
180+
if (val < 0)
181+
return val;
182+
183+
if (val == expected)
184+
break;
185+
186+
usleep(wait_interval_us);
187+
}
188+
189+
return val;
190+
}
191+
171192
long cg_read_lc(const char *cgroup, const char *control)
172193
{
173194
char buf[PAGE_SIZE];

tools/testing/selftests/cgroup/lib/include/cgroup_util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#define CG_NAMED_NAME "selftest"
1818
#define CG_PATH_FORMAT (!cg_test_v1_named ? "0::%s" : (":name=" CG_NAMED_NAME ":%s"))
1919

20+
#define DEFAULT_WAIT_INTERVAL_US (100 * 1000) /* 100 ms */
21+
2022
/*
2123
* Checks if two given values differ by less than err% of their sum.
2224
*/
@@ -64,6 +66,9 @@ extern int cg_read_strstr(const char *cgroup, const char *control,
6466
extern long cg_read_long(const char *cgroup, const char *control);
6567
extern long cg_read_long_fd(int fd);
6668
long cg_read_key_long(const char *cgroup, const char *control, const char *key);
69+
long cg_read_key_long_poll(const char *cgroup, const char *control,
70+
const char *key, long expected, int retries,
71+
useconds_t wait_interval_us);
6772
extern long cg_read_lc(const char *cgroup, const char *control);
6873
extern int cg_write(const char *cgroup, const char *control, char *buf);
6974
extern int cg_open(const char *cgroup, const char *control, int flags);

0 commit comments

Comments
 (0)