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 <drm/drm_hashtab.h> 32038ecc50SThomas Hellstrom #include <linux/list.h> 33038ecc50SThomas Hellstrom #include <linux/ww_mutex.h> 34038ecc50SThomas Hellstrom #include <drm/ttm/ttm_execbuf_util.h> 35038ecc50SThomas Hellstrom 36a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_NONE 0 37a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_SET BIT(0) 38a9f58c45SThomas Hellstrom #define VMW_RES_DIRTY_CLEAR BIT(1) 39a9f58c45SThomas Hellstrom 40038ecc50SThomas Hellstrom /** 41fd567467SThomas Hellstrom * struct vmw_validation_mem - Custom interface to provide memory reservations 42fd567467SThomas Hellstrom * for the validation code. 43fd567467SThomas Hellstrom * @reserve_mem: Callback to reserve memory 44fd567467SThomas Hellstrom * @unreserve_mem: Callback to unreserve memory 45fd567467SThomas Hellstrom * @gran: Reservation granularity. Contains a hint how much memory should 46fd567467SThomas Hellstrom * be reserved in each call to @reserve_mem(). A slow implementation may want 47fd567467SThomas Hellstrom * reservation to be done in large batches. 48fd567467SThomas Hellstrom */ 49fd567467SThomas Hellstrom struct vmw_validation_mem { 50fd567467SThomas Hellstrom int (*reserve_mem)(struct vmw_validation_mem *m, size_t size); 51fd567467SThomas Hellstrom void (*unreserve_mem)(struct vmw_validation_mem *m, size_t size); 52fd567467SThomas Hellstrom size_t gran; 53fd567467SThomas Hellstrom }; 54fd567467SThomas Hellstrom 55fd567467SThomas Hellstrom /** 56038ecc50SThomas Hellstrom * struct vmw_validation_context - Per command submission validation context 57038ecc50SThomas Hellstrom * @ht: Hash table used to find resource- or buffer object duplicates 58038ecc50SThomas Hellstrom * @resource_list: List head for resource validation metadata 59038ecc50SThomas Hellstrom * @resource_ctx_list: List head for resource validation metadata for 60038ecc50SThomas Hellstrom * resources that need to be validated before those in @resource_list 61038ecc50SThomas Hellstrom * @bo_list: List head for buffer objects 62fc18afcfSThomas Hellstrom * @page_list: List of pages used by the memory allocator 63038ecc50SThomas Hellstrom * @ticket: Ticked used for ww mutex locking 64038ecc50SThomas Hellstrom * @res_mutex: Pointer to mutex used for resource reserving 65038ecc50SThomas Hellstrom * @merge_dups: Whether to merge metadata for duplicate resources or 66038ecc50SThomas Hellstrom * buffer objects 67fc18afcfSThomas Hellstrom * @mem_size_left: Free memory left in the last page in @page_list 68fc18afcfSThomas Hellstrom * @page_address: Kernel virtual address of the last page in @page_list 69fd567467SThomas Hellstrom * @vm: A pointer to the memory reservation interface or NULL if no 70fd567467SThomas Hellstrom * memory reservation is needed. 71fd567467SThomas Hellstrom * @vm_size_left: Amount of reserved memory that so far has not been allocated. 72fd567467SThomas Hellstrom * @total_mem: Amount of reserved memory. 73038ecc50SThomas Hellstrom */ 74038ecc50SThomas Hellstrom struct vmw_validation_context { 75038ecc50SThomas Hellstrom struct drm_open_hash *ht; 76038ecc50SThomas Hellstrom struct list_head resource_list; 77038ecc50SThomas Hellstrom struct list_head resource_ctx_list; 78038ecc50SThomas Hellstrom struct list_head bo_list; 79fc18afcfSThomas Hellstrom struct list_head page_list; 80038ecc50SThomas Hellstrom struct ww_acquire_ctx ticket; 81038ecc50SThomas Hellstrom struct mutex *res_mutex; 82038ecc50SThomas Hellstrom unsigned int merge_dups; 83fc18afcfSThomas Hellstrom unsigned int mem_size_left; 84fc18afcfSThomas Hellstrom u8 *page_address; 85fd567467SThomas Hellstrom struct vmw_validation_mem *vm; 86fd567467SThomas Hellstrom size_t vm_size_left; 87fd567467SThomas Hellstrom size_t total_mem; 88038ecc50SThomas Hellstrom }; 89038ecc50SThomas Hellstrom 90038ecc50SThomas Hellstrom struct vmw_buffer_object; 91038ecc50SThomas Hellstrom struct vmw_resource; 92038ecc50SThomas Hellstrom struct vmw_fence_obj; 93038ecc50SThomas Hellstrom 94038ecc50SThomas Hellstrom #if 0 95038ecc50SThomas Hellstrom /** 96038ecc50SThomas Hellstrom * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 97038ecc50SThomas Hellstrom * @_name: The name of the variable 98038ecc50SThomas Hellstrom * @_ht: The hash table used to find dups or NULL if none 99038ecc50SThomas Hellstrom * @_merge_dups: Whether to merge duplicate buffer object- or resource 100038ecc50SThomas Hellstrom * entries. If set to true, ideally a hash table pointer should be supplied 101038ecc50SThomas Hellstrom * as well unless the number of resources and buffer objects per validation 102038ecc50SThomas Hellstrom * is known to be very small 103038ecc50SThomas Hellstrom */ 104038ecc50SThomas Hellstrom #endif 105038ecc50SThomas Hellstrom #define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ 106038ecc50SThomas Hellstrom struct vmw_validation_context _name = \ 107038ecc50SThomas Hellstrom { .ht = _ht, \ 108038ecc50SThomas Hellstrom .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 109038ecc50SThomas Hellstrom .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 110038ecc50SThomas Hellstrom .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 111fc18afcfSThomas Hellstrom .page_list = LIST_HEAD_INIT((_name).page_list), \ 112fc18afcfSThomas Hellstrom .res_mutex = NULL, \ 113038ecc50SThomas Hellstrom .merge_dups = _merge_dups, \ 114fc18afcfSThomas Hellstrom .mem_size_left = 0, \ 115038ecc50SThomas Hellstrom } 116038ecc50SThomas Hellstrom 117038ecc50SThomas Hellstrom /** 118038ecc50SThomas Hellstrom * vmw_validation_has_bos - return whether the validation context has 119038ecc50SThomas Hellstrom * any buffer objects registered. 120038ecc50SThomas Hellstrom * 121038ecc50SThomas Hellstrom * @ctx: The validation context 122038ecc50SThomas Hellstrom * Returns: Whether any buffer objects are registered 123038ecc50SThomas Hellstrom */ 124038ecc50SThomas Hellstrom static inline bool 125038ecc50SThomas Hellstrom vmw_validation_has_bos(struct vmw_validation_context *ctx) 126038ecc50SThomas Hellstrom { 127038ecc50SThomas Hellstrom return !list_empty(&ctx->bo_list); 128038ecc50SThomas Hellstrom } 129038ecc50SThomas Hellstrom 130038ecc50SThomas Hellstrom /** 131fd567467SThomas Hellstrom * vmw_validation_set_val_mem - Register a validation mem object for 132fd567467SThomas Hellstrom * validation memory reservation 133fd567467SThomas Hellstrom * @ctx: The validation context 134fd567467SThomas Hellstrom * @vm: Pointer to a struct vmw_validation_mem 135fd567467SThomas Hellstrom * 136fd567467SThomas Hellstrom * Must be set before the first attempt to allocate validation memory. 137fd567467SThomas Hellstrom */ 138fd567467SThomas Hellstrom static inline void 139fd567467SThomas Hellstrom vmw_validation_set_val_mem(struct vmw_validation_context *ctx, 140fd567467SThomas Hellstrom struct vmw_validation_mem *vm) 141fd567467SThomas Hellstrom { 142fd567467SThomas Hellstrom ctx->vm = vm; 143fd567467SThomas Hellstrom } 144fd567467SThomas Hellstrom 145fd567467SThomas Hellstrom /** 146038ecc50SThomas Hellstrom * vmw_validation_set_ht - Register a hash table for duplicate finding 147038ecc50SThomas Hellstrom * @ctx: The validation context 148038ecc50SThomas Hellstrom * @ht: Pointer to a hash table to use for duplicate finding 149038ecc50SThomas Hellstrom * This function is intended to be used if the hash table wasn't 150038ecc50SThomas Hellstrom * available at validation context declaration time 151038ecc50SThomas Hellstrom */ 152038ecc50SThomas Hellstrom static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, 153038ecc50SThomas Hellstrom struct drm_open_hash *ht) 154038ecc50SThomas Hellstrom { 155038ecc50SThomas Hellstrom ctx->ht = ht; 156038ecc50SThomas Hellstrom } 157038ecc50SThomas Hellstrom 158038ecc50SThomas Hellstrom /** 159038ecc50SThomas Hellstrom * vmw_validation_bo_reserve - Reserve buffer objects registered with a 160038ecc50SThomas Hellstrom * validation context 161038ecc50SThomas Hellstrom * @ctx: The validation context 162038ecc50SThomas Hellstrom * @intr: Perform waits interruptible 163038ecc50SThomas Hellstrom * 164038ecc50SThomas Hellstrom * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 165038ecc50SThomas Hellstrom * code on failure 166038ecc50SThomas Hellstrom */ 167038ecc50SThomas Hellstrom static inline int 168038ecc50SThomas Hellstrom vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 169038ecc50SThomas Hellstrom bool intr) 170038ecc50SThomas Hellstrom { 171038ecc50SThomas Hellstrom return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 1726e58ab7aSChristian König NULL, true); 173038ecc50SThomas Hellstrom } 174038ecc50SThomas Hellstrom 175038ecc50SThomas Hellstrom /** 176*3729fe2bSDave Airlie * vmw_validation_bo_backoff - Unreserve buffer objects registered with a 177*3729fe2bSDave Airlie * validation context 178*3729fe2bSDave Airlie * @ctx: The validation context 179*3729fe2bSDave Airlie * 180*3729fe2bSDave Airlie * This function unreserves the buffer objects previously reserved using 181*3729fe2bSDave Airlie * vmw_validation_bo_reserve. It's typically used as part of an error path 182*3729fe2bSDave Airlie */ 183*3729fe2bSDave Airlie static inline void 184*3729fe2bSDave Airlie vmw_validation_bo_backoff(struct vmw_validation_context *ctx) 185*3729fe2bSDave Airlie { 186*3729fe2bSDave Airlie ttm_eu_backoff_reservation(&ctx->ticket, &ctx->bo_list); 187*3729fe2bSDave Airlie } 188*3729fe2bSDave Airlie 189*3729fe2bSDave Airlie /** 190038ecc50SThomas Hellstrom * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 191038ecc50SThomas Hellstrom * with a validation context 192038ecc50SThomas Hellstrom * @ctx: The validation context 193038ecc50SThomas Hellstrom * 194038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 195038ecc50SThomas Hellstrom * vmw_validation_bo_reserve, and fences them with a fence object. 196038ecc50SThomas Hellstrom */ 197038ecc50SThomas Hellstrom static inline void 198038ecc50SThomas Hellstrom vmw_validation_bo_fence(struct vmw_validation_context *ctx, 199038ecc50SThomas Hellstrom struct vmw_fence_obj *fence) 200038ecc50SThomas Hellstrom { 201038ecc50SThomas Hellstrom ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 202038ecc50SThomas Hellstrom (void *) fence); 203038ecc50SThomas Hellstrom } 204038ecc50SThomas Hellstrom 205038ecc50SThomas Hellstrom /** 206038ecc50SThomas Hellstrom * vmw_validation_context_init - Initialize a validation context 207038ecc50SThomas Hellstrom * @ctx: Pointer to the validation context to initialize 208038ecc50SThomas Hellstrom * 209038ecc50SThomas Hellstrom * This function initializes a validation context with @merge_dups set 210038ecc50SThomas Hellstrom * to false 211038ecc50SThomas Hellstrom */ 212038ecc50SThomas Hellstrom static inline void 213038ecc50SThomas Hellstrom vmw_validation_context_init(struct vmw_validation_context *ctx) 214038ecc50SThomas Hellstrom { 215038ecc50SThomas Hellstrom memset(ctx, 0, sizeof(*ctx)); 216038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_list); 217038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_ctx_list); 218038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->bo_list); 219038ecc50SThomas Hellstrom } 220038ecc50SThomas Hellstrom 22164ad2abfSThomas Hellstrom /** 22264ad2abfSThomas Hellstrom * vmw_validation_align - Align a validation memory allocation 22364ad2abfSThomas Hellstrom * @val: The size to be aligned 22464ad2abfSThomas Hellstrom * 22564ad2abfSThomas Hellstrom * Returns: @val aligned to the granularity used by the validation memory 22664ad2abfSThomas Hellstrom * allocator. 22764ad2abfSThomas Hellstrom */ 22864ad2abfSThomas Hellstrom static inline unsigned int vmw_validation_align(unsigned int val) 22964ad2abfSThomas Hellstrom { 23064ad2abfSThomas Hellstrom return ALIGN(val, sizeof(long)); 23164ad2abfSThomas Hellstrom } 23264ad2abfSThomas Hellstrom 233038ecc50SThomas Hellstrom int vmw_validation_add_bo(struct vmw_validation_context *ctx, 234038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 235038ecc50SThomas Hellstrom bool as_mob, bool cpu_blit); 236038ecc50SThomas Hellstrom int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 237038ecc50SThomas Hellstrom bool interruptible, 238038ecc50SThomas Hellstrom bool validate_as_mob); 239038ecc50SThomas Hellstrom int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 240038ecc50SThomas Hellstrom void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 241038ecc50SThomas Hellstrom int vmw_validation_add_resource(struct vmw_validation_context *ctx, 242038ecc50SThomas Hellstrom struct vmw_resource *res, 243038ecc50SThomas Hellstrom size_t priv_size, 244a9f58c45SThomas Hellstrom u32 dirty, 245038ecc50SThomas Hellstrom void **p_node, 246038ecc50SThomas Hellstrom bool *first_usage); 247038ecc50SThomas Hellstrom void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 248038ecc50SThomas Hellstrom int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 249038ecc50SThomas Hellstrom bool intr); 250038ecc50SThomas Hellstrom void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 251038ecc50SThomas Hellstrom bool backoff); 252038ecc50SThomas Hellstrom void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 253038ecc50SThomas Hellstrom void *val_private, 254038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 255038ecc50SThomas Hellstrom unsigned long backup_offset); 256038ecc50SThomas Hellstrom int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 257038ecc50SThomas Hellstrom 258038ecc50SThomas Hellstrom int vmw_validation_prepare(struct vmw_validation_context *ctx, 259038ecc50SThomas Hellstrom struct mutex *mutex, bool intr); 260038ecc50SThomas Hellstrom void vmw_validation_revert(struct vmw_validation_context *ctx); 261038ecc50SThomas Hellstrom void vmw_validation_done(struct vmw_validation_context *ctx, 262038ecc50SThomas Hellstrom struct vmw_fence_obj *fence); 263038ecc50SThomas Hellstrom 26464ad2abfSThomas Hellstrom void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 26564ad2abfSThomas Hellstrom unsigned int size); 26664ad2abfSThomas Hellstrom int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 26764ad2abfSThomas Hellstrom int vmw_validation_preload_res(struct vmw_validation_context *ctx, 26864ad2abfSThomas Hellstrom unsigned int size); 269a9f58c45SThomas Hellstrom void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, 270a9f58c45SThomas Hellstrom void *val_private, u32 dirty); 271038ecc50SThomas Hellstrom #endif 272