1038ecc50SThomas Hellstrom /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2038ecc50SThomas Hellstrom /************************************************************************** 3038ecc50SThomas Hellstrom * 4038ecc50SThomas Hellstrom * Copyright © 2018 VMware, Inc., Palo Alto, CA., USA 5038ecc50SThomas Hellstrom * All Rights Reserved. 6038ecc50SThomas Hellstrom * 7038ecc50SThomas Hellstrom * Permission is hereby granted, free of charge, to any person obtaining a 8038ecc50SThomas Hellstrom * copy of this software and associated documentation files (the 9038ecc50SThomas Hellstrom * "Software"), to deal in the Software without restriction, including 10038ecc50SThomas Hellstrom * without limitation the rights to use, copy, modify, merge, publish, 11038ecc50SThomas Hellstrom * distribute, sub license, and/or sell copies of the Software, and to 12038ecc50SThomas Hellstrom * permit persons to whom the Software is furnished to do so, subject to 13038ecc50SThomas Hellstrom * the following conditions: 14038ecc50SThomas Hellstrom * 15038ecc50SThomas Hellstrom * The above copyright notice and this permission notice (including the 16038ecc50SThomas Hellstrom * next paragraph) shall be included in all copies or substantial portions 17038ecc50SThomas Hellstrom * of the Software. 18038ecc50SThomas Hellstrom * 19038ecc50SThomas Hellstrom * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20038ecc50SThomas Hellstrom * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21038ecc50SThomas Hellstrom * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22038ecc50SThomas Hellstrom * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23038ecc50SThomas Hellstrom * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24038ecc50SThomas Hellstrom * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25038ecc50SThomas Hellstrom * USE OR OTHER DEALINGS IN THE SOFTWARE. 26038ecc50SThomas Hellstrom * 27038ecc50SThomas Hellstrom **************************************************************************/ 28038ecc50SThomas Hellstrom #ifndef _VMWGFX_VALIDATION_H_ 29038ecc50SThomas Hellstrom #define _VMWGFX_VALIDATION_H_ 30038ecc50SThomas Hellstrom 31038ecc50SThomas Hellstrom #include <linux/list.h> 32038ecc50SThomas Hellstrom #include <linux/ww_mutex.h> 33d5c1f011SSam Ravnborg 34d5c1f011SSam Ravnborg #include <drm/drm_hashtab.h> 35038ecc50SThomas Hellstrom #include <drm/ttm/ttm_execbuf_util.h> 36038ecc50SThomas Hellstrom 37a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_NONE 0 38a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_SET BIT(0) 39a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_CLEAR BIT(1) 40a9f58c45SThomas Hellstrom 41038ecc50SThomas Hellstrom /** 42fd567467SThomas Hellstrom * struct vmw_validation_mem - Custom interface to provide memory reservations 43fd567467SThomas Hellstrom * for the validation code. 44fd567467SThomas Hellstrom * @reserve_mem: Callback to reserve memory 45fd567467SThomas Hellstrom * @unreserve_mem: Callback to unreserve memory 46fd567467SThomas Hellstrom * @gran: Reservation granularity. Contains a hint how much memory should 47fd567467SThomas Hellstrom * be reserved in each call to @reserve_mem(). A slow implementation may want 48fd567467SThomas Hellstrom * reservation to be done in large batches. 49fd567467SThomas Hellstrom */ 50fd567467SThomas Hellstrom struct vmw_validation_mem { 51fd567467SThomas Hellstrom int (*reserve_mem)(struct vmw_validation_mem *m, size_t size); 52fd567467SThomas Hellstrom void (*unreserve_mem)(struct vmw_validation_mem *m, size_t size); 53fd567467SThomas Hellstrom size_t gran; 54fd567467SThomas Hellstrom }; 55fd567467SThomas Hellstrom 56fd567467SThomas Hellstrom /** 57038ecc50SThomas Hellstrom * struct vmw_validation_context - Per command submission validation context 58038ecc50SThomas Hellstrom * @ht: Hash table used to find resource- or buffer object duplicates 59038ecc50SThomas Hellstrom * @resource_list: List head for resource validation metadata 60038ecc50SThomas Hellstrom * @resource_ctx_list: List head for resource validation metadata for 61038ecc50SThomas Hellstrom * resources that need to be validated before those in @resource_list 62038ecc50SThomas Hellstrom * @bo_list: List head for buffer objects 63fc18afcfSThomas Hellstrom * @page_list: List of pages used by the memory allocator 64038ecc50SThomas Hellstrom * @ticket: Ticked used for ww mutex locking 65038ecc50SThomas Hellstrom * @res_mutex: Pointer to mutex used for resource reserving 66038ecc50SThomas Hellstrom * @merge_dups: Whether to merge metadata for duplicate resources or 67038ecc50SThomas Hellstrom * buffer objects 68fc18afcfSThomas Hellstrom * @mem_size_left: Free memory left in the last page in @page_list 69fc18afcfSThomas Hellstrom * @page_address: Kernel virtual address of the last page in @page_list 70fd567467SThomas Hellstrom * @vm: A pointer to the memory reservation interface or NULL if no 71fd567467SThomas Hellstrom * memory reservation is needed. 72fd567467SThomas Hellstrom * @vm_size_left: Amount of reserved memory that so far has not been allocated. 73fd567467SThomas Hellstrom * @total_mem: Amount of reserved memory. 74038ecc50SThomas Hellstrom */ 75038ecc50SThomas Hellstrom struct vmw_validation_context { 76038ecc50SThomas Hellstrom struct drm_open_hash *ht; 77038ecc50SThomas Hellstrom struct list_head resource_list; 78038ecc50SThomas Hellstrom struct list_head resource_ctx_list; 79038ecc50SThomas Hellstrom struct list_head bo_list; 80fc18afcfSThomas Hellstrom struct list_head page_list; 81038ecc50SThomas Hellstrom struct ww_acquire_ctx ticket; 82038ecc50SThomas Hellstrom struct mutex *res_mutex; 83038ecc50SThomas Hellstrom unsigned int merge_dups; 84fc18afcfSThomas Hellstrom unsigned int mem_size_left; 85fc18afcfSThomas Hellstrom u8 *page_address; 86fd567467SThomas Hellstrom struct vmw_validation_mem *vm; 87fd567467SThomas Hellstrom size_t vm_size_left; 88fd567467SThomas Hellstrom size_t total_mem; 89038ecc50SThomas Hellstrom }; 90038ecc50SThomas Hellstrom 91038ecc50SThomas Hellstrom struct vmw_buffer_object; 92038ecc50SThomas Hellstrom struct vmw_resource; 93038ecc50SThomas Hellstrom struct vmw_fence_obj; 94038ecc50SThomas Hellstrom 95038ecc50SThomas Hellstrom #if 0 96038ecc50SThomas Hellstrom /** 97038ecc50SThomas Hellstrom * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 98038ecc50SThomas Hellstrom * @_name: The name of the variable 99038ecc50SThomas Hellstrom * @_ht: The hash table used to find dups or NULL if none 100038ecc50SThomas Hellstrom * @_merge_dups: Whether to merge duplicate buffer object- or resource 101038ecc50SThomas Hellstrom * entries. If set to true, ideally a hash table pointer should be supplied 102038ecc50SThomas Hellstrom * as well unless the number of resources and buffer objects per validation 103038ecc50SThomas Hellstrom * is known to be very small 104038ecc50SThomas Hellstrom */ 105038ecc50SThomas Hellstrom #endif 106038ecc50SThomas Hellstrom #define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ 107038ecc50SThomas Hellstrom struct vmw_validation_context _name = \ 108038ecc50SThomas Hellstrom { .ht = _ht, \ 109038ecc50SThomas Hellstrom .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 110038ecc50SThomas Hellstrom .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 111038ecc50SThomas Hellstrom .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 112fc18afcfSThomas Hellstrom .page_list = LIST_HEAD_INIT((_name).page_list), \ 113fc18afcfSThomas Hellstrom .res_mutex = NULL, \ 114038ecc50SThomas Hellstrom .merge_dups = _merge_dups, \ 115fc18afcfSThomas Hellstrom .mem_size_left = 0, \ 116038ecc50SThomas Hellstrom } 117038ecc50SThomas Hellstrom 118038ecc50SThomas Hellstrom /** 119038ecc50SThomas Hellstrom * vmw_validation_has_bos - return whether the validation context has 120038ecc50SThomas Hellstrom * any buffer objects registered. 121038ecc50SThomas Hellstrom * 122038ecc50SThomas Hellstrom * @ctx: The validation context 123038ecc50SThomas Hellstrom * Returns: Whether any buffer objects are registered 124038ecc50SThomas Hellstrom */ 125038ecc50SThomas Hellstrom static inline bool 126038ecc50SThomas Hellstrom vmw_validation_has_bos(struct vmw_validation_context *ctx) 127038ecc50SThomas Hellstrom { 128038ecc50SThomas Hellstrom return !list_empty(&ctx->bo_list); 129038ecc50SThomas Hellstrom } 130038ecc50SThomas Hellstrom 131038ecc50SThomas Hellstrom /** 132fd567467SThomas Hellstrom * vmw_validation_set_val_mem - Register a validation mem object for 133fd567467SThomas Hellstrom * validation memory reservation 134fd567467SThomas Hellstrom * @ctx: The validation context 135fd567467SThomas Hellstrom * @vm: Pointer to a struct vmw_validation_mem 136fd567467SThomas Hellstrom * 137fd567467SThomas Hellstrom * Must be set before the first attempt to allocate validation memory. 138fd567467SThomas Hellstrom */ 139fd567467SThomas Hellstrom static inline void 140fd567467SThomas Hellstrom vmw_validation_set_val_mem(struct vmw_validation_context *ctx, 141fd567467SThomas Hellstrom struct vmw_validation_mem *vm) 142fd567467SThomas Hellstrom { 143fd567467SThomas Hellstrom ctx->vm = vm; 144fd567467SThomas Hellstrom } 145fd567467SThomas Hellstrom 146fd567467SThomas Hellstrom /** 147038ecc50SThomas Hellstrom * vmw_validation_set_ht - Register a hash table for duplicate finding 148038ecc50SThomas Hellstrom * @ctx: The validation context 149038ecc50SThomas Hellstrom * @ht: Pointer to a hash table to use for duplicate finding 150038ecc50SThomas Hellstrom * This function is intended to be used if the hash table wasn't 151038ecc50SThomas Hellstrom * available at validation context declaration time 152038ecc50SThomas Hellstrom */ 153038ecc50SThomas Hellstrom static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, 154038ecc50SThomas Hellstrom struct drm_open_hash *ht) 155038ecc50SThomas Hellstrom { 156038ecc50SThomas Hellstrom ctx->ht = ht; 157038ecc50SThomas Hellstrom } 158038ecc50SThomas Hellstrom 159038ecc50SThomas Hellstrom /** 160038ecc50SThomas Hellstrom * vmw_validation_bo_reserve - Reserve buffer objects registered with a 161038ecc50SThomas Hellstrom * validation context 162038ecc50SThomas Hellstrom * @ctx: The validation context 163038ecc50SThomas Hellstrom * @intr: Perform waits interruptible 164038ecc50SThomas Hellstrom * 165038ecc50SThomas Hellstrom * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 166038ecc50SThomas Hellstrom * code on failure 167038ecc50SThomas Hellstrom */ 168038ecc50SThomas Hellstrom static inline int 169038ecc50SThomas Hellstrom vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 170038ecc50SThomas Hellstrom bool intr) 171038ecc50SThomas Hellstrom { 172038ecc50SThomas Hellstrom return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 1739165fb87SChristian König NULL); 174038ecc50SThomas Hellstrom } 175038ecc50SThomas Hellstrom 176038ecc50SThomas Hellstrom /** 177038ecc50SThomas Hellstrom * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 178038ecc50SThomas Hellstrom * with a validation context 179038ecc50SThomas Hellstrom * @ctx: The validation context 180038ecc50SThomas Hellstrom * 181038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 182038ecc50SThomas Hellstrom * vmw_validation_bo_reserve, and fences them with a fence object. 183038ecc50SThomas Hellstrom */ 184038ecc50SThomas Hellstrom static inline void 185038ecc50SThomas Hellstrom vmw_validation_bo_fence(struct vmw_validation_context *ctx, 186038ecc50SThomas Hellstrom struct vmw_fence_obj *fence) 187038ecc50SThomas Hellstrom { 188038ecc50SThomas Hellstrom ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 189038ecc50SThomas Hellstrom (void *) fence); 190038ecc50SThomas Hellstrom } 191038ecc50SThomas Hellstrom 192038ecc50SThomas Hellstrom /** 193038ecc50SThomas Hellstrom * vmw_validation_context_init - Initialize a validation context 194038ecc50SThomas Hellstrom * @ctx: Pointer to the validation context to initialize 195038ecc50SThomas Hellstrom * 196038ecc50SThomas Hellstrom * This function initializes a validation context with @merge_dups set 197038ecc50SThomas Hellstrom * to false 198038ecc50SThomas Hellstrom */ 199038ecc50SThomas Hellstrom static inline void 200038ecc50SThomas Hellstrom vmw_validation_context_init(struct vmw_validation_context *ctx) 201038ecc50SThomas Hellstrom { 202038ecc50SThomas Hellstrom memset(ctx, 0, sizeof(*ctx)); 203038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_list); 204038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_ctx_list); 205038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->bo_list); 206038ecc50SThomas Hellstrom } 207038ecc50SThomas Hellstrom 20864ad2abfSThomas Hellstrom /** 20964ad2abfSThomas Hellstrom * vmw_validation_align - Align a validation memory allocation 21064ad2abfSThomas Hellstrom * @val: The size to be aligned 21164ad2abfSThomas Hellstrom * 21264ad2abfSThomas Hellstrom * Returns: @val aligned to the granularity used by the validation memory 21364ad2abfSThomas Hellstrom * allocator. 21464ad2abfSThomas Hellstrom */ 21564ad2abfSThomas Hellstrom static inline unsigned int vmw_validation_align(unsigned int val) 21664ad2abfSThomas Hellstrom { 21764ad2abfSThomas Hellstrom return ALIGN(val, sizeof(long)); 21864ad2abfSThomas Hellstrom } 21964ad2abfSThomas Hellstrom 220038ecc50SThomas Hellstrom int vmw_validation_add_bo(struct vmw_validation_context *ctx, 221038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 222038ecc50SThomas Hellstrom bool as_mob, bool cpu_blit); 223038ecc50SThomas Hellstrom int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 224038ecc50SThomas Hellstrom bool interruptible, 225038ecc50SThomas Hellstrom bool validate_as_mob); 226038ecc50SThomas Hellstrom int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 227038ecc50SThomas Hellstrom void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 228038ecc50SThomas Hellstrom int vmw_validation_add_resource(struct vmw_validation_context *ctx, 229038ecc50SThomas Hellstrom struct vmw_resource *res, 230038ecc50SThomas Hellstrom size_t priv_size, 231a9f58c45SThomas Hellstrom u32 dirty, 232038ecc50SThomas Hellstrom void **p_node, 233038ecc50SThomas Hellstrom bool *first_usage); 234038ecc50SThomas Hellstrom void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 235038ecc50SThomas Hellstrom int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 236038ecc50SThomas Hellstrom bool intr); 237038ecc50SThomas Hellstrom void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 238038ecc50SThomas Hellstrom bool backoff); 239038ecc50SThomas Hellstrom void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 240038ecc50SThomas Hellstrom void *val_private, 241038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 242038ecc50SThomas Hellstrom unsigned long backup_offset); 243038ecc50SThomas Hellstrom int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 244038ecc50SThomas Hellstrom 245038ecc50SThomas Hellstrom int vmw_validation_prepare(struct vmw_validation_context *ctx, 246038ecc50SThomas Hellstrom struct mutex *mutex, bool intr); 247038ecc50SThomas Hellstrom void vmw_validation_revert(struct vmw_validation_context *ctx); 248038ecc50SThomas Hellstrom void vmw_validation_done(struct vmw_validation_context *ctx, 249038ecc50SThomas Hellstrom struct vmw_fence_obj *fence); 250038ecc50SThomas Hellstrom 25164ad2abfSThomas Hellstrom void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 25264ad2abfSThomas Hellstrom unsigned int size); 25364ad2abfSThomas Hellstrom int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 25464ad2abfSThomas Hellstrom int vmw_validation_preload_res(struct vmw_validation_context *ctx, 25564ad2abfSThomas Hellstrom unsigned int size); 256a9f58c45SThomas Hellstrom void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, 257a9f58c45SThomas Hellstrom void *val_private, u32 dirty); 258*b7468b15SThomas Hellstrom void vmw_validation_bo_backoff(struct vmw_validation_context *ctx); 259*b7468b15SThomas Hellstrom 260038ecc50SThomas Hellstrom #endif 261