diff options
author | Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 2009-03-19 09:59:02 +0100 |
---|---|---|
committer | Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 2009-03-19 10:08:02 +0100 |
commit | 145c81299dfe46ad2e68f219268c4096092700f6 (patch) | |
tree | b7fb5086207db1e1ecaed21aed1fa8afee24af0a | |
parent | 649b5f84710cc2da0e51870a9e5749a1ba47a3d3 (diff) |
ttm: Fix buffer object transfer.
Fix destruction and initalization of "ghost" buffer objects
that are created on pipelined buffer moves.
Reported and suggestions by Jerome Glisse.
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
-rw-r--r-- | linux-core/ttm/ttm_bo_util.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/linux-core/ttm/ttm_bo_util.c b/linux-core/ttm/ttm_bo_util.c index 2235a4c4..598c2b92 100644 --- a/linux-core/ttm/ttm_bo_util.c +++ b/linux-core/ttm/ttm_bo_util.c @@ -253,6 +253,11 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, return ret; } +static void ttm_transfered_destroy(struct ttm_buffer_object *bo) +{ + kfree(bo); +} + /** * ttm_buffer_object_transfer * @@ -286,12 +291,14 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, init_waitqueue_head(&fbo->event_queue); INIT_LIST_HEAD(&fbo->ddestroy); INIT_LIST_HEAD(&fbo->lru); + INIT_LIST_HEAD(&fbo->swap); fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); if (fbo->mem.mm_node) fbo->mem.mm_node->private = (void *)fbo; kref_init(&fbo->list_kref); kref_init(&fbo->kref); + fbo->destroy = &ttm_transfered_destroy; mutex_unlock(&fbo->mutex); @@ -489,7 +496,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, int ret; uint32_t save_flags = old_mem->flags; uint32_t save_proposed_flags = old_mem->proposed_flags; - struct ttm_buffer_object * old_obj; + struct ttm_buffer_object *ghost_obj; if (bo->sync_obj) driver->sync_obj_unref(&bo->sync_obj); bo->sync_obj = driver->sync_obj_ref(sync_obj); @@ -503,22 +510,32 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, ttm_tt_unbind(bo->ttm); ttm_tt_destroy(bo->ttm); bo->ttm = NULL; } } else { - - /* This should help pipeline ordinary buffer moves. + /** + * This should help pipeline ordinary buffer moves. * * Hang old buffer memory on a new buffer object, * and leave it to be released when the GPU * operation has completed. */ - ret = ttm_buffer_object_transfer(bo, &old_obj); + + ret = ttm_buffer_object_transfer(bo, &ghost_obj); if (ret) return ret; + + /** + * If we're not moving to fixed memory, the TTM object + * needs to stay alive. Otherwhise hang it on the ghost + * bo to be unbound and destroyed. + */ + if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED)) - old_obj->ttm = NULL; + ghost_obj->ttm = NULL; else - bo->ttm = NULL; + ghost_obj = NULL; + bo->priv_flags |= TTM_BO_PRIV_FLAG_MOVING; - ttm_bo_unreserve(old_obj); + ttm_bo_unreserve(ghost_obj); + ttm_bo_unref(&ghost_obj); } *old_mem = *new_mem; |