summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-02-10 11:22:12 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-02-25 06:45:49 +1000
commit3425df486ca247d9e8487be06a6cd0763ba38180 (patch)
tree2ab19a81f85693d0630fd79133ad1149d3e26444
parenta4154bbffdc9f6a38556ea9e82aef4975018ba23 (diff)
drm/nv50-nvc0: unmap buffers from the vm when they're evicted
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c36
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c6
3 files changed, 36 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index d7a9e80a7c7..4e74957ef2c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -508,10 +508,12 @@ nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
int ret;
src_offset = old_mem->start << PAGE_SHIFT;
- if (old_mem->mem_type == TTM_PL_VRAM)
- src_offset = nvbo->vma.offset;
- else
+ if (old_mem->mem_type == TTM_PL_VRAM) {
+ struct nouveau_vram *node = old_mem->mm_node;
+ src_offset = node->tmp_vma.offset;
+ } else {
src_offset += dev_priv->gart_info.aper_base;
+ }
dst_offset = new_mem->start << PAGE_SHIFT;
if (new_mem->mem_type == TTM_PL_VRAM)
@@ -559,10 +561,12 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
int ret;
src_offset = old_mem->start << PAGE_SHIFT;
- if (old_mem->mem_type == TTM_PL_VRAM)
- src_offset = nvbo->vma.offset;
- else
+ if (old_mem->mem_type == TTM_PL_VRAM) {
+ struct nouveau_vram *node = old_mem->mm_node;
+ src_offset = node->tmp_vma.offset;
+ } else {
src_offset += dev_priv->gart_info.aper_base;
+ }
dst_offset = new_mem->start << PAGE_SHIFT;
if (new_mem->mem_type == TTM_PL_VRAM)
@@ -711,6 +715,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
+ struct ttm_mem_reg *old_mem = &bo->mem;
struct nouveau_channel *chan;
int ret;
@@ -720,6 +725,21 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
}
+ /* create temporary vma for old memory, this will get cleaned
+ * up after ttm destroys the ttm_mem_reg
+ */
+ if (dev_priv->card_type >= NV_50 && old_mem->mem_type == TTM_PL_VRAM) {
+ struct nouveau_vram *node = old_mem->mm_node;
+
+ ret = nouveau_vm_get(chan->vm, old_mem->num_pages << PAGE_SHIFT,
+ nvbo->vma.node->type, NV_MEM_ACCESS_RO,
+ &node->tmp_vma);
+ if (ret)
+ goto out;
+
+ nouveau_vm_map(&node->tmp_vma, node);
+ }
+
if (dev_priv->card_type < NV_50)
ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
else
@@ -733,6 +753,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
no_wait_gpu, new_mem);
}
+out:
if (chan == dev_priv->channel)
mutex_unlock(&chan->mutex);
return ret;
@@ -811,7 +832,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
- if (dev_priv->card_type < NV_50 || nvbo->no_vm)
+ if (dev_priv->card_type < NV_50)
return;
switch (new_mem->mem_type) {
@@ -820,6 +841,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
break;
case TTM_PL_TT:
default:
+ nouveau_vm_unmap(&nvbo->vma);
break;
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index d409c0dc425..45609ee447b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -69,6 +69,7 @@ struct nouveau_vram {
struct drm_device *dev;
struct nouveau_vma bar_vma;
+ struct nouveau_vma tmp_vma;
u8 page_shift;
struct list_head regions;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 16eee50a057..b90383fd18f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -710,8 +710,14 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
+ struct nouveau_vram *node = mem->mm_node;
struct drm_device *dev = dev_priv->dev;
+ if (node->tmp_vma.node) {
+ nouveau_vm_unmap(&node->tmp_vma);
+ nouveau_vm_put(&node->tmp_vma);
+ }
+
vram->put(dev, (struct nouveau_vram **)&mem->mm_node);
}