Skip to content

Commit c2ea703

Browse files
author
Thomas Hellström
committed
drm/i915: Require the vm mutex for i915_vma_bind()
Protect updates of struct i915_vma flags and async binding / unbinding with the vm::mutex. This means that i915_vma_bind() needs to assert vm::mutex held. In order to make that possible drop the caching of kmap_atomic() maps around i915_vma_bind(). An alternative would be to use kmap_local() but since we block cpu unplugging during sleeps inside kmap_local() sections this may have unwanted side-effects. Particularly since we might wait for gpu while holding the vm mutex. This change may theoretically increase execbuf cpu-usage on snb, but at least on non-highmem systems that increase should be very small. Signed-off-by: Thomas Hellström <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 63cf4ca commit c2ea703

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,47 @@ static inline struct i915_ggtt *cache_to_ggtt(struct reloc_cache *cache)
10981098
return &i915->ggtt;
10991099
}
11001100

1101+
static void reloc_cache_unmap(struct reloc_cache *cache)
1102+
{
1103+
void *vaddr;
1104+
1105+
if (!cache->vaddr)
1106+
return;
1107+
1108+
vaddr = unmask_page(cache->vaddr);
1109+
if (cache->vaddr & KMAP)
1110+
kunmap_atomic(vaddr);
1111+
else
1112+
io_mapping_unmap_atomic((void __iomem *)vaddr);
1113+
}
1114+
1115+
static void reloc_cache_remap(struct reloc_cache *cache,
1116+
struct drm_i915_gem_object *obj)
1117+
{
1118+
void *vaddr;
1119+
1120+
if (!cache->vaddr)
1121+
return;
1122+
1123+
if (cache->vaddr & KMAP) {
1124+
struct page *page = i915_gem_object_get_page(obj, cache->page);
1125+
1126+
vaddr = kmap_atomic(page);
1127+
cache->vaddr = unmask_flags(cache->vaddr) |
1128+
(unsigned long)vaddr;
1129+
} else {
1130+
struct i915_ggtt *ggtt = cache_to_ggtt(cache);
1131+
unsigned long offset;
1132+
1133+
offset = cache->node.start;
1134+
if (!drm_mm_node_allocated(&cache->node))
1135+
offset += cache->page << PAGE_SHIFT;
1136+
1137+
cache->vaddr = (unsigned long)
1138+
io_mapping_map_atomic_wc(&ggtt->iomap, offset);
1139+
}
1140+
}
1141+
11011142
static void reloc_cache_reset(struct reloc_cache *cache, struct i915_execbuffer *eb)
11021143
{
11031144
void *vaddr;
@@ -1362,10 +1403,17 @@ eb_relocate_entry(struct i915_execbuffer *eb,
13621403
* batchbuffers.
13631404
*/
13641405
if (reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
1365-
GRAPHICS_VER(eb->i915) == 6) {
1406+
GRAPHICS_VER(eb->i915) == 6 &&
1407+
!i915_vma_is_bound(target->vma, I915_VMA_GLOBAL_BIND)) {
1408+
struct i915_vma *vma = target->vma;
1409+
1410+
reloc_cache_unmap(&eb->reloc_cache);
1411+
mutex_lock(&vma->vm->mutex);
13661412
err = i915_vma_bind(target->vma,
13671413
target->vma->obj->cache_level,
13681414
PIN_GLOBAL, NULL);
1415+
mutex_unlock(&vma->vm->mutex);
1416+
reloc_cache_remap(&eb->reloc_cache, ev->vma->obj);
13691417
if (err)
13701418
return err;
13711419
}

drivers/gpu/drm/i915/i915_vma.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ int i915_vma_bind(struct i915_vma *vma,
393393
u32 bind_flags;
394394
u32 vma_flags;
395395

396+
lockdep_assert_held(&vma->vm->mutex);
396397
GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
397398
GEM_BUG_ON(vma->size > vma->node.size);
398399

0 commit comments

Comments
 (0)