summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_gem.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-05-07 09:48:30 +1000
committerBen Skeggs <bskeggs@redhat.com>2013-07-01 13:50:31 +1000
commitc4c7044ffc1ba973e2ec0f0dc94980b49101d877 (patch)
tree936ddc8e8ae3b940079e5577a4ad947a90d58343 /drivers/gpu/drm/nouveau/nouveau_gem.c
parent780194b1b9f5fdbaa06dd71e60b31ceaaedafbe4 (diff)
downloadop-kernel-dev-c4c7044ffc1ba973e2ec0f0dc94980b49101d877.zip
op-kernel-dev-c4c7044ffc1ba973e2ec0f0dc94980b49101d877.tar.gz
drm/nouveau: delay busy bo vma removal until fence signals
As opposed to an explicit wait. Allows userspace to not stall waiting on buffer deletion. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_gem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index b4b4d0c..c0e324b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -101,6 +101,41 @@ out:
return ret;
}
+static void
+nouveau_gem_object_delete(void *data)
+{
+ struct nouveau_vma *vma = data;
+ nouveau_vm_unmap(vma);
+ nouveau_vm_put(vma);
+ kfree(vma);
+}
+
+static void
+nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
+{
+ const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM;
+ struct nouveau_fence *fence = NULL;
+
+ list_del(&vma->head);
+
+ if (mapped) {
+ spin_lock(&nvbo->bo.bdev->fence_lock);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ spin_unlock(&nvbo->bo.bdev->fence_lock);
+ }
+
+ if (fence) {
+ nouveau_fence_work(fence, nouveau_gem_object_delete, vma);
+ } else {
+ if (mapped)
+ nouveau_vm_unmap(vma);
+ nouveau_vm_put(vma);
+ kfree(vma);
+ }
+ nouveau_fence_unref(&fence);
+}
+
void
nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
@@ -118,10 +153,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
if (vma) {
- if (--vma->refcount == 0) {
- nouveau_bo_vma_del(nvbo, vma);
- kfree(vma);
- }
+ if (--vma->refcount == 0)
+ nouveau_gem_object_unmap(nvbo, vma);
}
ttm_bo_unreserve(&nvbo->bo);
}
OpenPOWER on IntegriCloud