mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 10:11:38 -04:00
drm/i915/selftests: Keep mock file open during unfaultable migrate with fill
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 GEM objects for
page table structures and scratch in GPU mappable memory.
Then, also in igt_mmap_offset(), the file is closed (fput) and
the cleanup of these objects is scheduled on a delayed worqueue,
which is designed to execute after unspecified amount of time.
Next, the test calls igt_fill_mappable() to fill mappable GPU
memory. At this point, three scenarios are possible
(N = max size of GPU memory for this test in MiB):
1) the objects allocated for the mock file get cleaned up after
crucial part of the test is over, so the memory is full with
the 1 MiB they occupy and N - 1 MiB added by
igt_fill_mappable(), so the migration fails properly;
2) the object cleanup fires before igt_fill_mappable()
completes, so the whole memory is populated with N MiB from
igt_fill_mappable(), so migration fails as well;
3) the object cleanup is performed right after fill is done,
so only N - 1 MiB are in the mappable portion of GPU memory,
allowing the migration to succeed - we'd expect no space
left to perform migration, but an object was able to fit in
the remaining 1 MiB, which caused get_user() to succeed, so
a page fault did not fail.
The test incorrectly assumes that the GPU mappable memory state
is unchanging during the test. Amend this by keeping the mock
file open until migration and page fault checking is complete.
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13929
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Sebastian Brzezinka <sebastian.brzezinka@intel.com>
Acked-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://lore.kernel.org/r/6xc74s3mbmtliqxihtxbok32jobhc26vfm5mu6cod4ywov6utf@ujp3rmqcwmr3
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
This commit is contained in:
committed by
Andi Shyti
parent
9512d9fc2a
commit
8103ecc199
@@ -1157,6 +1157,7 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_request *rq = NULL;
|
||||
struct vm_area_struct *area;
|
||||
struct file *mock_file;
|
||||
unsigned long addr;
|
||||
LIST_HEAD(objects);
|
||||
u64 offset;
|
||||
@@ -1176,16 +1177,25 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
|
||||
goto out_put;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Pretend to open("/dev/dri/card0"), which will eventually create a GEM
|
||||
* context along with multiple GEM objects (for paging structures and
|
||||
* scratch) that are placed in mappable portion of GPU memory.
|
||||
* Calling fput() on the file places objects' cleanup routines in delayed
|
||||
* worqueues, which execute after unspecified amount of time.
|
||||
* Keep the file open until migration and page fault checks are done to
|
||||
* make sure object cleanup is not executed after igt_fill_mappable()
|
||||
* finishes and before migration is attempted - that would leave a gap
|
||||
* large enough for the migration to succeed, when we'd expect it to fail.
|
||||
*/
|
||||
addr = igt_mmap_offset(i915, offset, obj->base.size,
|
||||
PROT_WRITE, MAP_SHARED);
|
||||
mock_file = mock_drm_getfile(i915->drm.primary, O_RDWR);
|
||||
if (IS_ERR(mock_file))
|
||||
return PTR_ERR(mock_file);
|
||||
|
||||
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;
|
||||
goto out_fput;
|
||||
}
|
||||
|
||||
mmap_read_lock(current->mm);
|
||||
@@ -1292,6 +1302,9 @@ static int __igt_mmap_migrate(struct intel_memory_region **placements,
|
||||
out_addr:
|
||||
vm_munmap(addr, obj->base.size);
|
||||
|
||||
out_fput:
|
||||
fput(mock_file);
|
||||
|
||||
out_put:
|
||||
i915_gem_object_put(obj);
|
||||
igt_close_objects(i915, &objects);
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
#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;
|
||||
|
||||
@@ -31,22 +31,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:
|
||||
fput(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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user