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

Reply via email to