From: Thomas Hellström <[email protected]> Add write_eviction_nonblock to exercise the O_NONBLOCK path of the dmem cgroup max interface. After filling VRAM to the cgroup limit, each limit-lowering step writes dmem.max with O_NONBLOCK so that synchronous eviction is skipped. The test then verifies that usage has not yet dropped below the new limit, allocates a small BO to trigger eviction explicitly, and finally confirms that usage falls within bounds.
Assisted-by: GitHub Copilot:claude-sonnet-4.6 Signed-off-by: Thomas Hellström <[email protected]> Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]> --- tests/cgroup_dmem.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/cgroup_dmem.c b/tests/cgroup_dmem.c index 5cdb2f8830c8..7f3cfe22db2c 100644 --- a/tests/cgroup_dmem.c +++ b/tests/cgroup_dmem.c @@ -38,6 +38,7 @@ #define EVICT_STEP SZ_128M #define TEST_INTERRUPTIBLE (1 << 0) +#define TEST_NONBLOCK (1 << 1) /** * SUBTEST: simple @@ -73,6 +74,18 @@ * This subtest requires GPU device with at least one VRAM region. */ +/** + * SUBTEST: write_eviction_nonblock + * DESCRIPTION: + * Same fill phase as write_eviction. In the limit-lowering phase dmem.max + * is written with O_NONBLOCK, which causes the kernel to skip synchronous + * eviction. After each nonblock write the test verifies that usage has not + * yet dropped below the new limit, then triggers eviction explicitly by + * allocating a small BO. Finally verifies that usage falls within bounds + * after the forced eviction. + * This subtest requires GPU device with at least one VRAM region. + */ + static atomic_int signal_count; static struct sigaction sigcont_oldact; @@ -129,7 +142,7 @@ static void test_write_eviction(int fd, char *cg_region, unsigned int flags, con struct igt_cgroup *cg; void **handles; int max_bo; - uint64_t current, capacity, cg_max, limit, after; + uint64_t current, capacity, cg_max, limit, after, before; int err; igt_cgroup_dmem_get_capacity(cg_region, &capacity); @@ -174,14 +187,31 @@ static void test_write_eviction(int fd, char *cg_region, unsigned int flags, con while (limit >= EVICT_STEP) { limit -= EVICT_STEP; - igt_cgroup_dmem_set_max(cg, cg_region, limit, false); + + if (flags & TEST_NONBLOCK) + igt_cgroup_dmem_get_current(cg, cg_region, &before); + + igt_cgroup_dmem_set_max(cg, cg_region, limit, + !!(flags & TEST_NONBLOCK)); igt_cgroup_dmem_get_current(cg, cg_region, &after); igt_debug("Lowered max to %"PRIu64" MiB: usage = %"PRIu64" MiB\n", limit / SZ_1M, after / SZ_1M); + if (flags & TEST_NONBLOCK) { + /* + * O_NONBLOCK skips eviction: verify usage has not + * dropped below the new limit yet. + */ + igt_assert_f(after == before, + "Expected no eviction with O_NONBLOCK, but " + "usage dropped from %"PRIu64" MiB to %"PRIu64" MiB " + "(limit %"PRIu64" MiB)\n", + before / SZ_1M, after / SZ_1M, limit / SZ_1M); + } + if (limit > EVICT_STEP) { - if ((flags & TEST_INTERRUPTIBLE) && after > limit) { + if ((flags & (TEST_INTERRUPTIBLE | TEST_NONBLOCK)) && after > limit) { /* Let a new bo creation trigger eviction. */ void *handle; err = drv->allocate_vram(ctx, BO_SIZE / 8, &handle); @@ -218,6 +248,7 @@ static const struct { } subtests[] = { { "write_eviction", test_write_eviction, 0 }, { "write_eviction_interruptible", test_write_eviction, TEST_INTERRUPTIBLE }, + { "write_eviction_nonblock", test_write_eviction, TEST_NONBLOCK }, { } }; -- 2.47.3
