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.ka...@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. .../drm/i915/gem/selftests/i915_gem_mman.c | 11 ++++- drivers/gpu/drm/i915/selftests/igt_mmap.c | 47 +++++++++++++------ drivers/gpu/drm/i915/selftests/igt_mmap.h | 8 ++++ 3 files changed, 50 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..ebe2c1933f03 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,36 @@ 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; + fput(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