Jerome Glisse wrote:
> 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 ?
>
>   
Jerome,
This is actually a synchronous operation which is indicated by the 
"true" argument to the evict parameter in psb_move_blit, so at 
out_cleanup the move is already idle.
This is where we hit the limitation of the current move code, since the 
last ttm_bo_move_ttm must wait for idle.

To make this fully asynchronous there are changes needed to the move 
code, as we've discussed previously.
In particular, I think we need to put a sync object on each memtype 
manager, and that sync object needs to be waited for when accessing a 
memory region with a new engine or the CPU. So a move will actually

    * Schedule the move
    * Put a sync object on the manager.
    * Free its memory region
    * Schedule move cleanup.

> Also strangely i am getting a vram object with
> mm_node = NULL in driver callback function.
>   

That sounds odd. When do these objects appear?
/Thomas

> 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