IGT mmap testing in i915 uses current task's address space to allocate new userspace mapping, without registering real user for that address space in mm_struct.
It was observed that mm->mm_users would occasionally drop to 0 during tests, which reaped userspace mappings, further leading to failures upon reading from userland memory. Prevent this by artificially increasing mm_users counter for the duration of the test. Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14204 Signed-off-by: Krzysztof Karas <[email protected]> --- During testing I also found out that this problem affects another function, __igt_mmap(), which also utilizes userspace VMAs. v2: * use mmget/mmput() (Jani); * include __igt_mmap() in the scope; * change comments and commit message; .../drm/i915/gem/selftests/i915_gem_mman.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) 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 0d250d57496a..82ab090f66c8 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -916,6 +916,13 @@ static int __igt_mmap(struct drm_i915_private *i915, if (err) return err; + /* + * Get a reference to tasks's mm_struct to artificially increase mm_users + * and ensure the kernel does not try to clean up the userspace mappings + * of the current task during the test. + */ + mmget_not_zero(current->mm); + addr = igt_mmap_offset(i915, offset, obj->base.size, PROT_WRITE, MAP_SHARED); if (IS_ERR_VALUE(addr)) return addr; @@ -968,6 +975,11 @@ static int __igt_mmap(struct drm_i915_private *i915, err = gtt_check(obj); out_unmap: vm_munmap(addr, obj->base.size); + /* + * mmput() is not supposed to be called on task's own + * mm_struct, so let kernel handle that. + */ + mmput_async(current->mm); return err; } @@ -1177,6 +1189,13 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements, if (err) goto out_put; + /* + * Get a reference to tasks's mm_struct to artificially increase mm_users + * and ensure the kernel does not try to clean up the userspace mappings + * of the current task during the test. + */ + mmget_not_zero(current->mm); + /* * 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 @@ -1293,6 +1312,11 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements, out_addr: vm_munmap(addr, obj->base.size); + /* + * mmput() is not supposed to be called on task's own + * mm_struct, so let kernel handle that. + */ + mmput_async(current->mm); out_put: i915_gem_object_put(obj); -- 2.43.0 -- Best Regards, Krzysztof
