Commit 17eee668 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-fixes-2019-11-20' of...

Merge tag 'drm-misc-next-fixes-2019-11-20' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

- Fix ttm bo refcnt when using the new gem obj mmap hook (Thomas)

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20191120204946.GA120328@art_vandelay
parents 30c185da 9786b65b
...@@ -1105,21 +1105,33 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ...@@ -1105,21 +1105,33 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
if (obj_size < vma->vm_end - vma->vm_start) if (obj_size < vma->vm_end - vma->vm_start)
return -EINVAL; return -EINVAL;
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
* This reference is cleaned up by the corresponding vm_close
* (which should happen whether the vma was created by this call, or
* by a vm_open due to mremap or partial unmap or whatever).
*/
drm_gem_object_get(obj);
if (obj->funcs && obj->funcs->mmap) { if (obj->funcs && obj->funcs->mmap) {
/* Remove the fake offset */ /* Remove the fake offset */
vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
ret = obj->funcs->mmap(obj, vma); ret = obj->funcs->mmap(obj, vma);
if (ret) if (ret) {
drm_gem_object_put_unlocked(obj);
return ret; return ret;
}
WARN_ON(!(vma->vm_flags & VM_DONTEXPAND)); WARN_ON(!(vma->vm_flags & VM_DONTEXPAND));
} else { } else {
if (obj->funcs && obj->funcs->vm_ops) if (obj->funcs && obj->funcs->vm_ops)
vma->vm_ops = obj->funcs->vm_ops; vma->vm_ops = obj->funcs->vm_ops;
else if (dev->driver->gem_vm_ops) else if (dev->driver->gem_vm_ops)
vma->vm_ops = dev->driver->gem_vm_ops; vma->vm_ops = dev->driver->gem_vm_ops;
else else {
drm_gem_object_put_unlocked(obj);
return -EINVAL; return -EINVAL;
}
vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
...@@ -1128,14 +1140,6 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ...@@ -1128,14 +1140,6 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
vma->vm_private_data = obj; vma->vm_private_data = obj;
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
* This reference is cleaned up by the corresponding vm_close
* (which should happen whether the vma was created by this call, or
* by a vm_open due to mremap or partial unmap or whatever).
*/
drm_gem_object_get(obj);
return 0; return 0;
} }
EXPORT_SYMBOL(drm_gem_mmap_obj); EXPORT_SYMBOL(drm_gem_mmap_obj);
......
...@@ -64,8 +64,19 @@ int drm_gem_ttm_mmap(struct drm_gem_object *gem, ...@@ -64,8 +64,19 @@ int drm_gem_ttm_mmap(struct drm_gem_object *gem,
struct vm_area_struct *vma) struct vm_area_struct *vma)
{ {
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem); struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
int ret;
return ttm_bo_mmap_obj(vma, bo); ret = ttm_bo_mmap_obj(vma, bo);
if (ret < 0)
return ret;
/*
* ttm has its own object refcounting, so drop gem reference
* to avoid double accounting counting.
*/
drm_gem_object_put_unlocked(gem);
return 0;
} }
EXPORT_SYMBOL(drm_gem_ttm_mmap); EXPORT_SYMBOL(drm_gem_ttm_mmap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment