drm/vmwgfx: Implement an infrastructure for write-coherent resources
This infrastructure will, for coherent resources, make sure that from the user-space point of view, data written by the CPU is immediately automatically available to the GPU at resource validation time. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Will Deacon <will.deacon@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@surriel.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Jérôme Glisse <jglisse@redhat.com> Cc: Kirill A. Shutemov <kirill@shutemov.name> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Deepak Rawat <drawat@vmware.com>
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
* struct vmw_validation_bo_node - Buffer object validation metadata.
|
||||
* @base: Metadata used for TTM reservation- and validation.
|
||||
* @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.
|
||||
*
|
||||
@@ -42,6 +44,7 @@
|
||||
struct vmw_validation_bo_node {
|
||||
struct ttm_validate_buffer base;
|
||||
struct drm_hash_item hash;
|
||||
unsigned int coherent_count;
|
||||
u32 as_mob : 1;
|
||||
u32 cpu_blit : 1;
|
||||
};
|
||||
@@ -459,6 +462,19 @@ int vmw_validation_res_reserve(struct vmw_validation_context *ctx,
|
||||
if (ret)
|
||||
goto out_unreserve;
|
||||
}
|
||||
|
||||
if (val->switching_backup && val->new_backup &&
|
||||
res->coherent) {
|
||||
struct vmw_validation_bo_node *bo_node =
|
||||
vmw_validation_find_bo_dup(ctx,
|
||||
val->new_backup);
|
||||
|
||||
if (WARN_ON(!bo_node)) {
|
||||
ret = -EINVAL;
|
||||
goto out_unreserve;
|
||||
}
|
||||
bo_node->coherent_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -565,6 +581,9 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr)
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(entry, &ctx->bo_list, base.head) {
|
||||
struct vmw_buffer_object *vbo =
|
||||
container_of(entry->base.bo, typeof(*vbo), base);
|
||||
|
||||
if (entry->cpu_blit) {
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = intr,
|
||||
@@ -579,6 +598,27 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr)
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Rather than having the resource code allocating the bo
|
||||
* dirty tracker in resource_unreserve() where we can't fail,
|
||||
* Do it here when validating the buffer object.
|
||||
*/
|
||||
if (entry->coherent_count) {
|
||||
unsigned int coherent_count = entry->coherent_count;
|
||||
|
||||
while (coherent_count) {
|
||||
ret = vmw_bo_dirty_add(vbo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
coherent_count--;
|
||||
}
|
||||
entry->coherent_count -= coherent_count;
|
||||
}
|
||||
|
||||
if (vbo->dirty)
|
||||
vmw_bo_dirty_scan(vbo);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -831,3 +871,34 @@ int vmw_validation_preload_res(struct vmw_validation_context *ctx,
|
||||
ctx->mem_size_left += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_validation_bo_backoff - Unreserve buffer objects registered with a
|
||||
* validation context
|
||||
* @ctx: The validation context
|
||||
*
|
||||
* This function unreserves the buffer objects previously reserved using
|
||||
* vmw_validation_bo_reserve. It's typically used as part of an error path
|
||||
*/
|
||||
void vmw_validation_bo_backoff(struct vmw_validation_context *ctx)
|
||||
{
|
||||
struct vmw_validation_bo_node *entry;
|
||||
|
||||
/*
|
||||
* Switching coherent resource backup buffers failed.
|
||||
* Release corresponding buffer object dirty trackers.
|
||||
*/
|
||||
list_for_each_entry(entry, &ctx->bo_list, base.head) {
|
||||
if (entry->coherent_count) {
|
||||
unsigned int coherent_count = entry->coherent_count;
|
||||
struct vmw_buffer_object *vbo =
|
||||
container_of(entry->base.bo, typeof(*vbo),
|
||||
base);
|
||||
|
||||
while (coherent_count--)
|
||||
vmw_bo_dirty_release(vbo);
|
||||
}
|
||||
}
|
||||
|
||||
ttm_eu_backoff_reservation(&ctx->ticket, &ctx->bo_list);
|
||||
}
|
||||
|
Reference in New Issue
Block a user