On Tue, 2009-04-21 at 14:42 +0200, Thomas Hellstrom wrote:
> Jerome Glisse wrote:
> > Hi Thomas,
> >
> > I am not sure of the correct solution for moving a bo from
> > VRAM to SYSTEM when you need to go through TT, here are
> > solution i thought of and why they are wrong:
> >
> > (in driver callback move i get bo & newmem with bo being
> > in vram and newmem being SYSTEM)
> >
> > 1) ttm_bo_move_buffer(bo, TT, ...);
> > 2) move_null(bo, new_mem);
> >
> > Problem:
> > 1) Will find space in tt and create a new node it will
> > then call handle move mem which will allocate pages
> > & bind to tt and callback into the driver move which
> > will emit blit to do the actual copy
> > It will also create a ghost object for holding the
> > vram node until blit is done.
> > 2) According to openchrome implementation i should bug
> > if old_mem->mm_node != NULL which is at this point
> > the case as mm_node is now a node of tt allocated
> > memory and i can't free this node as i need to
> > wait for the blit to finish
> >
> >
> > 1) ttm_bo_move_buffer(bo, TT, ...);
> > 2) ttm_bo_move_accel_cleanup(bo, ?syncobj?, new_mem);
> >
> > I think it's the right solution so there is 2 ghost
> > object created but i am wondering if i have right
> > to do it.
> > 1) create ghost holding vram node
> > 2) will create another ghost holding the tt node
> > but the sync obj i provide should be the same
> > as for the ghost of 1. I could know the syncobj
> > and use it but does it sounds like what i want
> > to do ?
> >
> > Cheers,
> > Jerome
> >
> >
> Jerome,
>
> Below is what Moorestown/Poulsbo does for the same thing.
> However, the Moorestown / Poulsbo MMU can deal with cached page table
> entries,
> so depending on whether or not the Radeon can do that, you might want to
> adjust
> tmp_mem.caching flags.
> The ttm_bo_handle_move_mem function may also need some patching to avoid
> calling
> ttm_tt_set_placement_caching for the new ttm, and instead let the driver
> move code do that.
>
> static int psb_move_blit(struct ttm_buffer_object *bo,
> bool evict, bool no_wait,
> struct ttm_mem_reg *new_mem)
> {
> struct drm_psb_private *dev_priv =
> container_of(bo->bdev, struct drm_psb_private, bdev);
> struct drm_device *dev = dev_priv->dev;
> struct ttm_mem_reg *old_mem = &bo->mem;
> struct ttm_fence_object *fence;
> int dir = 0;
> int ret;
>
> if ((old_mem->mem_type == new_mem->mem_type) &&
> (new_mem->mm_node->start <
> old_mem->mm_node->start + old_mem->mm_node->size)) {
> dir = 1;
> }
>
> psb_emit_2d_copy_blit(dev,
> old_mem->mm_node->start << PAGE_SHIFT,
> new_mem->mm_node->start << PAGE_SHIFT,
> new_mem->num_pages, dir);
>
> ret = ttm_fence_object_create(&dev_priv->fdev, 0,
> _PSB_FENCE_TYPE_EXE,
> TTM_FENCE_FLAG_EMIT,
> &fence);
> if (unlikely(ret != 0)) {
> psb_idle_2d(dev);
> if (fence)
> ttm_fence_object_unref(&fence);
> }
>
> ret = ttm_bo_move_accel_cleanup(bo, (void *) fence,
> (void *) (unsigned long)
> _PSB_FENCE_TYPE_EXE,
> evict, no_wait, new_mem);
> if (fence)
> ttm_fence_object_unref(&fence);
> return ret;
> }
>
> /*
> * Flip destination ttm into GATT,
> * then blit and subsequently move out again.
> */
>
> static int psb_move_flip(struct ttm_buffer_object *bo,
> bool evict, bool interruptible, bool no_wait,
> struct ttm_mem_reg *new_mem)
> {
> struct ttm_bo_device *bdev = bo->bdev;
> struct ttm_mem_reg tmp_mem;
> int ret;
>
> tmp_mem = *new_mem;
> tmp_mem.mm_node = NULL;
> tmp_mem.proposed_flags = TTM_PL_FLAG_TT;
>
> ret = ttm_bo_mem_space(bo, &tmp_mem, interruptible, no_wait);
> if (ret)
> return ret;
> ret = ttm_tt_bind(bo->ttm, &tmp_mem);
> if (ret)
> goto out_cleanup;
> ret = psb_move_blit(bo, true, no_wait, &tmp_mem);
> if (ret)
> goto out_cleanup;
>
> ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem);
> out_cleanup:
> if (tmp_mem.mm_node) {
> spin_lock(&bdev->lru_lock);
> drm_mm_put_block(tmp_mem.mm_node);
> tmp_mem.mm_node = NULL;
> spin_unlock(&bdev->lru_lock);
> }
> return ret;
> }
>
>
Shouldn't out_cleanup only happen on error so
we don't put block tt otherwise next operation
might alloc this tt while move is not yet
done. Or is tmp_mem.mm_node set to null somewhere
in ttm ?
Also strangely i am getting a vram object with
mm_node = NULL in driver callback function.
Cheers,
Jerome
------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today.
Use priority code J9JMT32. http://p.sf.net/sfu/p
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel