Browse Source

drm/nouveau: remove implicit mapping of every bo into chan_vm

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs 14 years ago
parent
commit
2fd3db6f14

+ 1 - 9
drivers/gpu/drm/nouveau/nouveau_bo.c

@@ -49,7 +49,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
 		DRM_ERROR("bo %p still attached to GEM object\n", bo);
 
 	nv10_mem_put_tile_region(dev, nvbo->tile, NULL);
-	nouveau_bo_vma_del(nvbo, &nvbo->vma);
 	kfree(nvbo);
 }
 
@@ -115,14 +114,6 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
 	nvbo->bo.mem.num_pages = size >> PAGE_SHIFT;
 	nouveau_bo_placement_set(nvbo, flags, 0);
 
-	if (dev_priv->chan_vm) {
-		ret = nouveau_bo_vma_add(nvbo, dev_priv->chan_vm, &nvbo->vma);
-		if (ret) {
-			kfree(nvbo);
-			return ret;
-		}
-	}
-
 	ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
 			  ttm_bo_type_device, &nvbo->placement,
 			  align >> PAGE_SHIFT, 0, false, NULL, size,
@@ -1103,6 +1094,7 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
 		nouveau_vm_map_sg(vma, 0, size, node, node->pages);
 
 	list_add_tail(&vma->head, &nvbo->vma_list);
+	vma->refcount = 1;
 	return 0;
 }
 

+ 0 - 1
drivers/gpu/drm/nouveau/nouveau_drv.h

@@ -115,7 +115,6 @@ struct nouveau_bo {
 
 	struct nouveau_channel *channel;
 
-	struct nouveau_vma vma;
 	struct list_head vma_list;
 	unsigned page_shift;
 

+ 41 - 1
drivers/gpu/drm/nouveau/nouveau_gem.c

@@ -63,20 +63,60 @@ int
 nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
 {
 	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
+	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+	struct nouveau_vma *vma;
+	int ret;
 
 	if (!fpriv->vm)
 		return 0;
 
-	return 0;
+	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+	if (ret)
+		return ret;
+
+	vma = nouveau_bo_vma_find(nvbo, fpriv->vm);
+	if (!vma) {
+		vma = kzalloc(sizeof(*vma), GFP_KERNEL);
+		if (!vma) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = nouveau_bo_vma_add(nvbo, fpriv->vm, vma);
+		if (ret) {
+			kfree(vma);
+			goto out;
+		}
+	} else {
+		vma->refcount++;
+	}
+
+out:
+	ttm_bo_unreserve(&nvbo->bo);
+	return ret;
 }
 
 void
 nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
 {
 	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
+	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+	struct nouveau_vma *vma;
+	int ret;
 
 	if (!fpriv->vm)
 		return;
+
+	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+	if (ret)
+		return;
+
+	vma = nouveau_bo_vma_find(nvbo, fpriv->vm);
+	if (vma) {
+		if (--vma->refcount == 0)
+			nouveau_bo_vma_del(nvbo, vma);
+	}
+	ttm_bo_unreserve(&nvbo->bo);
 }
 
 int

+ 1 - 0
drivers/gpu/drm/nouveau/nouveau_vm.h

@@ -42,6 +42,7 @@ struct nouveau_vm_pgd {
 
 struct nouveau_vma {
 	struct list_head head;
+	int refcount;
 	struct nouveau_vm *vm;
 	struct nouveau_mm_node *node;
 	u64 offset;