On 03/09/2026 23:00, Thadeu Lima de Souza Cascardo wrote:
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 0d3b415acd54..ee6345c17878 100644
--- a/tests/cgroup_dmem.c
+++ b/tests/cgroup_dmem.c
@@ -41,6 +41,7 @@
  #define USAGE_DROP_TIMEOUT_MS 1000
#define TEST_INTERRUPTIBLE (1 << 0)
+#define TEST_NONBLOCK          (1 << 1)
/**
   * SUBTEST: simple
@@ -90,6 +91,18 @@
   * REQUIREMENTS: must run as root; xe 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.
+ * REQUIREMENTS: must run as root; xe device with at least one VRAM region
+ */
+
  static atomic_int signal_count;
  static struct sigaction sigcont_oldact;
@@ -277,7 +290,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);
@@ -322,14 +335,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.
+                        */

Is this userspace ABI contract or happens to be? It feels odd - even if we ask for non block for the write why would kernel not be allowed to do stuff behind the covers?

Regards,

Tvrtko

+                       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);
@@ -368,6 +398,7 @@ static const struct {
        { "current", test_current, 0 },
        { "write_eviction", test_write_eviction, 0 },
        { "write_eviction_interruptible", test_write_eviction, 
TEST_INTERRUPTIBLE },
+       { "write_eviction_nonblock", test_write_eviction, TEST_NONBLOCK },
        { }
  };

Reply via email to