[PATCH] drm/i915: Make sure we always have the vm mutex held when calling i915_vma_bind
Thomas Hellström
thomas.hellstrom at linux.intel.com
Fri Nov 12 09:22:11 UTC 2021
In order to avoid special-casing for the async vma work we would like to
be able to assert that the vm mutex is always held when calling
i915_vma_bind.
This is complicated by the fact that we call i915_vma_bind from atomic
context in eb_relocate_entry, and at that point we're in atomic context
because we cache a kmap_atomic().
Replace kmap_atomic() and the io_mapping_map_atomic_wc with their
s/atomic/local/ counterparts and take the vm mutex around the call to
i915_vma_bind. When doing this also add a pagefault_disable() around the
__put_user in the relocation code since it will otherwise typically not
be called with pagefaults disabled anymore, which may trigger a deadlock
in certain situations.
Finally assert vm mutex held in i915_vma_bind.
Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
---
.../gpu/drm/i915/gem/i915_gem_execbuffer.c | 26 ++++++++++++-------
drivers/gpu/drm/i915/i915_vma.c | 2 ++
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index ea5b7b2a4d70..cc0d8b1f65dc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1117,13 +1117,13 @@ static void reloc_cache_reset(struct reloc_cache *cache, struct i915_execbuffer
if (cache->vaddr & CLFLUSH_AFTER)
mb();
- kunmap_atomic(vaddr);
+ kunmap_local(vaddr);
i915_gem_object_finish_access(obj);
} else {
struct i915_ggtt *ggtt = cache_to_ggtt(cache);
intel_gt_flush_ggtt_writes(ggtt->vm.gt);
- io_mapping_unmap_atomic((void __iomem *)vaddr);
+ io_mapping_unmap_local((void __iomem *)vaddr);
if (drm_mm_node_allocated(&cache->node)) {
ggtt->vm.clear_range(&ggtt->vm,
@@ -1149,7 +1149,7 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
struct page *page;
if (cache->vaddr) {
- kunmap_atomic(unmask_page(cache->vaddr));
+ kunmap_local(unmask_page(cache->vaddr));
} else {
unsigned int flushes;
int err;
@@ -1171,7 +1171,7 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
if (!obj->mm.dirty)
set_page_dirty(page);
- vaddr = kmap_atomic(page);
+ vaddr = kmap_local_page(page);
cache->vaddr = unmask_flags(cache->vaddr) | (unsigned long)vaddr;
cache->page = pageno;
@@ -1189,7 +1189,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
if (cache->vaddr) {
intel_gt_flush_ggtt_writes(ggtt->vm.gt);
- io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
+ io_mapping_unmap_local((void __force __iomem *)unmask_page(cache->vaddr));
} else {
struct i915_vma *vma;
int err;
@@ -1237,8 +1237,8 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
offset += page << PAGE_SHIFT;
}
- vaddr = (void __force *)io_mapping_map_atomic_wc(&ggtt->iomap,
- offset);
+ vaddr = (void __force *)io_mapping_map_local_wc(&ggtt->iomap,
+ offset);
cache->page = page;
cache->vaddr = (unsigned long)vaddr;
@@ -1368,9 +1368,15 @@ eb_relocate_entry(struct i915_execbuffer *eb,
*/
if (reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
GRAPHICS_VER(eb->i915) == 6) {
- err = i915_vma_bind(target->vma,
- target->vma->obj->cache_level,
+ struct i915_vma *vma = target->vma;
+
+ err = mutex_lock_interruptible(&vma->vm->mutex);
+ if (err)
+ return err;
+ err = i915_vma_bind(vma,
+ vma->obj->cache_level,
PIN_GLOBAL, NULL);
+ mutex_unlock(&vma->vm->mutex);
if (err)
return err;
}
@@ -1489,8 +1495,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct eb_vma *ev)
* can read from this userspace address.
*/
offset = gen8_canonical_addr(offset & ~UPDATE);
+ pagefault_disable();
__put_user(offset,
&urelocs[r - stack].presumed_offset);
+ pagefault_enable();
}
} while (r++, --count);
urelocs += ARRAY_SIZE(stack);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 8781c4f61952..2f3ce02d1242 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -376,6 +376,8 @@ int i915_vma_bind(struct i915_vma *vma,
u32 bind_flags;
u32 vma_flags;
+ lockdep_assert_held(&vma->vm->mutex);
+
GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
GEM_BUG_ON(vma->size > vma->node.size);
--
2.31.1
More information about the Intel-gfx-trybot
mailing list