[PATCH 1/2] drm/ttm: add a way to bo_wait for either the last read or last write
Jerome Glisse
j.glisse at gmail.com
Fri Aug 12 10:21:45 PDT 2011
On Sun, Aug 7, 2011 at 4:39 PM, Marek Olšák <maraeo at gmail.com> wrote:
> Sometimes we want to know whether a buffer is busy and wait for it (bo_wait).
> However, sometimes it would be more useful to be able to query whether
> a buffer is busy and being either read or written, and wait until it's stopped
> being either read or written. The point of this is to be able to avoid
> unnecessary waiting, e.g. if a GPU has written something to a buffer and is now
> reading that buffer, and a CPU wants to map that buffer for read, it needs to
> only wait for the last write. If there were no write, there wouldn't be any
> waiting needed.
>
> This, or course, requires user space drivers to send read/write flags
> with each relocation (like we have read/write domains in radeon, so we can
> actually use those for something useful now).
>
> Now how this patch works:
>
> The read/write flags should passed to ttm_validate_buffer. TTM maintains
> separate sync objects of the last read and write for each buffer, in addition
> to the sync object of the last use of a buffer. ttm_bo_wait then operates
> with one the sync objects.
Just minor comment for extra safety see below, otherwise:
Reviewed-by: Jerome Glisse <jglisse at redhat.com>
> Signed-off-by: Marek Olšák <maraeo at gmail.com>
> ---
> drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +-
> drivers/gpu/drm/nouveau/nouveau_gem.c | 5 +-
> drivers/gpu/drm/radeon/radeon_cs.c | 1 +
> drivers/gpu/drm/radeon/radeon_object.h | 2 +-
> drivers/gpu/drm/ttm/ttm_bo.c | 97 ++++++++++++++++++++++--------
> drivers/gpu/drm/ttm/ttm_bo_util.c | 26 +++++++--
> drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 +-
> drivers/gpu/drm/ttm/ttm_execbuf_util.c | 17 +++++-
> drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 1 +
> include/drm/ttm/ttm_bo_api.h | 16 +++++-
> include/drm/ttm/ttm_execbuf_util.h | 6 ++
> 11 files changed, 137 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
> index 890d50e..e87e24b 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
> @@ -1104,7 +1104,8 @@ nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
> if (vma->node) {
> if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) {
> spin_lock(&nvbo->bo.bdev->fence_lock);
> - ttm_bo_wait(&nvbo->bo, false, false, false);
> + ttm_bo_wait(&nvbo->bo, false, false, false,
> + TTM_USAGE_READWRITE);
> spin_unlock(&nvbo->bo.bdev->fence_lock);
> nouveau_vm_unmap(vma);
> }
> diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
> index 5f0bc57..322bf62 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
> @@ -589,7 +589,8 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
> }
>
> spin_lock(&nvbo->bo.bdev->fence_lock);
> - ret = ttm_bo_wait(&nvbo->bo, false, false, false);
> + ret = ttm_bo_wait(&nvbo->bo, false, false, false,
> + TTM_USAGE_READWRITE);
> spin_unlock(&nvbo->bo.bdev->fence_lock);
> if (ret) {
> NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret);
> @@ -825,7 +826,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
> nvbo = nouveau_gem_object(gem);
>
> spin_lock(&nvbo->bo.bdev->fence_lock);
> - ret = ttm_bo_wait(&nvbo->bo, true, true, no_wait);
> + ret = ttm_bo_wait(&nvbo->bo, true, true, no_wait, TTM_USAGE_READWRITE);
> spin_unlock(&nvbo->bo.bdev->fence_lock);
> drm_gem_object_unreference_unlocked(gem);
> return ret;
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
> index fae00c0..14e8531 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -80,6 +80,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
> p->relocs[i].lobj.wdomain = r->write_domain;
> p->relocs[i].lobj.rdomain = r->read_domains;
> p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo;
> + p->relocs[i].lobj.tv.usage = TTM_USAGE_READWRITE;
> p->relocs[i].handle = r->handle;
> p->relocs[i].flags = r->flags;
> radeon_bo_list_add_object(&p->relocs[i].lobj,
> diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
> index ede6c13..e9dc8b2 100644
> --- a/drivers/gpu/drm/radeon/radeon_object.h
> +++ b/drivers/gpu/drm/radeon/radeon_object.h
> @@ -130,7 +130,7 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
> if (mem_type)
> *mem_type = bo->tbo.mem.mem_type;
> if (bo->tbo.sync_obj)
> - r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
> + r = ttm_bo_wait(&bo->tbo, true, true, no_wait, TTM_USAGE_READWRITE);
> spin_unlock(&bo->tbo.bdev->fence_lock);
> ttm_bo_unreserve(&bo->tbo);
> return r;
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 56619f6..bb8c86d 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -494,7 +494,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
> int ret;
>
> spin_lock(&bdev->fence_lock);
> - (void) ttm_bo_wait(bo, false, false, true);
> + (void) ttm_bo_wait(bo, false, false, true, TTM_USAGE_READWRITE);
> if (!bo->sync_obj) {
>
> spin_lock(&glob->lru_lock);
> @@ -562,7 +562,8 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
>
> retry:
> spin_lock(&bdev->fence_lock);
> - ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
> + ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu,
> + TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
>
> if (unlikely(ret != 0))
> @@ -721,7 +722,8 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
> int ret = 0;
>
> spin_lock(&bdev->fence_lock);
> - ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
> + ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu,
> + TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
>
> if (unlikely(ret != 0)) {
> @@ -1068,7 +1070,8 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
> * instead of doing it here.
> */
> spin_lock(&bdev->fence_lock);
> - ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
> + ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu,
> + TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
> if (ret)
> return ret;
> @@ -1688,34 +1691,83 @@ out_unlock:
> return ret;
> }
>
> +static void ttm_bo_unref_sync_obj_locked(struct ttm_buffer_object *bo,
> + void *sync_obj,
> + void **extra_sync_obj)
> +{
> + struct ttm_bo_device *bdev = bo->bdev;
> + struct ttm_bo_driver *driver = bdev->driver;
> + void *tmp_obj = NULL, *tmp_obj_read = NULL, *tmp_obj_write = NULL;
> +
> + /* We must unref the sync obj wherever it's ref'd.
> + * Note that if we unref bo->sync_obj, we can unref both the read
> + * and write sync objs too, because they can't be newer than
> + * bo->sync_obj, so they are no longer relevant. */
> + if (sync_obj == bo->sync_obj ||
> + sync_obj == bo->sync_obj_read) {
> + tmp_obj_read = bo->sync_obj_read;
> + bo->sync_obj_read = NULL;
> + }
> + if (sync_obj == bo->sync_obj ||
> + sync_obj == bo->sync_obj_write) {
> + tmp_obj_write = bo->sync_obj_write;
> + bo->sync_obj_write = NULL;
> + }
> + if (sync_obj == bo->sync_obj) {
> + tmp_obj = bo->sync_obj;
> + bo->sync_obj = NULL;
> + }
> +
> + clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
> + spin_unlock(&bdev->fence_lock);
> + if (tmp_obj)
> + driver->sync_obj_unref(&tmp_obj);
> + if (tmp_obj_read)
> + driver->sync_obj_unref(&tmp_obj_read);
> + if (tmp_obj_write)
> + driver->sync_obj_unref(&tmp_obj_write);
> + if (extra_sync_obj)
> + driver->sync_obj_unref(extra_sync_obj);
> + spin_lock(&bdev->fence_lock);
> +}
> +
> int ttm_bo_wait(struct ttm_buffer_object *bo,
> - bool lazy, bool interruptible, bool no_wait)
> + bool lazy, bool interruptible, bool no_wait,
> + enum ttm_buffer_usage usage)
> {
> struct ttm_bo_driver *driver = bo->bdev->driver;
> struct ttm_bo_device *bdev = bo->bdev;
> void *sync_obj;
> void *sync_obj_arg;
> int ret = 0;
> + void **bo_sync_obj;
>
> - if (likely(bo->sync_obj == NULL))
> + switch (usage) {
> + case TTM_USAGE_READ:
> + bo_sync_obj = &bo->sync_obj_read;
> + break;
> + case TTM_USAGE_WRITE:
> + bo_sync_obj = &bo->sync_obj_write;
> + break;
> + case TTM_USAGE_READWRITE:
> + default:
> + bo_sync_obj = &bo->sync_obj;
> + }
> +
> + if (likely(*bo_sync_obj == NULL))
> return 0;
>
> - while (bo->sync_obj) {
> + while (*bo_sync_obj) {
>
> - if (driver->sync_obj_signaled(bo->sync_obj, bo->sync_obj_arg)) {
> - void *tmp_obj = bo->sync_obj;
> - bo->sync_obj = NULL;
> - clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
> - spin_unlock(&bdev->fence_lock);
> - driver->sync_obj_unref(&tmp_obj);
> - spin_lock(&bdev->fence_lock);
> + if (driver->sync_obj_signaled(*bo_sync_obj, bo->sync_obj_arg)) {
> + ttm_bo_unref_sync_obj_locked(bo, *bo_sync_obj, NULL);
> continue;
> }
>
> if (no_wait)
> return -EBUSY;
>
> - sync_obj = driver->sync_obj_ref(bo->sync_obj);
> + sync_obj = driver->sync_obj_ref(*bo_sync_obj);
> sync_obj_arg = bo->sync_obj_arg;
> spin_unlock(&bdev->fence_lock);
> ret = driver->sync_obj_wait(sync_obj, sync_obj_arg,
> @@ -1726,16 +1778,9 @@ int ttm_bo_wait(struct ttm_buffer_object *bo,
> return ret;
> }
> spin_lock(&bdev->fence_lock);
> - if (likely(bo->sync_obj == sync_obj &&
> + if (likely(*bo_sync_obj == sync_obj &&
> bo->sync_obj_arg == sync_obj_arg)) {
> - void *tmp_obj = bo->sync_obj;
> - bo->sync_obj = NULL;
> - clear_bit(TTM_BO_PRIV_FLAG_MOVING,
> - &bo->priv_flags);
> - spin_unlock(&bdev->fence_lock);
> - driver->sync_obj_unref(&sync_obj);
> - driver->sync_obj_unref(&tmp_obj);
> - spin_lock(&bdev->fence_lock);
> + ttm_bo_unref_sync_obj_locked(bo, *bo_sync_obj, &sync_obj);
> } else {
> spin_unlock(&bdev->fence_lock);
> driver->sync_obj_unref(&sync_obj);
> @@ -1759,7 +1804,7 @@ int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
> if (unlikely(ret != 0))
> return ret;
> spin_lock(&bdev->fence_lock);
> - ret = ttm_bo_wait(bo, false, true, no_wait);
> + ret = ttm_bo_wait(bo, false, true, no_wait, TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
> if (likely(ret == 0))
> atomic_inc(&bo->cpu_writers);
> @@ -1833,7 +1878,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
> */
>
> spin_lock(&bo->bdev->fence_lock);
> - ret = ttm_bo_wait(bo, false, false, false);
> + ret = ttm_bo_wait(bo, false, false, false, TTM_USAGE_READWRITE);
> spin_unlock(&bo->bdev->fence_lock);
>
> if (unlikely(ret != 0))
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
> index 77dbf40..0399573 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_util.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
> @@ -436,6 +436,8 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
> atomic_set(&fbo->cpu_writers, 0);
>
> fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
> + fbo->sync_obj_read = driver->sync_obj_ref(bo->sync_obj_read);
> + fbo->sync_obj_write = driver->sync_obj_ref(bo->sync_obj_write);
> kref_init(&fbo->list_kref);
> kref_init(&fbo->kref);
> fbo->destroy = &ttm_transfered_destroy;
> @@ -618,20 +620,30 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
> struct ttm_mem_reg *old_mem = &bo->mem;
> int ret;
> struct ttm_buffer_object *ghost_obj;
> - void *tmp_obj = NULL;
> + void *tmp_obj = NULL, *tmp_obj_read = NULL, *tmp_obj_write = NULL;
>
> spin_lock(&bdev->fence_lock);
> - if (bo->sync_obj) {
> + if (bo->sync_obj)
> tmp_obj = bo->sync_obj;
> - bo->sync_obj = NULL;
> - }
> + if (bo->sync_obj_read)
> + tmp_obj_read = bo->sync_obj_read;
> + if (bo->sync_obj_write)
> + tmp_obj_write = bo->sync_obj_write;
> +
> bo->sync_obj = driver->sync_obj_ref(sync_obj);
> + bo->sync_obj_read = driver->sync_obj_ref(sync_obj);
> + bo->sync_obj_write = driver->sync_obj_ref(sync_obj);
> bo->sync_obj_arg = sync_obj_arg;
> if (evict) {
> - ret = ttm_bo_wait(bo, false, false, false);
> + ret = ttm_bo_wait(bo, false, false, false,
> + TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
> if (tmp_obj)
> driver->sync_obj_unref(&tmp_obj);
> + if (tmp_obj_read)
> + driver->sync_obj_unref(&tmp_obj_read);
> + if (tmp_obj_write)
> + driver->sync_obj_unref(&tmp_obj_write);
> if (ret)
> return ret;
>
> @@ -655,6 +667,10 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
> spin_unlock(&bdev->fence_lock);
> if (tmp_obj)
> driver->sync_obj_unref(&tmp_obj);
> + if (tmp_obj_read)
> + driver->sync_obj_unref(&tmp_obj_read);
> + if (tmp_obj_write)
> + driver->sync_obj_unref(&tmp_obj_write);
>
> ret = ttm_buffer_object_transfer(bo, &ghost_obj);
> if (ret)
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> index 221b924..ff1e26f 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> @@ -122,7 +122,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>
> spin_lock(&bdev->fence_lock);
> if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
> - ret = ttm_bo_wait(bo, false, true, false);
> + ret = ttm_bo_wait(bo, false, true, false, TTM_USAGE_READWRITE);
> spin_unlock(&bdev->fence_lock);
> if (unlikely(ret != 0)) {
> retval = (ret != -ERESTARTSYS) ?
> diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> index 3832fe1..0438296 100644
> --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> @@ -223,6 +223,14 @@ void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
> bo = entry->bo;
> entry->old_sync_obj = bo->sync_obj;
Here we should set entry->old_sync_obj_read &
entry->old_sync_obj_write to NULL so
we don't get bite by uninitialized memory (if caller fail or forget to do so)
> bo->sync_obj = driver->sync_obj_ref(sync_obj);
> + if (entry->usage & TTM_USAGE_READ) {
> + entry->old_sync_obj_read = bo->sync_obj_read;
> + bo->sync_obj_read = driver->sync_obj_ref(sync_obj);
> + }
> + if (entry->usage & TTM_USAGE_WRITE) {
> + entry->old_sync_obj_write = bo->sync_obj_write;
> + bo->sync_obj_write = driver->sync_obj_ref(sync_obj);
> + }
> bo->sync_obj_arg = entry->new_sync_obj_arg;
> ttm_bo_unreserve_locked(bo);
> entry->reserved = false;
> @@ -231,8 +239,15 @@ void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
> spin_unlock(&bdev->fence_lock);
>
> list_for_each_entry(entry, list, head) {
> - if (entry->old_sync_obj)
> + if (entry->old_sync_obj) {
> driver->sync_obj_unref(&entry->old_sync_obj);
> + }
> + if (entry->old_sync_obj_read) {
> + driver->sync_obj_unref(&entry->old_sync_obj_read);
> + }
> + if (entry->old_sync_obj_write) {
> + driver->sync_obj_unref(&entry->old_sync_obj_write);
> + }
> }
> }
> EXPORT_SYMBOL(ttm_eu_fence_buffer_objects);
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> index 41b95ed..8ca3ddb 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> @@ -224,6 +224,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
> if (unlikely(cur_validate_node == sw_context->cur_val_buf)) {
> val_buf = &sw_context->val_bufs[cur_validate_node];
> val_buf->bo = ttm_bo_reference(bo);
> + val_buf->usage = TTM_USAGE_READWRITE;
> val_buf->new_sync_obj_arg = (void *) dev_priv;
> list_add_tail(&val_buf->head, &sw_context->validate_nodes);
> ++sw_context->cur_val_buf;
> diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
> index 42e3469..da957bf 100644
> --- a/include/drm/ttm/ttm_bo_api.h
> +++ b/include/drm/ttm/ttm_bo_api.h
> @@ -44,6 +44,11 @@ struct ttm_bo_device;
>
> struct drm_mm_node;
>
> +enum ttm_buffer_usage {
> + TTM_USAGE_READ = 1,
> + TTM_USAGE_WRITE = 2,
> + TTM_USAGE_READWRITE = TTM_USAGE_READ | TTM_USAGE_WRITE
> +};
>
> /**
> * struct ttm_placement
> @@ -174,7 +179,10 @@ struct ttm_tt;
> * the bo_device::lru_lock.
> * @reserved: Deadlock-free lock used for synchronization state transitions.
> * @sync_obj_arg: Opaque argument to synchronization object function.
> - * @sync_obj: Pointer to a synchronization object.
> + * @sync_obj: Pointer to a synchronization object of a last read or write,
> + * whichever is later.
> + * @sync_obj_read: Pointer to a synchronization object of a last read.
> + * @sync_obj_write: Pointer to a synchronization object of a last write.
> * @priv_flags: Flags describing buffer object internal state.
> * @vm_rb: Rb node for the vm rb tree.
> * @vm_node: Address space manager node.
> @@ -258,6 +266,8 @@ struct ttm_buffer_object {
>
> void *sync_obj_arg;
> void *sync_obj;
> + void *sync_obj_read;
> + void *sync_obj_write;
> unsigned long priv_flags;
>
> /**
> @@ -325,6 +335,7 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
> * @bo: The buffer object.
> * @interruptible: Use interruptible wait.
> * @no_wait: Return immediately if buffer is busy.
> + * @usage: Whether to wait for the last read and/or the last write.
> *
> * This function must be called with the bo::mutex held, and makes
> * sure any previous rendering to the buffer is completed.
> @@ -334,7 +345,8 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
> * Returns -ERESTARTSYS if interrupted by a signal.
> */
> extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
> - bool interruptible, bool no_wait);
> + bool interruptible, bool no_wait,
> + enum ttm_buffer_usage usage);
> /**
> * ttm_bo_validate
> *
> diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h
> index 26cc7f9..375f299 100644
> --- a/include/drm/ttm/ttm_execbuf_util.h
> +++ b/include/drm/ttm/ttm_execbuf_util.h
> @@ -41,20 +41,26 @@
> * @bo: refcounted buffer object pointer.
> * @new_sync_obj_arg: New sync_obj_arg for @bo, to be used once
> * adding a new sync object.
> + * @usage Indicates how @bo is used by the device.
> * @reserved: Indicates whether @bo has been reserved for validation.
> * @removed: Indicates whether @bo has been removed from lru lists.
> * @put_count: Number of outstanding references on bo::list_kref.
> * @old_sync_obj: Pointer to a sync object about to be unreferenced
> + * @old_sync_obj_read: Pointer to a read sync object about to be unreferenced.
> + * @old_sync_obj_write: Pointer to a write sync object about to be unreferenced.
> */
>
> struct ttm_validate_buffer {
> struct list_head head;
> struct ttm_buffer_object *bo;
> void *new_sync_obj_arg;
> + enum ttm_buffer_usage usage;
> bool reserved;
> bool removed;
> int put_count;
> void *old_sync_obj;
> + void *old_sync_obj_read;
> + void *old_sync_obj_write;
> };
>
> /**
> --
> 1.7.4.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
More information about the dri-devel
mailing list