[PATCH v3] drm/i915/selftests: Keep mock file open during unfaultable migrate with fill
Krzysztof Karas
krzysztof.karas at intel.com
Tue Jun 17 13:19:07 UTC 2025
igt_mmap_migrate() tests migration with various parameters.
In one of the cases, where FILL and UNFAULTABLE flags are set,
during first stages of this test a mock file is opened in
igt_mmap_offset(), which results in allocating some data in the
GPU memory. Then, also in igt_mmap_offset(), the file is closed
(fput) and the cleanup of that data is scheduled. Right after
that, the test calls igt_fill_mappable() to fill all available
GPU memory. At this point, three scenarios are possible
(N = max size of GPU memory for this test in MiB):
1) the data cleanup does not fire until the whole test is over,
so the memory is fully occupied by 1 MiB with that data and
N - 1 MiB added by igt_fill_mappable(),
2) the data cleanup fires before igt_fill_mappable() completes,
so the whole memory is populated with N MiB by
igt_fill_mappable(),
3) the data cleanup is performed right after fill is done,
so only N - 1 MiB are in the GPU memory, preventing the test
from properly faulting - we'd expect no space left, but an
object was able to fit in the remaining 1 MiB.
Amend the problem by keeping the mock file open throughout the
duration of this test and calling fput() from the test itself.
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13929
Signed-off-by: Krzysztof Karas <krzysztof.karas at intel.com>
---
On DG2 platforms the memory for data allocated as a result of
opening a mock file remains occupied until the test is done
(scenario 1), but on ATSM cards the data is freed earlier
(scenarios 2 and 3), which leads to sporadic failures.
During testing I observed that the max memory was equal
to either 4096 or 2048 and igt_fill_mappable() tries to allocate
as many 1k objects as possible before halving allocation size.
v2:
* change ownership of the file used in igt_mmap_offset*
functions to the caller (Krzysztof, Sebastian);
* rename igt_mmap_offset_get_file() to
igt_mmap_offset_with_file();
v3:
* remove double fput() call (Krzysztof);
.../drm/i915/gem/selftests/i915_gem_mman.c | 11 ++++-
drivers/gpu/drm/i915/selftests/igt_mmap.c | 46 +++++++++++++------
drivers/gpu/drm/i915/selftests/igt_mmap.h | 8 ++++
3 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 9c3f17e51885..216d1d5ec2f5 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -1176,6 +1176,7 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
struct drm_i915_private *i915 = placements[0]->i915;
struct drm_i915_gem_object *obj;
struct i915_request *rq = NULL;
+ struct file *mock_file;
unsigned long addr;
LIST_HEAD(objects);
u64 offset;
@@ -1194,14 +1195,19 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
if (err)
goto out_put;
+ /* Pretend to open("/dev/dri/card0") */
+ mock_file = mock_drm_getfile(i915->drm.primary, O_RDWR);
+ if (IS_ERR(mock_file))
+ return PTR_ERR(mock_file);
+
/*
* This will eventually create a GEM context, due to opening dummy drm
* file, which needs a tiny amount of mappable device memory for the top
* level paging structures(and perhaps scratch), so make sure we
* allocate early, to avoid tears.
*/
- addr = igt_mmap_offset(i915, offset, obj->base.size,
- PROT_WRITE, MAP_SHARED);
+ addr = igt_mmap_offset_with_file(i915, offset, obj->base.size,
+ PROT_WRITE, MAP_SHARED, mock_file);
if (IS_ERR_VALUE(addr)) {
err = addr;
goto out_put;
@@ -1299,6 +1305,7 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
}
out_put:
+ fput(mock_file);
i915_gem_object_put(obj);
igt_close_objects(i915, &objects);
return err;
diff --git a/drivers/gpu/drm/i915/selftests/igt_mmap.c b/drivers/gpu/drm/i915/selftests/igt_mmap.c
index e920a461bd36..6f1b6d5cc2d3 100644
--- a/drivers/gpu/drm/i915/selftests/igt_mmap.c
+++ b/drivers/gpu/drm/i915/selftests/igt_mmap.c
@@ -9,17 +9,22 @@
#include "i915_drv.h"
#include "igt_mmap.h"
-unsigned long igt_mmap_offset(struct drm_i915_private *i915,
- u64 offset,
- unsigned long size,
- unsigned long prot,
- unsigned long flags)
+unsigned long igt_mmap_offset_with_file(struct drm_i915_private *i915,
+ u64 offset,
+ unsigned long size,
+ unsigned long prot,
+ unsigned long flags,
+ struct file *file)
{
struct drm_vma_offset_node *node;
- struct file *file;
unsigned long addr;
int err;
+ if (!file) {
+ pr_info("file cannot be NULL\n");
+ return -EINVAL;
+ }
+
/* no need to refcount, we own this object */
drm_vma_offset_lock_lookup(i915->drm.vma_offset_manager);
node = drm_vma_offset_exact_lookup_locked(i915->drm.vma_offset_manager,
@@ -31,22 +36,35 @@ unsigned long igt_mmap_offset(struct drm_i915_private *i915,
return -ENOENT;
}
- /* Pretend to open("/dev/dri/card0") */
- file = mock_drm_getfile(i915->drm.primary, O_RDWR);
- if (IS_ERR(file))
- return PTR_ERR(file);
-
err = drm_vma_node_allow(node, file->private_data);
if (err) {
- addr = err;
- goto out_file;
+ return err;
}
addr = vm_mmap(file, 0, drm_vma_node_size(node) << PAGE_SHIFT,
prot, flags, drm_vma_node_offset_addr(node));
drm_vma_node_revoke(node, file->private_data);
-out_file:
+
+ return addr;
+}
+
+unsigned long igt_mmap_offset(struct drm_i915_private *i915,
+ u64 offset,
+ unsigned long size,
+ unsigned long prot,
+ unsigned long flags)
+{
+ struct file *file;
+ unsigned long addr;
+
+ /* Pretend to open("/dev/dri/card0") */
+ file = mock_drm_getfile(i915->drm.primary, O_RDWR);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ addr = igt_mmap_offset_with_file(i915, offset, size, prot, flags, file);
fput(file);
+
return addr;
}
diff --git a/drivers/gpu/drm/i915/selftests/igt_mmap.h b/drivers/gpu/drm/i915/selftests/igt_mmap.h
index acbe34d81a6d..7b177b44cd3c 100644
--- a/drivers/gpu/drm/i915/selftests/igt_mmap.h
+++ b/drivers/gpu/drm/i915/selftests/igt_mmap.h
@@ -11,6 +11,7 @@
struct drm_i915_private;
struct drm_vma_offset_node;
+struct file;
unsigned long igt_mmap_offset(struct drm_i915_private *i915,
u64 offset,
@@ -18,4 +19,11 @@ unsigned long igt_mmap_offset(struct drm_i915_private *i915,
unsigned long prot,
unsigned long flags);
+unsigned long igt_mmap_offset_with_file(struct drm_i915_private *i915,
+ u64 offset,
+ unsigned long size,
+ unsigned long prot,
+ unsigned long flags,
+ struct file *file);
+
#endif /* IGT_MMAP_H */
--
2.43.0
More information about the Intel-gfx
mailing list