aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-01-25 00:34:22 -0500
committerDave Airlie <airlied@redhat.com>2012-01-25 13:54:28 -0500
commit9f1feed2e16652a6e599ed4a73b4c501bb3d4568 (patch)
tree4df8c894d3444f277243c8e32d58eca31496f679 /drivers/gpu/drm
parent9fc04b503df9a34ec1a691225445c5b7dfd022e7 (diff)
drm/ttm: fix two regressions since move_notify changes
Both changes in dc97b3409a790d2a21aac6e5cdb99558b5944119 cause serious regressions in the nouveau driver. move_notify() was originally able to presume that bo->mem is the old node, and new_mem is the new node. The above commit moves the call to move_notify() to after move() has been done, which means that now, sometimes, new_mem isn't the new node at all, bo->mem is, and new_mem points at a stale, possibly-just-been-killed-by-move node. This is clearly not a good situation. This patch reverts this change, and replaces it with a cleanup in the move() failure path instead. The second issue is that the call to move_notify() from cleanup_memtype_use() causes the TTM ghost objects to get passed into the driver. This is clearly bad as the driver knows nothing about these "fake" TTM BOs, and ends up accessing uninitialised memory. I worked around this in nouveau's move_notify() hook by ensuring the BO destructor was nouveau's. I don't particularly like this solution, and would rather TTM never pass the driver these objects. However, I don't clearly understand the reason why we're calling move_notify() here anyway and am happy to work around the problem in nouveau instead of breaking the behaviour expected by other drivers. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Cc: Jerome Glisse <j.glisse@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c17
2 files changed, 17 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 724b41a2b9e9..ec54364ac828 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -812,6 +812,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
812 struct nouveau_bo *nvbo = nouveau_bo(bo); 812 struct nouveau_bo *nvbo = nouveau_bo(bo);
813 struct nouveau_vma *vma; 813 struct nouveau_vma *vma;
814 814
815 /* ttm can now (stupidly) pass the driver bos it didn't create... */
816 if (bo->destroy != nouveau_bo_del_ttm)
817 return;
818
815 list_for_each_entry(vma, &nvbo->vma_list, head) { 819 list_for_each_entry(vma, &nvbo->vma_list, head) {
816 if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { 820 if (new_mem && new_mem->mem_type == TTM_PL_VRAM) {
817 nouveau_vm_map(vma, new_mem->mm_node); 821 nouveau_vm_map(vma, new_mem->mm_node);
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 2f0eab66ece6..7c3a57de8187 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -404,6 +404,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
404 } 404 }
405 } 405 }
406 406
407 if (bdev->driver->move_notify)
408 bdev->driver->move_notify(bo, mem);
409
407 if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && 410 if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
408 !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) 411 !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
409 ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); 412 ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem);
@@ -413,11 +416,17 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
413 else 416 else
414 ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); 417 ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem);
415 418
416 if (ret) 419 if (ret) {
417 goto out_err; 420 if (bdev->driver->move_notify) {
421 struct ttm_mem_reg tmp_mem = *mem;
422 *mem = bo->mem;
423 bo->mem = tmp_mem;
424 bdev->driver->move_notify(bo, mem);
425 bo->mem = *mem;
426 }
418 427
419 if (bdev->driver->move_notify) 428 goto out_err;
420 bdev->driver->move_notify(bo, mem); 429 }
421 430
422moved: 431moved:
423 if (bo->evicted) { 432 if (bo->evicted) {