> > > > Problem with explicit placement selection in vmwgfx is that by the time > > the buffer object needs to be validated the information about which > > placement was supposed to be used is lost. To workaround this the driver > > had a bunch of state in various places e.g. as_mob or cpu_blit to > > somehow convey the information on which placement was intended. > > > > Fix it properly by allowing the buffer objects to hold their preferred > > placement so it can be reused whenever needed. This makes the entire > > validation pipeline a lot easier both to understand and maintain. I think this patch mixes up src/dst_pitch in the stdu code. CC [M] drivers/gpu/drm/etnaviv/etnaviv_gem_submit.o /home/airlied/devel/kernel/dim/src/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:509:29: error: variable 'dst_pitch' is uninitialized when used here [-Werror,-Wuninitialized] src_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp; ^~~~~~~~~ /home/airlied/devel/kernel/dim/src/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:492:26: note: initialize the variable 'dst_pitch' to silence this warning s32 src_pitch, dst_pitch; ^ = 0 Dave. > > > > Signed-off-by: Zack Rusin <zackr@xxxxxxxxxx> > > --- > > drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 145 +++++++-- > > drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 25 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 9 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 11 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 3 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 - > > drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 35 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 5 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 22 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 21 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 11 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h | 3 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 13 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 15 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 4 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 304 ++---------------- > > drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c | 3 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 6 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 47 --- > > drivers/gpu/drm/vmwgfx/vmwgfx_va.c | 4 +- > > drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 74 ++--- > > drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 6 +- > > 22 files changed, 312 insertions(+), 456 deletions(-) > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > > index c6dc733f6d45..d8f6ccecf4bf 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > > @@ -135,11 +135,17 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv, > > goto out_unreserve; > > } > > > > - ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, &ctx); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR); > > + ret = ttm_bo_validate(bo, &buf->placement, &ctx); > > if (likely(ret == 0) || ret == -ERESTARTSYS) > > goto out_unreserve; > > > > - ret = ttm_bo_validate(bo, &vmw_vram_placement, &ctx); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_VRAM); > > + ret = ttm_bo_validate(bo, &buf->placement, &ctx); > > > > out_unreserve: > > if (!ret) > > @@ -190,17 +196,8 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv, > > { > > struct ttm_operation_ctx ctx = {interruptible, false }; > > struct ttm_buffer_object *bo = &buf->base; > > - struct ttm_placement placement; > > - struct ttm_place place; > > int ret = 0; > > > > - place = vmw_vram_placement.placement[0]; > > - place.lpfn = PFN_UP(bo->resource->size); > > - placement.num_placement = 1; > > - placement.placement = &place; > > - placement.num_busy_placement = 1; > > - placement.busy_placement = &place; > > - > > vmw_execbuf_release_pinned_bo(dev_priv); > > ret = ttm_bo_reserve(bo, interruptible, false, NULL); > > if (unlikely(ret != 0)) > > @@ -216,14 +213,21 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv, > > bo->resource->start > 0 && > > buf->base.pin_count == 0) { > > ctx.interruptible = false; > > - (void) ttm_bo_validate(bo, &vmw_sys_placement, &ctx); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_SYS, > > + VMW_BO_DOMAIN_SYS); > > + (void)ttm_bo_validate(bo, &buf->placement, &ctx); > > } > > > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_VRAM); > > + buf->places[0].lpfn = PFN_UP(bo->resource->size); > > if (buf->base.pin_count > 0) > > - ret = ttm_resource_compat(bo->resource, &placement) > > + ret = ttm_resource_compat(bo->resource, &buf->placement) > > ? 0 : -EINVAL; > > else > > - ret = ttm_bo_validate(bo, &placement, &ctx); > > + ret = ttm_bo_validate(bo, &buf->placement, &ctx); > > > > /* For some reason we didn't end up at the start of vram */ > > WARN_ON(ret == 0 && bo->resource->start != 0); > > @@ -431,7 +435,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, > > } > > > > int vmw_bo_create(struct vmw_private *vmw, > > - size_t size, struct ttm_placement *placement, > > + size_t size, u32 domain, u32 busy_domain, > > bool interruptible, bool pin, > > struct vmw_bo **p_bo) > > { > > @@ -444,7 +448,8 @@ int vmw_bo_create(struct vmw_private *vmw, > > } > > > > ret = vmw_bo_init(vmw, *p_bo, size, > > - placement, interruptible, pin); > > + domain, busy_domain, > > + interruptible, pin); > > if (unlikely(ret != 0)) > > goto out_error; > > > > @@ -461,7 +466,8 @@ int vmw_bo_create(struct vmw_private *vmw, > > * @dev_priv: Pointer to the device private struct > > * @vmw_bo: Pointer to the struct vmw_bo to initialize. > > * @size: Buffer object size in bytes. > > - * @placement: Initial placement. > > + * @domain: Domain to put the bo in. > > + * @busy_domain: Domain to put the bo if busy. > > * @interruptible: Whether waits should be performed interruptible. > > * @pin: If the BO should be created pinned at a fixed location. > > * Returns: Zero on success, negative error code on error. > > @@ -470,7 +476,9 @@ int vmw_bo_create(struct vmw_private *vmw, > > */ > > int vmw_bo_init(struct vmw_private *dev_priv, > > struct vmw_bo *vmw_bo, > > - size_t size, struct ttm_placement *placement, > > + size_t size, > > + u32 domain, > > + u32 busy_domain, > > bool interruptible, bool pin) > > { > > struct ttm_operation_ctx ctx = { > > @@ -489,8 +497,9 @@ int vmw_bo_init(struct vmw_private *dev_priv, > > size = ALIGN(size, PAGE_SIZE); > > drm_gem_private_object_init(vdev, &vmw_bo->base.base, size); > > > > + vmw_bo_placement_set(vmw_bo, domain, busy_domain); > > ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, ttm_bo_type_device, > > - placement, 0, &ctx, NULL, NULL, vmw_bo_free); > > + &vmw_bo->placement, 0, &ctx, NULL, NULL, vmw_bo_free); > > if (unlikely(ret)) { > > return ret; > > } > > @@ -825,3 +834,101 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, > > if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB) > > vmw_resource_unbind_list(vbo); > > } > > + > > +static u32 > > +set_placement_list(struct ttm_place *pl, u32 domain) > > +{ > > + u32 n = 0; > > + > > + /* > > + * The placements are ordered according to our preferences > > + */ > > + if (domain & VMW_BO_DOMAIN_MOB) { > > + pl[n].mem_type = VMW_PL_MOB; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + if (domain & VMW_BO_DOMAIN_GMR) { > > + pl[n].mem_type = VMW_PL_GMR; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + if (domain & VMW_BO_DOMAIN_VRAM) { > > + pl[n].mem_type = TTM_PL_VRAM; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + WARN_ON((domain & VMW_BO_DOMAIN_WAITABLE_SYS) != 0); > > + if (domain & VMW_BO_DOMAIN_WAITABLE_SYS) { > > + pl[n].mem_type = VMW_PL_SYSTEM; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + if (domain & VMW_BO_DOMAIN_SYS) { > > + pl[n].mem_type = TTM_PL_SYSTEM; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + > > + WARN_ON(!n); > > + if (!n) { > > + pl[n].mem_type = TTM_PL_SYSTEM; > > + pl[n].flags = 0; > > + pl[n].fpfn = 0; > > + pl[n].lpfn = 0; > > + n++; > > + } > > + return n; > > +} > > + > > +void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain) > > +{ > > + struct ttm_device *bdev = bo->base.bdev; > > + struct vmw_private *vmw = > > + container_of(bdev, struct vmw_private, bdev); > > + struct ttm_placement *pl = &bo->placement; > > + bool mem_compatible = false; > > + u32 i; > > + > > + pl->placement = bo->places; > > + pl->num_placement = set_placement_list(bo->places, domain); > > + > > + if (drm_debug_enabled(DRM_UT_DRIVER) && bo->base.resource) { > > + for (i = 0; i < pl->num_placement; ++i) { > > + if (bo->base.resource->mem_type == TTM_PL_SYSTEM || > > + bo->base.resource->mem_type == pl->placement[i].mem_type) > > + mem_compatible = true; > > + } > > + if (!mem_compatible) > > + drm_warn(&vmw->drm, > > + "%s: Incompatible transition from " > > + "bo->base.resource->mem_type = %u to domain = %u\n", > > + __func__, bo->base.resource->mem_type, domain); > > + } > > + > > + pl->busy_placement = bo->busy_places; > > + pl->num_busy_placement = set_placement_list(bo->busy_places, busy_domain); > > +} > > + > > +void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo) > > +{ > > + struct ttm_device *bdev = bo->base.bdev; > > + struct vmw_private *vmw = > > + container_of(bdev, struct vmw_private, bdev); > > + u32 domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM; > > + > > + if (vmw->has_mob) > > + domain = VMW_BO_DOMAIN_MOB; > > + > > + vmw_bo_placement_set(bo, domain, domain); > > +} > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h > > index 2ede1e28d7ce..538d8739d7a5 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h > > @@ -31,6 +31,7 @@ > > #include "device_include/svga_reg.h" > > > > #include <drm/ttm/ttm_bo_api.h> > > +#include <drm/ttm/ttm_placement.h> > > > > #include <linux/rbtree_types.h> > > #include <linux/types.h> > > @@ -40,6 +41,14 @@ struct vmw_fence_obj; > > struct vmw_private; > > struct vmw_resource; > > > > +enum vmw_bo_domain { > > + VMW_BO_DOMAIN_SYS = BIT(0), > > + VMW_BO_DOMAIN_WAITABLE_SYS = BIT(1), > > + VMW_BO_DOMAIN_VRAM = BIT(2), > > + VMW_BO_DOMAIN_GMR = BIT(3), > > + VMW_BO_DOMAIN_MOB = BIT(4), > > +}; > > + > > /** > > * struct vmw_bo - TTM buffer object with vmwgfx additions > > * @base: The TTM buffer object > > @@ -53,6 +62,11 @@ struct vmw_resource; > > */ > > struct vmw_bo { > > struct ttm_buffer_object base; > > + > > + struct ttm_placement placement; > > + struct ttm_place places[5]; > > + struct ttm_place busy_places[5]; > > + > > struct rb_root res_tree; > > > > atomic_t cpu_writers; > > @@ -64,17 +78,24 @@ struct vmw_bo { > > struct vmw_bo_dirty *dirty; > > }; > > > > +void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain); > > +void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo); > > + > > int vmw_bo_create_kernel(struct vmw_private *dev_priv, > > unsigned long size, > > struct ttm_placement *placement, > > struct ttm_buffer_object **p_bo); > > int vmw_bo_create(struct vmw_private *dev_priv, > > - size_t size, struct ttm_placement *placement, > > + size_t size, > > + u32 domain, > > + u32 busy_domain, > > bool interruptible, bool pin, > > struct vmw_bo **p_bo); > > int vmw_bo_init(struct vmw_private *dev_priv, > > struct vmw_bo *vmw_bo, > > - size_t size, struct ttm_placement *placement, > > + size_t size, > > + u32 domain, > > + u32 busy_domain, > > bool interruptible, bool pin); > > int vmw_bo_unref_ioctl(struct drm_device *dev, void *data, > > struct drm_file *file_priv); > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > > index cc02be6a9884..84ef5f0a785b 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > > @@ -76,7 +76,8 @@ static const struct vmw_res_func vmw_legacy_context_func = { > > .needs_backup = false, > > .may_evict = false, > > .type_name = "legacy contexts", > > - .backup_placement = NULL, > > + .domain = VMW_BO_DOMAIN_SYS, > > + .busy_domain = VMW_BO_DOMAIN_SYS, > > .create = NULL, > > .destroy = NULL, > > .bind = NULL, > > @@ -90,7 +91,8 @@ static const struct vmw_res_func vmw_gb_context_func = { > > .prio = 3, > > .dirty_prio = 3, > > .type_name = "guest backed contexts", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_gb_context_create, > > .destroy = vmw_gb_context_destroy, > > .bind = vmw_gb_context_bind, > > @@ -104,7 +106,8 @@ static const struct vmw_res_func vmw_dx_context_func = { > > .prio = 3, > > .dirty_prio = 3, > > .type_name = "dx contexts", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_dx_context_create, > > .destroy = vmw_dx_context_destroy, > > .bind = vmw_dx_context_bind, > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c > > index 9193faae8dab..d49db8146df1 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c > > @@ -136,7 +136,8 @@ static const struct vmw_res_func vmw_cotable_func = { > > .prio = 3, > > .dirty_prio = 3, > > .type_name = "context guest backed object tables", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_cotable_create, > > .destroy = vmw_cotable_destroy, > > .bind = vmw_cotable_bind, > > @@ -424,7 +425,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) > > * for the new COTable. Initially pin the buffer object to make sure > > * we can use tryreserve without failure. > > */ > > - ret = vmw_bo_create(dev_priv, new_size, &vmw_mob_placement, > > + ret = vmw_bo_create(dev_priv, new_size, > > + VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB, > > true, true, &buf); > > if (ret) { > > DRM_ERROR("Failed initializing new cotable MOB.\n"); > > @@ -465,7 +467,10 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) > > } > > > > /* Unpin new buffer, and switch backup buffers. */ > > - ret = ttm_bo_validate(bo, &vmw_mob_placement, &ctx); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_MOB, > > + VMW_BO_DOMAIN_MOB); > > + ret = ttm_bo_validate(bo, &buf->placement, &ctx); > > if (unlikely(ret != 0)) { > > DRM_ERROR("Failed validating new COTable backup buffer.\n"); > > goto out_wait; > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c > > index 60d08185a71f..c12ad8264043 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c > > @@ -399,7 +399,8 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) > > * user of the bo currently. > > */ > > ret = vmw_bo_create(dev_priv, PAGE_SIZE, > > - &vmw_sys_placement, false, true, &vbo); > > + VMW_BO_DOMAIN_SYS, VMW_BO_DOMAIN_SYS, > > + false, true, &vbo); > > if (unlikely(ret != 0)) > > return ret; > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h > > index e9a16a1e043d..5629a00039fe 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h > > @@ -930,9 +930,7 @@ extern struct ttm_placement vmw_vram_placement; > > extern struct ttm_placement vmw_vram_sys_placement; > > extern struct ttm_placement vmw_vram_gmr_placement; > > extern struct ttm_placement vmw_sys_placement; > > -extern struct ttm_placement vmw_srf_placement; > > extern struct ttm_placement vmw_mob_placement; > > -extern struct ttm_placement vmw_nonfixed_placement; > > extern struct ttm_device_funcs vmw_bo_driver; > > extern const struct vmw_sg_table * > > vmw_bo_sg_table(struct ttm_buffer_object *bo); > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > > index 687c6926bc00..eda7f8471bcd 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > > @@ -477,9 +477,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, > > struct vmw_bo *dx_query_mob; > > > > dx_query_mob = vmw_context_get_dx_query_mob(ctx); > > - if (dx_query_mob) > > + if (dx_query_mob) { > > + vmw_bo_placement_set(dx_query_mob, > > + VMW_BO_DOMAIN_MOB, > > + VMW_BO_DOMAIN_MOB); > > ret = vmw_validation_add_bo(sw_context->ctx, > > - dx_query_mob, true, false); > > + dx_query_mob); > > + } > > } > > > > mutex_unlock(&dev_priv->binding_mutex); > > @@ -1035,17 +1039,17 @@ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, > > > > if (unlikely(sw_context->cur_query_bo != NULL)) { > > sw_context->needs_post_query_barrier = true; > > + vmw_bo_placement_set_default_accelerated(sw_context->cur_query_bo); > > ret = vmw_validation_add_bo(sw_context->ctx, > > - sw_context->cur_query_bo, > > - dev_priv->has_mob, false); > > + sw_context->cur_query_bo); > > if (unlikely(ret != 0)) > > return ret; > > } > > sw_context->cur_query_bo = new_query_bo; > > > > + vmw_bo_placement_set_default_accelerated(dev_priv->dummy_query_bo); > > ret = vmw_validation_add_bo(sw_context->ctx, > > - dev_priv->dummy_query_bo, > > - dev_priv->has_mob, false); > > + dev_priv->dummy_query_bo); > > if (unlikely(ret != 0)) > > return ret; > > } > > @@ -1157,7 +1161,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, > > drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n"); > > return PTR_ERR(vmw_bo); > > } > > - ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false); > > + vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB); > > + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo); > > ttm_bo_put(&vmw_bo->base); > > if (unlikely(ret != 0)) > > return ret; > > @@ -1211,7 +1216,9 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, > > drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n"); > > return PTR_ERR(vmw_bo); > > } > > - ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false); > > + vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); > > + ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo); > > ttm_bo_put(&vmw_bo->base); > > if (unlikely(ret != 0)) > > return ret; > > @@ -4361,13 +4368,17 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, > > if (dev_priv->pinned_bo == NULL) > > goto out_unlock; > > > > - ret = vmw_validation_add_bo(&val_ctx, dev_priv->pinned_bo, false, > > - false); > > + vmw_bo_placement_set(dev_priv->pinned_bo, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); > > + ret = vmw_validation_add_bo(&val_ctx, dev_priv->pinned_bo); > > if (ret) > > goto out_no_reserve; > > > > - ret = vmw_validation_add_bo(&val_ctx, dev_priv->dummy_query_bo, false, > > - false); > > + vmw_bo_placement_set(dev_priv->dummy_query_bo, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); > > + ret = vmw_validation_add_bo(&val_ctx, dev_priv->dummy_query_bo); > > if (ret) > > goto out_no_reserve; > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > > index c7ebcd4f3afa..5f383578a320 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c > > @@ -121,9 +121,8 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, > > int ret; > > > > ret = vmw_bo_create(dev_priv, size, > > - (dev_priv->has_mob) ? > > - &vmw_sys_placement : > > - &vmw_vram_sys_placement, > > + (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_SYS, > > true, false, p_vbo); > > > > (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs; > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > index e83286e08837..d975c0a818c7 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > @@ -1270,9 +1270,9 @@ int vmw_kms_readback(struct vmw_private *dev_priv, > > user_fence_rep, vclips, num_clips, > > NULL); > > case vmw_du_screen_target: > > - return vmw_kms_stdu_dma(dev_priv, file_priv, vfb, > > - user_fence_rep, NULL, vclips, num_clips, > > - 1, false, true, NULL); > > + return vmw_kms_stdu_readback(dev_priv, file_priv, vfb, > > + user_fence_rep, NULL, vclips, num_clips, > > + 1, NULL); > > default: > > WARN_ONCE(true, > > "Readback called with invalid display system.\n"); > > @@ -2999,8 +2999,20 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update) > > struct vmw_framebuffer_bo *vfbbo = > > container_of(update->vfb, typeof(*vfbbo), base); > > > > - ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer, false, > > - update->cpu_blit); > > + /* > > + * For screen targets we want a mappable bo, for everything else we want > > + * accelerated i.e. host backed (vram or gmr) bo. If the display unit > > + * is not screen target then mob's shouldn't be available. > > + */ > > + if (update->dev_priv->active_display_unit == vmw_du_screen_target) { > > + vmw_bo_placement_set(vfbbo->buffer, > > + VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR, > > + VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR); > > + } else { > > + WARN_ON(update->dev_priv->has_mob); > > + vmw_bo_placement_set_default_accelerated(vfbbo->buffer); > > + } > > + ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer); > > } else { > > struct vmw_framebuffer_surface *vfbs = > > container_of(update->vfb, typeof(*vfbs), base); > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h > > index 7a97e53e8e51..1bdf601e7c35 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h > > @@ -126,7 +126,6 @@ struct vmw_du_update_plane { > > struct vmw_framebuffer *vfb; > > struct vmw_fence_obj **out_fence; > > struct mutex *mutex; > > - bool cpu_blit; > > bool intr; > > }; > > > > @@ -564,17 +563,15 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, > > unsigned num_clips, int inc, > > struct vmw_fence_obj **out_fence, > > struct drm_crtc *crtc); > > -int vmw_kms_stdu_dma(struct vmw_private *dev_priv, > > - struct drm_file *file_priv, > > - struct vmw_framebuffer *vfb, > > - struct drm_vmw_fence_rep __user *user_fence_rep, > > - struct drm_clip_rect *clips, > > - struct drm_vmw_rect *vclips, > > - uint32_t num_clips, > > - int increment, > > - bool to_surface, > > - bool interruptible, > > - struct drm_crtc *crtc); > > +int vmw_kms_stdu_readback(struct vmw_private *dev_priv, > > + struct drm_file *file_priv, > > + struct vmw_framebuffer *vfb, > > + struct drm_vmw_fence_rep __user *user_fence_rep, > > + struct drm_clip_rect *clips, > > + struct drm_vmw_rect *vclips, > > + uint32_t num_clips, > > + int increment, > > + struct drm_crtc *crtc); > > > > int vmw_du_helper_plane_update(struct vmw_du_update_plane *update); > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c > > index 54e412f8c2d1..6780a36e6171 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c > > @@ -332,7 +332,7 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res, > > } > > > > ret = vmw_bo_create(res->dev_priv, res->backup_size, > > - res->func->backup_placement, > > + res->func->domain, res->func->busy_domain, > > interruptible, false, &backup); > > if (unlikely(ret != 0)) > > goto out_no_bo; > > @@ -529,8 +529,10 @@ vmw_resource_check_buffer(struct ww_acquire_ctx *ticket, > > return 0; > > > > backup_dirty = res->backup_dirty; > > + vmw_bo_placement_set(res->backup, res->func->domain, > > + res->func->busy_domain); > > ret = ttm_bo_validate(&res->backup->base, > > - res->func->backup_placement, > > + &res->backup->placement, > > &ctx); > > > > if (unlikely(ret != 0)) > > @@ -968,9 +970,12 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) > > if (ret) > > goto out_no_validate; > > if (!vbo->base.pin_count) { > > + vmw_bo_placement_set(vbo, > > + res->func->domain, > > + res->func->busy_domain); > > ret = ttm_bo_validate > > (&vbo->base, > > - res->func->backup_placement, > > + &vbo->placement, > > &ctx); > > if (ret) { > > ttm_bo_unreserve(&vbo->base); > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h > > index 3b7438b2d289..2c24e0929faa 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h > > @@ -83,7 +83,8 @@ struct vmw_res_func { > > enum vmw_res_type res_type; > > bool needs_backup; > > const char *type_name; > > - struct ttm_placement *backup_placement; > > + u32 domain; > > + u32 busy_domain; > > bool may_evict; > > u32 prio; > > u32 dirty_prio; > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c > > index a04897f04c13..e9d03ef98154 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c > > @@ -445,7 +445,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, > > */ > > vmw_overlay_pause_all(dev_priv); > > ret = vmw_bo_create(dev_priv, size, > > - &vmw_vram_placement, > > + VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_VRAM, > > false, true, &vps->bo); > > vmw_overlay_resume_all(dev_priv); > > if (ret) { > > @@ -547,7 +548,6 @@ static int vmw_sou_plane_update_bo(struct vmw_private *dev_priv, > > bo_update.base.vfb = vfb; > > bo_update.base.out_fence = out_fence; > > bo_update.base.mutex = NULL; > > - bo_update.base.cpu_blit = false; > > bo_update.base.intr = true; > > > > bo_update.base.calc_fifo_size = vmw_sou_bo_fifo_size; > > @@ -708,7 +708,6 @@ static int vmw_sou_plane_update_surface(struct vmw_private *dev_priv, > > srf_update.base.vfb = vfb; > > srf_update.base.out_fence = out_fence; > > srf_update.base.mutex = &dev_priv->cmdbuf_mutex; > > - srf_update.base.cpu_blit = false; > > srf_update.base.intr = true; > > > > srf_update.base.calc_fifo_size = vmw_sou_surface_fifo_size; > > @@ -1224,7 +1223,9 @@ int vmw_kms_sou_do_bo_dirty(struct vmw_private *dev_priv, > > DECLARE_VAL_CONTEXT(val_ctx, NULL, 0); > > int ret; > > > > - ret = vmw_validation_add_bo(&val_ctx, buf, false, false); > > + vmw_bo_placement_set(buf, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); > > + ret = vmw_validation_add_bo(&val_ctx, buf); > > if (ret) > > return ret; > > > > @@ -1330,7 +1331,9 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv, > > DECLARE_VAL_CONTEXT(val_ctx, NULL, 0); > > int ret; > > > > - ret = vmw_validation_add_bo(&val_ctx, buf, false, false); > > + vmw_bo_placement_set(buf, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > + VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); > > + ret = vmw_validation_add_bo(&val_ctx, buf); > > if (ret) > > return ret; > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c > > index b186d0993d83..9920c103bffb 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c > > @@ -94,7 +94,8 @@ static const struct vmw_res_func vmw_gb_shader_func = { > > .prio = 3, > > .dirty_prio = 3, > > .type_name = "guest backed shaders", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_gb_shader_create, > > .destroy = vmw_gb_shader_destroy, > > .bind = vmw_gb_shader_bind, > > @@ -108,7 +109,8 @@ static const struct vmw_res_func vmw_dx_shader_func = { > > .prio = 3, > > .dirty_prio = 3, > > .type_name = "dx shaders", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_dx_shader_create, > > /* > > * The destroy callback is only called with a committed resource on > > @@ -893,7 +895,9 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, > > if (!vmw_shader_id_ok(user_key, shader_type)) > > return -EINVAL; > > > > - ret = vmw_bo_create(dev_priv, size, &vmw_sys_placement, > > + ret = vmw_bo_create(dev_priv, size, > > + VMW_BO_DOMAIN_SYS, > > + VMW_BO_DOMAIN_SYS, > > true, true, &buf); > > if (unlikely(ret != 0)) > > goto out; > > @@ -913,7 +917,10 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, > > WARN_ON(is_iomem); > > > > ttm_bo_kunmap(&map); > > - ret = ttm_bo_validate(&buf->base, &vmw_sys_placement, &ctx); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_SYS, > > + VMW_BO_DOMAIN_SYS); > > + ret = ttm_bo_validate(&buf->base, &buf->placement, &ctx); > > WARN_ON(ret != 0); > > ttm_bo_unreserve(&buf->base); > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c > > index 4ea32b01efc0..603175b8c97e 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c > > @@ -24,6 +24,7 @@ > > * > > **************************************************************************/ > > > > +#include "vmwgfx_bo.h" > > #include "vmwgfx_drv.h" > > #include "vmwgfx_resource_priv.h" > > #include "vmwgfx_so.h" > > @@ -84,7 +85,8 @@ static const struct vmw_res_func vmw_view_func = { > > .needs_backup = false, > > .may_evict = false, > > .type_name = "DX view", > > - .backup_placement = NULL, > > + .domain = VMW_BO_DOMAIN_SYS, > > + .busy_domain = VMW_BO_DOMAIN_SYS, > > .create = vmw_view_create, > > .commit_notify = vmw_view_commit_notify, > > }; > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > > index 4745537fed25..0df86402e9ce 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c > > @@ -66,7 +66,6 @@ enum stdu_content_type { > > */ > > struct vmw_stdu_dirty { > > struct vmw_kms_dirty base; > > - SVGA3dTransferType transfer; > > s32 left, right, top, bottom; > > s32 fb_left, fb_top; > > u32 pitch; > > @@ -137,12 +136,6 @@ static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu); > > * Screen Target Display Unit CRTC Functions > > *****************************************************************************/ > > > > -static bool vmw_stdu_use_cpu_blit(const struct vmw_private *vmw) > > -{ > > - return !(vmw->capabilities & SVGA_CAP_3D) || vmw->vram_size < (32 * 1024 * 1024); > > -} > > - > > - > > /** > > * vmw_stdu_crtc_destroy - cleans up the STDU > > * > > @@ -451,93 +444,6 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, > > } > > } > > > > -/** > > - * vmw_stdu_bo_clip - Callback to encode a suface DMA command cliprect > > - * > > - * @dirty: The closure structure. > > - * > > - * Encodes a surface DMA command cliprect and updates the bounding box > > - * for the DMA. > > - */ > > -static void vmw_stdu_bo_clip(struct vmw_kms_dirty *dirty) > > -{ > > - struct vmw_stdu_dirty *ddirty = > > - container_of(dirty, struct vmw_stdu_dirty, base); > > - struct vmw_stdu_dma *cmd = dirty->cmd; > > - struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1]; > > - > > - blit += dirty->num_hits; > > - blit->srcx = dirty->fb_x; > > - blit->srcy = dirty->fb_y; > > - blit->x = dirty->unit_x1; > > - blit->y = dirty->unit_y1; > > - blit->d = 1; > > - blit->w = dirty->unit_x2 - dirty->unit_x1; > > - blit->h = dirty->unit_y2 - dirty->unit_y1; > > - dirty->num_hits++; > > - > > - if (ddirty->transfer != SVGA3D_WRITE_HOST_VRAM) > > - return; > > - > > - /* Destination bounding box */ > > - ddirty->left = min_t(s32, ddirty->left, dirty->unit_x1); > > - ddirty->top = min_t(s32, ddirty->top, dirty->unit_y1); > > - ddirty->right = max_t(s32, ddirty->right, dirty->unit_x2); > > - ddirty->bottom = max_t(s32, ddirty->bottom, dirty->unit_y2); > > -} > > - > > -/** > > - * vmw_stdu_bo_fifo_commit - Callback to fill in and submit a DMA command. > > - * > > - * @dirty: The closure structure. > > - * > > - * Fills in the missing fields in a DMA command, and optionally encodes > > - * a screen target update command, depending on transfer direction. > > - */ > > -static void vmw_stdu_bo_fifo_commit(struct vmw_kms_dirty *dirty) > > -{ > > - struct vmw_stdu_dirty *ddirty = > > - container_of(dirty, struct vmw_stdu_dirty, base); > > - struct vmw_screen_target_display_unit *stdu = > > - container_of(dirty->unit, typeof(*stdu), base); > > - struct vmw_stdu_dma *cmd = dirty->cmd; > > - struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1]; > > - SVGA3dCmdSurfaceDMASuffix *suffix = > > - (SVGA3dCmdSurfaceDMASuffix *) &blit[dirty->num_hits]; > > - size_t blit_size = sizeof(*blit) * dirty->num_hits + sizeof(*suffix); > > - > > - if (!dirty->num_hits) { > > - vmw_cmd_commit(dirty->dev_priv, 0); > > - return; > > - } > > - > > - cmd->header.id = SVGA_3D_CMD_SURFACE_DMA; > > - cmd->header.size = sizeof(cmd->body) + blit_size; > > - vmw_bo_get_guest_ptr(&ddirty->buf->base, &cmd->body.guest.ptr); > > - cmd->body.guest.pitch = ddirty->pitch; > > - cmd->body.host.sid = stdu->display_srf->res.id; > > - cmd->body.host.face = 0; > > - cmd->body.host.mipmap = 0; > > - cmd->body.transfer = ddirty->transfer; > > - suffix->suffixSize = sizeof(*suffix); > > - suffix->maximumOffset = ddirty->buf->base.base.size; > > - > > - if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) { > > - blit_size += sizeof(struct vmw_stdu_update); > > - > > - vmw_stdu_populate_update(&suffix[1], stdu->base.unit, > > - ddirty->left, ddirty->right, > > - ddirty->top, ddirty->bottom); > > - } > > - > > - vmw_cmd_commit(dirty->dev_priv, sizeof(*cmd) + blit_size); > > - > > - stdu->display_srf->res.res_dirty = true; > > - ddirty->left = ddirty->top = S32_MAX; > > - ddirty->right = ddirty->bottom = S32_MIN; > > -} > > - > > - > > /** > > * vmw_stdu_bo_cpu_clip - Callback to encode a CPU blit > > * > > @@ -598,62 +504,21 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) > > return; > > > > /* Assume we are blitting from Guest (bo) to Host (display_srf) */ > > - dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; > > - dst_bo = &stdu->display_srf->res.backup->base; > > - dst_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp; > > - > > - src_pitch = ddirty->pitch; > > - src_bo = &ddirty->buf->base; > > - src_offset = ddirty->fb_top * src_pitch + ddirty->fb_left * stdu->cpp; > > + src_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; > > + src_bo = &stdu->display_srf->res.backup->base; > > + src_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp; > > > > - /* Swap src and dst if the assumption was wrong. */ > > - if (ddirty->transfer != SVGA3D_WRITE_HOST_VRAM) { > > - swap(dst_pitch, src_pitch); > > - swap(dst_bo, src_bo); > > - swap(src_offset, dst_offset); > > - } > > + dst_pitch = ddirty->pitch; > > + dst_bo = &ddirty->buf->base; > > + dst_offset = ddirty->fb_top * src_pitch + ddirty->fb_left * stdu->cpp; > > > > (void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch, > > src_bo, src_offset, src_pitch, > > width * stdu->cpp, height, &diff); > > - > > - if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM && > > - drm_rect_visible(&diff.rect)) { > > - struct vmw_private *dev_priv; > > - struct vmw_stdu_update *cmd; > > - struct drm_clip_rect region; > > - int ret; > > - > > - /* We are updating the actual surface, not a proxy */ > > - region.x1 = diff.rect.x1; > > - region.x2 = diff.rect.x2; > > - region.y1 = diff.rect.y1; > > - region.y2 = diff.rect.y2; > > - ret = vmw_kms_update_proxy(&stdu->display_srf->res, ®ion, > > - 1, 1); > > - if (ret) > > - goto out_cleanup; > > - > > - > > - dev_priv = vmw_priv(stdu->base.crtc.dev); > > - cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd)); > > - if (!cmd) > > - goto out_cleanup; > > - > > - vmw_stdu_populate_update(cmd, stdu->base.unit, > > - region.x1, region.x2, > > - region.y1, region.y2); > > - > > - vmw_cmd_commit(dev_priv, sizeof(*cmd)); > > - } > > - > > -out_cleanup: > > - ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX; > > - ddirty->right = ddirty->bottom = S32_MIN; > > } > > > > /** > > - * vmw_kms_stdu_dma - Perform a DMA transfer between a buffer-object backed > > + * vmw_kms_stdu_readback - Perform a readback from a buffer-object backed > > * framebuffer and the screen target system. > > * > > * @dev_priv: Pointer to the device private structure. > > @@ -666,9 +531,6 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) > > * be NULL. > > * @num_clips: Number of clip rects in @clips or @vclips. > > * @increment: Increment to use when looping over @clips or @vclips. > > - * @to_surface: Whether to DMA to the screen target system as opposed to > > - * from the screen target system. > > - * @interruptible: Whether to perform waits interruptible if possible. > > * @crtc: If crtc is passed, perform stdu dma on that crtc only. > > * > > * If DMA-ing till the screen target system, the function will also notify > > @@ -677,59 +539,49 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) > > * Returns 0 on success, negative error code on failure. -ERESTARTSYS if > > * interrupted. > > */ > > -int vmw_kms_stdu_dma(struct vmw_private *dev_priv, > > - struct drm_file *file_priv, > > - struct vmw_framebuffer *vfb, > > - struct drm_vmw_fence_rep __user *user_fence_rep, > > - struct drm_clip_rect *clips, > > - struct drm_vmw_rect *vclips, > > - uint32_t num_clips, > > - int increment, > > - bool to_surface, > > - bool interruptible, > > - struct drm_crtc *crtc) > > +int vmw_kms_stdu_readback(struct vmw_private *dev_priv, > > + struct drm_file *file_priv, > > + struct vmw_framebuffer *vfb, > > + struct drm_vmw_fence_rep __user *user_fence_rep, > > + struct drm_clip_rect *clips, > > + struct drm_vmw_rect *vclips, > > + uint32_t num_clips, > > + int increment, > > + struct drm_crtc *crtc) > > { > > struct vmw_bo *buf = > > container_of(vfb, struct vmw_framebuffer_bo, base)->buffer; > > struct vmw_stdu_dirty ddirty; > > int ret; > > - bool cpu_blit = vmw_stdu_use_cpu_blit(dev_priv); > > DECLARE_VAL_CONTEXT(val_ctx, NULL, 0); > > > > /* > > - * VMs without 3D support don't have the surface DMA command and > > - * we'll be using a CPU blit, and the framebuffer should be moved out > > - * of VRAM. > > + * The GMR domain might seem confusing because it might seem like it should > > + * never happen with screen targets but e.g. the xorg vmware driver issues > > + * CMD_SURFACE_DMA for various pixmap updates which might transition our bo to > > + * a GMR. Instead of forcing another transition we can optimize the readback > > + * by reading directly from the GMR. > > */ > > - ret = vmw_validation_add_bo(&val_ctx, buf, false, cpu_blit); > > + vmw_bo_placement_set(buf, > > + VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR, > > + VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR); > > + ret = vmw_validation_add_bo(&val_ctx, buf); > > if (ret) > > return ret; > > > > - ret = vmw_validation_prepare(&val_ctx, NULL, interruptible); > > + ret = vmw_validation_prepare(&val_ctx, NULL, true); > > if (ret) > > goto out_unref; > > > > - ddirty.transfer = (to_surface) ? SVGA3D_WRITE_HOST_VRAM : > > - SVGA3D_READ_HOST_VRAM; > > ddirty.left = ddirty.top = S32_MAX; > > ddirty.right = ddirty.bottom = S32_MIN; > > ddirty.fb_left = ddirty.fb_top = S32_MAX; > > ddirty.pitch = vfb->base.pitches[0]; > > ddirty.buf = buf; > > - ddirty.base.fifo_commit = vmw_stdu_bo_fifo_commit; > > - ddirty.base.clip = vmw_stdu_bo_clip; > > - ddirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_dma) + > > - num_clips * sizeof(SVGA3dCopyBox) + > > - sizeof(SVGA3dCmdSurfaceDMASuffix); > > - if (to_surface) > > - ddirty.base.fifo_reserve_size += sizeof(struct vmw_stdu_update); > > - > > - > > - if (cpu_blit) { > > - ddirty.base.fifo_commit = vmw_stdu_bo_cpu_commit; > > - ddirty.base.clip = vmw_stdu_bo_cpu_clip; > > - ddirty.base.fifo_reserve_size = 0; > > - } > > + > > + ddirty.base.fifo_commit = vmw_stdu_bo_cpu_commit; > > + ddirty.base.clip = vmw_stdu_bo_cpu_clip; > > + ddirty.base.fifo_reserve_size = 0; > > > > ddirty.base.crtc = crtc; > > > > @@ -1161,11 +1013,8 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, > > /* > > * This should only happen if the buffer object is too large to create a > > * proxy surface for. > > - * If we are a 2D VM with a buffer object then we have to use CPU blit > > - * so cache these mappings > > */ > > - if (vps->content_fb_type == SEPARATE_BO && > > - vmw_stdu_use_cpu_blit(dev_priv)) > > + if (vps->content_fb_type == SEPARATE_BO) > > vps->cpp = new_fb->pitches[0] / new_fb->width; > > > > return 0; > > @@ -1175,14 +1024,6 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, > > return ret; > > } > > > > -static uint32_t vmw_stdu_bo_fifo_size(struct vmw_du_update_plane *update, > > - uint32_t num_hits) > > -{ > > - return sizeof(struct vmw_stdu_dma) + sizeof(SVGA3dCopyBox) * num_hits + > > - sizeof(SVGA3dCmdSurfaceDMASuffix) + > > - sizeof(struct vmw_stdu_update); > > -} > > - > > static uint32_t vmw_stdu_bo_fifo_size_cpu(struct vmw_du_update_plane *update, > > uint32_t num_hits) > > { > > @@ -1190,68 +1031,6 @@ static uint32_t vmw_stdu_bo_fifo_size_cpu(struct vmw_du_update_plane *update, > > sizeof(struct vmw_stdu_update); > > } > > > > -static uint32_t vmw_stdu_bo_populate_dma(struct vmw_du_update_plane *update, > > - void *cmd, uint32_t num_hits) > > -{ > > - struct vmw_screen_target_display_unit *stdu; > > - struct vmw_framebuffer_bo *vfbbo; > > - struct vmw_stdu_dma *cmd_dma = cmd; > > - > > - stdu = container_of(update->du, typeof(*stdu), base); > > - vfbbo = container_of(update->vfb, typeof(*vfbbo), base); > > - > > - cmd_dma->header.id = SVGA_3D_CMD_SURFACE_DMA; > > - cmd_dma->header.size = sizeof(cmd_dma->body) + > > - sizeof(struct SVGA3dCopyBox) * num_hits + > > - sizeof(SVGA3dCmdSurfaceDMASuffix); > > - vmw_bo_get_guest_ptr(&vfbbo->buffer->base, &cmd_dma->body.guest.ptr); > > - cmd_dma->body.guest.pitch = update->vfb->base.pitches[0]; > > - cmd_dma->body.host.sid = stdu->display_srf->res.id; > > - cmd_dma->body.host.face = 0; > > - cmd_dma->body.host.mipmap = 0; > > - cmd_dma->body.transfer = SVGA3D_WRITE_HOST_VRAM; > > - > > - return sizeof(*cmd_dma); > > -} > > - > > -static uint32_t vmw_stdu_bo_populate_clip(struct vmw_du_update_plane *update, > > - void *cmd, struct drm_rect *clip, > > - uint32_t fb_x, uint32_t fb_y) > > -{ > > - struct SVGA3dCopyBox *box = cmd; > > - > > - box->srcx = fb_x; > > - box->srcy = fb_y; > > - box->srcz = 0; > > - box->x = clip->x1; > > - box->y = clip->y1; > > - box->z = 0; > > - box->w = drm_rect_width(clip); > > - box->h = drm_rect_height(clip); > > - box->d = 1; > > - > > - return sizeof(*box); > > -} > > - > > -static uint32_t vmw_stdu_bo_populate_update(struct vmw_du_update_plane *update, > > - void *cmd, struct drm_rect *bb) > > -{ > > - struct vmw_screen_target_display_unit *stdu; > > - struct vmw_framebuffer_bo *vfbbo; > > - SVGA3dCmdSurfaceDMASuffix *suffix = cmd; > > - > > - stdu = container_of(update->du, typeof(*stdu), base); > > - vfbbo = container_of(update->vfb, typeof(*vfbbo), base); > > - > > - suffix->suffixSize = sizeof(*suffix); > > - suffix->maximumOffset = vfbbo->buffer->base.base.size; > > - > > - vmw_stdu_populate_update(&suffix[1], stdu->base.unit, bb->x1, bb->x2, > > - bb->y1, bb->y2); > > - > > - return sizeof(*suffix) + sizeof(struct vmw_stdu_update); > > -} > > - > > static uint32_t vmw_stdu_bo_pre_clip_cpu(struct vmw_du_update_plane *update, > > void *cmd, uint32_t num_hits) > > { > > @@ -1369,24 +1148,12 @@ static int vmw_stdu_plane_update_bo(struct vmw_private *dev_priv, > > bo_update.base.vfb = vfb; > > bo_update.base.out_fence = out_fence; > > bo_update.base.mutex = NULL; > > - bo_update.base.cpu_blit = vmw_stdu_use_cpu_blit(dev_priv); > > bo_update.base.intr = false; > > > > - /* > > - * VM without 3D support don't have surface DMA command and framebuffer > > - * should be moved out of VRAM. > > - */ > > - if (bo_update.base.cpu_blit) { > > - bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size_cpu; > > - bo_update.base.pre_clip = vmw_stdu_bo_pre_clip_cpu; > > - bo_update.base.clip = vmw_stdu_bo_clip_cpu; > > - bo_update.base.post_clip = vmw_stdu_bo_populate_update_cpu; > > - } else { > > - bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size; > > - bo_update.base.pre_clip = vmw_stdu_bo_populate_dma; > > - bo_update.base.clip = vmw_stdu_bo_populate_clip; > > - bo_update.base.post_clip = vmw_stdu_bo_populate_update; > > - } > > + bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size_cpu; > > + bo_update.base.pre_clip = vmw_stdu_bo_pre_clip_cpu; > > + bo_update.base.clip = vmw_stdu_bo_clip_cpu; > > + bo_update.base.post_clip = vmw_stdu_bo_populate_update_cpu; > > > > return vmw_du_helper_plane_update(&bo_update.base); > > } > > @@ -1549,7 +1316,6 @@ static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv, > > srf_update.vfb = vfb; > > srf_update.out_fence = out_fence; > > srf_update.mutex = &dev_priv->cmdbuf_mutex; > > - srf_update.cpu_blit = false; > > srf_update.intr = true; > > > > if (vfbs->is_bo_proxy) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c > > index 71ce89150ba7..b35ac195285d 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c > > @@ -66,7 +66,8 @@ static const struct vmw_res_func vmw_dx_streamoutput_func = { > > .needs_backup = true, > > .may_evict = false, > > .type_name = "DX streamoutput", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_dx_streamoutput_create, > > .destroy = NULL, /* Command buffer managed resource. */ > > .bind = vmw_dx_streamoutput_bind, > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > > index 296d903c5acb..9c6a691b005e 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c > > @@ -131,7 +131,8 @@ static const struct vmw_res_func vmw_legacy_surface_func = { > > .prio = 1, > > .dirty_prio = 1, > > .type_name = "legacy surfaces", > > - .backup_placement = &vmw_srf_placement, > > + .domain = VMW_BO_DOMAIN_GMR, > > + .busy_domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, > > .create = &vmw_legacy_srf_create, > > .destroy = &vmw_legacy_srf_destroy, > > .bind = &vmw_legacy_srf_bind, > > @@ -145,7 +146,8 @@ static const struct vmw_res_func vmw_gb_surface_func = { > > .prio = 1, > > .dirty_prio = 2, > > .type_name = "guest backed surfaces", > > - .backup_placement = &vmw_mob_placement, > > + .domain = VMW_BO_DOMAIN_MOB, > > + .busy_domain = VMW_BO_DOMAIN_MOB, > > .create = vmw_gb_surface_create, > > .destroy = vmw_gb_surface_destroy, > > .bind = vmw_gb_surface_bind, > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c > > index 41480af87255..c43df4109613 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c > > @@ -79,20 +79,6 @@ static const struct ttm_place vram_gmr_placement_flags[] = { > > } > > }; > > > > -static const struct ttm_place gmr_vram_placement_flags[] = { > > - { > > - .fpfn = 0, > > - .lpfn = 0, > > - .mem_type = VMW_PL_GMR, > > - .flags = 0 > > - }, { > > - .fpfn = 0, > > - .lpfn = 0, > > - .mem_type = TTM_PL_VRAM, > > - .flags = 0 > > - } > > -}; > > - > > static const struct ttm_place vmw_sys_placement_flags = { > > .fpfn = 0, > > .lpfn = 0, > > @@ -128,32 +114,6 @@ struct ttm_placement vmw_pt_sys_placement = { > > .busy_placement = &vmw_sys_placement_flags > > }; > > > > -static const struct ttm_place nonfixed_placement_flags[] = { > > - { > > - .fpfn = 0, > > - .lpfn = 0, > > - .mem_type = TTM_PL_SYSTEM, > > - .flags = 0 > > - }, { > > - .fpfn = 0, > > - .lpfn = 0, > > - .mem_type = VMW_PL_GMR, > > - .flags = 0 > > - }, { > > - .fpfn = 0, > > - .lpfn = 0, > > - .mem_type = VMW_PL_MOB, > > - .flags = 0 > > - } > > -}; > > - > > -struct ttm_placement vmw_srf_placement = { > > - .num_placement = 1, > > - .num_busy_placement = 2, > > - .placement = &gmr_placement_flags, > > - .busy_placement = gmr_vram_placement_flags > > -}; > > - > > struct ttm_placement vmw_mob_placement = { > > .num_placement = 1, > > .num_busy_placement = 1, > > @@ -161,13 +121,6 @@ struct ttm_placement vmw_mob_placement = { > > .busy_placement = &mob_placement_flags > > }; > > > > -struct ttm_placement vmw_nonfixed_placement = { > > - .num_placement = 3, > > - .placement = nonfixed_placement_flags, > > - .num_busy_placement = 1, > > - .busy_placement = &sys_placement_flags > > -}; > > - > > const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt); > > > > /** > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_va.c b/drivers/gpu/drm/vmwgfx/vmwgfx_va.c > > index 6ad744ae07f5..c968180c9769 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_va.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_va.c > > @@ -25,6 +25,7 @@ > > * > > **************************************************************************/ > > > > +#include "vmwgfx_bo.h" > > #include "vmwgfx_drv.h" > > #include "vmwgfx_resource_priv.h" > > > > @@ -83,7 +84,8 @@ static const struct vmw_simple_resource_func va_stream_func = { > > .needs_backup = false, > > .may_evict = false, > > .type_name = "overlay stream", > > - .backup_placement = NULL, > > + .domain = VMW_BO_DOMAIN_SYS, > > + .busy_domain = VMW_BO_DOMAIN_SYS, > > .create = NULL, > > .destroy = NULL, > > .bind = NULL, > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c > > index 770b1b53bde7..05f0909ff1dd 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c > > @@ -27,6 +27,7 @@ > > **************************************************************************/ > > #include "vmwgfx_bo.h" > > #include "vmwgfx_drv.h" > > +#include "vmwgfx_resource_priv.h" > > #include "vmwgfx_validation.h" > > > > #include <linux/slab.h> > > @@ -40,8 +41,6 @@ > > * @hash: A hash entry used for the duplicate detection hash table. > > * @coherent_count: If switching backup buffers, number of new coherent > > * resources that will have this buffer as a backup buffer. > > - * @as_mob: Validate as mob. > > - * @cpu_blit: Validate for cpu blit access. > > * > > * Bit fields are used since these structures are allocated and freed in > > * large numbers and space conservation is desired. > > @@ -50,8 +49,6 @@ struct vmw_validation_bo_node { > > struct ttm_validate_buffer base; > > struct vmwgfx_hash_item hash; > > unsigned int coherent_count; > > - u32 as_mob : 1; > > - u32 cpu_blit : 1; > > }; > > /** > > * struct vmw_validation_res_node - Resource validation metadata. > > @@ -260,26 +257,16 @@ vmw_validation_find_res_dup(struct vmw_validation_context *ctx, > > * vmw_validation_add_bo - Add a buffer object to the validation context. > > * @ctx: The validation context. > > * @vbo: The buffer object. > > - * @as_mob: Validate as mob, otherwise suitable for GMR operations. > > - * @cpu_blit: Validate in a page-mappable location. > > * > > * Return: Zero on success, negative error code otherwise. > > */ > > int vmw_validation_add_bo(struct vmw_validation_context *ctx, > > - struct vmw_bo *vbo, > > - bool as_mob, > > - bool cpu_blit) > > + struct vmw_bo *vbo) > > { > > struct vmw_validation_bo_node *bo_node; > > > > bo_node = vmw_validation_find_bo_dup(ctx, vbo); > > - if (bo_node) { > > - if (bo_node->as_mob != as_mob || > > - bo_node->cpu_blit != cpu_blit) { > > - DRM_ERROR("Inconsistent buffer usage.\n"); > > - return -EINVAL; > > - } > > - } else { > > + if (!bo_node) { > > struct ttm_validate_buffer *val_buf; > > > > bo_node = vmw_validation_mem_alloc(ctx, sizeof(*bo_node)); > > @@ -297,8 +284,6 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, > > return -ESRCH; > > val_buf->num_shared = 0; > > list_add_tail(&val_buf->head, &ctx->bo_list); > > - bo_node->as_mob = as_mob; > > - bo_node->cpu_blit = cpu_blit; > > } > > > > return 0; > > @@ -455,9 +440,10 @@ int vmw_validation_res_reserve(struct vmw_validation_context *ctx, > > if (res->backup) { > > struct vmw_bo *vbo = res->backup; > > > > - ret = vmw_validation_add_bo > > - (ctx, vbo, vmw_resource_needs_backup(res), > > - false); > > + vmw_bo_placement_set(vbo, > > + res->func->domain, > > + res->func->busy_domain); > > + ret = vmw_validation_add_bo(ctx, vbo); > > if (ret) > > goto out_unreserve; > > } > > @@ -519,14 +505,12 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, > > * vmw_validation_bo_validate_single - Validate a single buffer object. > > * @bo: The TTM buffer object base. > > * @interruptible: Whether to perform waits interruptible if possible. > > - * @validate_as_mob: Whether to validate in MOB memory. > > * > > * Return: Zero on success, -ERESTARTSYS if interrupted. Negative error > > * code on failure. > > */ > > -int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, > > - bool interruptible, > > - bool validate_as_mob) > > +static int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, > > + bool interruptible) > > { > > struct vmw_bo *vbo = > > container_of(bo, struct vmw_bo, base); > > @@ -542,27 +526,17 @@ int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, > > if (vbo->base.pin_count > 0) > > return 0; > > > > - if (validate_as_mob) > > - return ttm_bo_validate(bo, &vmw_mob_placement, &ctx); > > - > > - /** > > - * Put BO in VRAM if there is space, otherwise as a GMR. > > - * If there is no space in VRAM and GMR ids are all used up, > > - * start evicting GMRs to make room. If the DMA buffer can't be > > - * used as a GMR, this will return -ENOMEM. > > - */ > > - > > - ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, &ctx); > > + ret = ttm_bo_validate(bo, &vbo->placement, &ctx); > > if (ret == 0 || ret == -ERESTARTSYS) > > return ret; > > > > - /** > > - * If that failed, try VRAM again, this time evicting > > + /* > > + * If that failed, try again, this time evicting > > * previous contents. > > */ > > + ctx.allow_res_evict = true; > > > > - ret = ttm_bo_validate(bo, &vmw_vram_placement, &ctx); > > - return ret; > > + return ttm_bo_validate(bo, &vbo->placement, &ctx); > > } > > > > /** > > @@ -583,18 +557,8 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr) > > struct vmw_bo *vbo = > > container_of(entry->base.bo, typeof(*vbo), base); > > > > - if (entry->cpu_blit) { > > - struct ttm_operation_ctx ttm_ctx = { > > - .interruptible = intr, > > - .no_wait_gpu = false > > - }; > > - > > - ret = ttm_bo_validate(entry->base.bo, > > - &vmw_nonfixed_placement, &ttm_ctx); > > - } else { > > - ret = vmw_validation_bo_validate_single > > - (entry->base.bo, intr, entry->as_mob); > > - } > > + ret = vmw_validation_bo_validate_single(entry->base.bo, intr); > > + > > if (ret) > > return ret; > > > > @@ -655,9 +619,9 @@ int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr) > > if (backup && res->backup && (backup != res->backup)) { > > struct vmw_bo *vbo = res->backup; > > > > - ret = vmw_validation_add_bo > > - (ctx, vbo, vmw_resource_needs_backup(res), > > - false); > > + vmw_bo_placement_set(vbo, res->func->domain, > > + res->func->busy_domain); > > + ret = vmw_validation_add_bo(ctx, vbo); > > if (ret) > > return ret; > > } > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h > > index 4aa4f700c65e..240ee0c4ebfd 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h > > @@ -159,11 +159,7 @@ static inline unsigned int vmw_validation_align(unsigned int val) > > } > > > > int vmw_validation_add_bo(struct vmw_validation_context *ctx, > > - struct vmw_bo *vbo, > > - bool as_mob, bool cpu_blit); > > -int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, > > - bool interruptible, > > - bool validate_as_mob); > > + struct vmw_bo *vbo); > > int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); > > void vmw_validation_unref_lists(struct vmw_validation_context *ctx); > > int vmw_validation_add_resource(struct vmw_validation_context *ctx, > > LGTM! > > Reviewed-by: Maaz Mombasawala <mombasawalam@xxxxxxxxxx> > > -- > Maaz Mombasawala (VMware) <maazm@xxxxxxxxxxxx> >