OSDN Git Service

drm/nouveau: remove implicit mapping of every bo into chan_vm
authorBen Skeggs <bskeggs@redhat.com>
Tue, 7 Jun 2011 05:25:12 +0000 (15:25 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 23 Jun 2011 06:00:42 +0000 (16:00 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_vm.h

index 49af407..890d50e 100644 (file)
@@ -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;
 }
 
index bdb682d..bbea045 100644 (file)
@@ -115,7 +115,6 @@ struct nouveau_bo {
 
        struct nouveau_channel *channel;
 
-       struct nouveau_vma vma;
        struct list_head vma_list;
        unsigned page_shift;
 
index 3e1c701..0223937 100644 (file)
@@ -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
index 07d07ff..579ca8c 100644 (file)
@@ -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;