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 36038ecc50SThomas Hellstrom /** 37*fd567467SThomas Hellstrom * struct vmw_validation_mem - Custom interface to provide memory reservations 38*fd567467SThomas Hellstrom * for the validation code. 39*fd567467SThomas Hellstrom * @reserve_mem: Callback to reserve memory 40*fd567467SThomas Hellstrom * @unreserve_mem: Callback to unreserve memory 41*fd567467SThomas Hellstrom * @gran: Reservation granularity. Contains a hint how much memory should 42*fd567467SThomas Hellstrom * be reserved in each call to @reserve_mem(). A slow implementation may want 43*fd567467SThomas Hellstrom * reservation to be done in large batches. 44*fd567467SThomas Hellstrom */ 45*fd567467SThomas Hellstrom struct vmw_validation_mem { 46*fd567467SThomas Hellstrom int (*reserve_mem)(struct vmw_validation_mem *m, size_t size); 47*fd567467SThomas Hellstrom void (*unreserve_mem)(struct vmw_validation_mem *m, size_t size); 48*fd567467SThomas Hellstrom size_t gran; 49*fd567467SThomas Hellstrom }; 50*fd567467SThomas Hellstrom 51*fd567467SThomas Hellstrom /** 52038ecc50SThomas Hellstrom * struct vmw_validation_context - Per command submission validation context 53038ecc50SThomas Hellstrom * @ht: Hash table used to find resource- or buffer object duplicates 54038ecc50SThomas Hellstrom * @resource_list: List head for resource validation metadata 55038ecc50SThomas Hellstrom * @resource_ctx_list: List head for resource validation metadata for 56038ecc50SThomas Hellstrom * resources that need to be validated before those in @resource_list 57038ecc50SThomas Hellstrom * @bo_list: List head for buffer objects 58fc18afcfSThomas Hellstrom * @page_list: List of pages used by the memory allocator 59038ecc50SThomas Hellstrom * @ticket: Ticked used for ww mutex locking 60038ecc50SThomas Hellstrom * @res_mutex: Pointer to mutex used for resource reserving 61038ecc50SThomas Hellstrom * @merge_dups: Whether to merge metadata for duplicate resources or 62038ecc50SThomas Hellstrom * buffer objects 63fc18afcfSThomas Hellstrom * @mem_size_left: Free memory left in the last page in @page_list 64fc18afcfSThomas Hellstrom * @page_address: Kernel virtual address of the last page in @page_list 65*fd567467SThomas Hellstrom * @vm: A pointer to the memory reservation interface or NULL if no 66*fd567467SThomas Hellstrom * memory reservation is needed. 67*fd567467SThomas Hellstrom * @vm_size_left: Amount of reserved memory that so far has not been allocated. 68*fd567467SThomas Hellstrom * @total_mem: Amount of reserved memory. 69038ecc50SThomas Hellstrom */ 70038ecc50SThomas Hellstrom struct vmw_validation_context { 71038ecc50SThomas Hellstrom struct drm_open_hash *ht; 72038ecc50SThomas Hellstrom struct list_head resource_list; 73038ecc50SThomas Hellstrom struct list_head resource_ctx_list; 74038ecc50SThomas Hellstrom struct list_head bo_list; 75fc18afcfSThomas Hellstrom struct list_head page_list; 76038ecc50SThomas Hellstrom struct ww_acquire_ctx ticket; 77038ecc50SThomas Hellstrom struct mutex *res_mutex; 78038ecc50SThomas Hellstrom unsigned int merge_dups; 79fc18afcfSThomas Hellstrom unsigned int mem_size_left; 80fc18afcfSThomas Hellstrom u8 *page_address; 81*fd567467SThomas Hellstrom struct vmw_validation_mem *vm; 82*fd567467SThomas Hellstrom size_t vm_size_left; 83*fd567467SThomas Hellstrom size_t total_mem; 84038ecc50SThomas Hellstrom }; 85038ecc50SThomas Hellstrom 86038ecc50SThomas Hellstrom struct vmw_buffer_object; 87038ecc50SThomas Hellstrom struct vmw_resource; 88038ecc50SThomas Hellstrom struct vmw_fence_obj; 89038ecc50SThomas Hellstrom 90038ecc50SThomas Hellstrom #if 0 91038ecc50SThomas Hellstrom /** 92038ecc50SThomas Hellstrom * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 93038ecc50SThomas Hellstrom * @_name: The name of the variable 94038ecc50SThomas Hellstrom * @_ht: The hash table used to find dups or NULL if none 95038ecc50SThomas Hellstrom * @_merge_dups: Whether to merge duplicate buffer object- or resource 96038ecc50SThomas Hellstrom * entries. If set to true, ideally a hash table pointer should be supplied 97038ecc50SThomas Hellstrom * as well unless the number of resources and buffer objects per validation 98038ecc50SThomas Hellstrom * is known to be very small 99038ecc50SThomas Hellstrom */ 100038ecc50SThomas Hellstrom #endif 101038ecc50SThomas Hellstrom #define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ 102038ecc50SThomas Hellstrom struct vmw_validation_context _name = \ 103038ecc50SThomas Hellstrom { .ht = _ht, \ 104038ecc50SThomas Hellstrom .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 105038ecc50SThomas Hellstrom .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 106038ecc50SThomas Hellstrom .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 107fc18afcfSThomas Hellstrom .page_list = LIST_HEAD_INIT((_name).page_list), \ 108fc18afcfSThomas Hellstrom .res_mutex = NULL, \ 109038ecc50SThomas Hellstrom .merge_dups = _merge_dups, \ 110fc18afcfSThomas Hellstrom .mem_size_left = 0, \ 111038ecc50SThomas Hellstrom } 112038ecc50SThomas Hellstrom 113038ecc50SThomas Hellstrom /** 114038ecc50SThomas Hellstrom * vmw_validation_has_bos - return whether the validation context has 115038ecc50SThomas Hellstrom * any buffer objects registered. 116038ecc50SThomas Hellstrom * 117038ecc50SThomas Hellstrom * @ctx: The validation context 118038ecc50SThomas Hellstrom * Returns: Whether any buffer objects are registered 119038ecc50SThomas Hellstrom */ 120038ecc50SThomas Hellstrom static inline bool 121038ecc50SThomas Hellstrom vmw_validation_has_bos(struct vmw_validation_context *ctx) 122038ecc50SThomas Hellstrom { 123038ecc50SThomas Hellstrom return !list_empty(&ctx->bo_list); 124038ecc50SThomas Hellstrom } 125038ecc50SThomas Hellstrom 126038ecc50SThomas Hellstrom /** 127*fd567467SThomas Hellstrom * vmw_validation_set_val_mem - Register a validation mem object for 128*fd567467SThomas Hellstrom * validation memory reservation 129*fd567467SThomas Hellstrom * @ctx: The validation context 130*fd567467SThomas Hellstrom * @vm: Pointer to a struct vmw_validation_mem 131*fd567467SThomas Hellstrom * 132*fd567467SThomas Hellstrom * Must be set before the first attempt to allocate validation memory. 133*fd567467SThomas Hellstrom */ 134*fd567467SThomas Hellstrom static inline void 135*fd567467SThomas Hellstrom vmw_validation_set_val_mem(struct vmw_validation_context *ctx, 136*fd567467SThomas Hellstrom struct vmw_validation_mem *vm) 137*fd567467SThomas Hellstrom { 138*fd567467SThomas Hellstrom ctx->vm = vm; 139*fd567467SThomas Hellstrom } 140*fd567467SThomas Hellstrom 141*fd567467SThomas Hellstrom /** 142038ecc50SThomas Hellstrom * vmw_validation_set_ht - Register a hash table for duplicate finding 143038ecc50SThomas Hellstrom * @ctx: The validation context 144038ecc50SThomas Hellstrom * @ht: Pointer to a hash table to use for duplicate finding 145038ecc50SThomas Hellstrom * This function is intended to be used if the hash table wasn't 146038ecc50SThomas Hellstrom * available at validation context declaration time 147038ecc50SThomas Hellstrom */ 148038ecc50SThomas Hellstrom static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, 149038ecc50SThomas Hellstrom struct drm_open_hash *ht) 150038ecc50SThomas Hellstrom { 151038ecc50SThomas Hellstrom ctx->ht = ht; 152038ecc50SThomas Hellstrom } 153038ecc50SThomas Hellstrom 154038ecc50SThomas Hellstrom /** 155038ecc50SThomas Hellstrom * vmw_validation_bo_reserve - Reserve buffer objects registered with a 156038ecc50SThomas Hellstrom * validation context 157038ecc50SThomas Hellstrom * @ctx: The validation context 158038ecc50SThomas Hellstrom * @intr: Perform waits interruptible 159038ecc50SThomas Hellstrom * 160038ecc50SThomas Hellstrom * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 161038ecc50SThomas Hellstrom * code on failure 162038ecc50SThomas Hellstrom */ 163038ecc50SThomas Hellstrom static inline int 164038ecc50SThomas Hellstrom vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 165038ecc50SThomas Hellstrom bool intr) 166038ecc50SThomas Hellstrom { 167038ecc50SThomas Hellstrom return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 168038ecc50SThomas Hellstrom NULL); 169038ecc50SThomas Hellstrom } 170038ecc50SThomas Hellstrom 171038ecc50SThomas Hellstrom /** 172038ecc50SThomas Hellstrom * vmw_validation_bo_backoff - Unreserve buffer objects registered with a 173038ecc50SThomas Hellstrom * validation context 174038ecc50SThomas Hellstrom * @ctx: The validation context 175038ecc50SThomas Hellstrom * 176038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 177038ecc50SThomas Hellstrom * vmw_validation_bo_reserve. It's typically used as part of an error path 178038ecc50SThomas Hellstrom */ 179038ecc50SThomas Hellstrom static inline void 180038ecc50SThomas Hellstrom vmw_validation_bo_backoff(struct vmw_validation_context *ctx) 181038ecc50SThomas Hellstrom { 182038ecc50SThomas Hellstrom ttm_eu_backoff_reservation(&ctx->ticket, &ctx->bo_list); 183038ecc50SThomas Hellstrom } 184038ecc50SThomas Hellstrom 185038ecc50SThomas Hellstrom /** 186038ecc50SThomas Hellstrom * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 187038ecc50SThomas Hellstrom * with a validation context 188038ecc50SThomas Hellstrom * @ctx: The validation context 189038ecc50SThomas Hellstrom * 190038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 191038ecc50SThomas Hellstrom * vmw_validation_bo_reserve, and fences them with a fence object. 192038ecc50SThomas Hellstrom */ 193038ecc50SThomas Hellstrom static inline void 194038ecc50SThomas Hellstrom vmw_validation_bo_fence(struct vmw_validation_context *ctx, 195038ecc50SThomas Hellstrom struct vmw_fence_obj *fence) 196038ecc50SThomas Hellstrom { 197038ecc50SThomas Hellstrom ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 198038ecc50SThomas Hellstrom (void *) fence); 199038ecc50SThomas Hellstrom } 200038ecc50SThomas Hellstrom 201038ecc50SThomas Hellstrom /** 202038ecc50SThomas Hellstrom * vmw_validation_context_init - Initialize a validation context 203038ecc50SThomas Hellstrom * @ctx: Pointer to the validation context to initialize 204038ecc50SThomas Hellstrom * 205038ecc50SThomas Hellstrom * This function initializes a validation context with @merge_dups set 206038ecc50SThomas Hellstrom * to false 207038ecc50SThomas Hellstrom */ 208038ecc50SThomas Hellstrom static inline void 209038ecc50SThomas Hellstrom vmw_validation_context_init(struct vmw_validation_context *ctx) 210038ecc50SThomas Hellstrom { 211038ecc50SThomas Hellstrom memset(ctx, 0, sizeof(*ctx)); 212038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_list); 213038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_ctx_list); 214038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->bo_list); 215038ecc50SThomas Hellstrom } 216038ecc50SThomas Hellstrom 21764ad2abfSThomas Hellstrom /** 21864ad2abfSThomas Hellstrom * vmw_validation_align - Align a validation memory allocation 21964ad2abfSThomas Hellstrom * @val: The size to be aligned 22064ad2abfSThomas Hellstrom * 22164ad2abfSThomas Hellstrom * Returns: @val aligned to the granularity used by the validation memory 22264ad2abfSThomas Hellstrom * allocator. 22364ad2abfSThomas Hellstrom */ 22464ad2abfSThomas Hellstrom static inline unsigned int vmw_validation_align(unsigned int val) 22564ad2abfSThomas Hellstrom { 22664ad2abfSThomas Hellstrom return ALIGN(val, sizeof(long)); 22764ad2abfSThomas Hellstrom } 22864ad2abfSThomas Hellstrom 229038ecc50SThomas Hellstrom int vmw_validation_add_bo(struct vmw_validation_context *ctx, 230038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 231038ecc50SThomas Hellstrom bool as_mob, bool cpu_blit); 232038ecc50SThomas Hellstrom int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 233038ecc50SThomas Hellstrom bool interruptible, 234038ecc50SThomas Hellstrom bool validate_as_mob); 235038ecc50SThomas Hellstrom int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 236038ecc50SThomas Hellstrom void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 237038ecc50SThomas Hellstrom int vmw_validation_add_resource(struct vmw_validation_context *ctx, 238038ecc50SThomas Hellstrom struct vmw_resource *res, 239038ecc50SThomas Hellstrom size_t priv_size, 240038ecc50SThomas Hellstrom void **p_node, 241038ecc50SThomas Hellstrom bool *first_usage); 242038ecc50SThomas Hellstrom void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 243038ecc50SThomas Hellstrom int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 244038ecc50SThomas Hellstrom bool intr); 245038ecc50SThomas Hellstrom void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 246038ecc50SThomas Hellstrom bool backoff); 247038ecc50SThomas Hellstrom void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 248038ecc50SThomas Hellstrom void *val_private, 249038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 250038ecc50SThomas Hellstrom unsigned long backup_offset); 251038ecc50SThomas Hellstrom int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 252038ecc50SThomas Hellstrom 253038ecc50SThomas Hellstrom int vmw_validation_prepare(struct vmw_validation_context *ctx, 254038ecc50SThomas Hellstrom struct mutex *mutex, bool intr); 255038ecc50SThomas Hellstrom void vmw_validation_revert(struct vmw_validation_context *ctx); 256038ecc50SThomas Hellstrom void vmw_validation_done(struct vmw_validation_context *ctx, 257038ecc50SThomas Hellstrom struct vmw_fence_obj *fence); 258038ecc50SThomas Hellstrom 25964ad2abfSThomas Hellstrom void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 26064ad2abfSThomas Hellstrom unsigned int size); 26164ad2abfSThomas Hellstrom int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 26264ad2abfSThomas Hellstrom int vmw_validation_preload_res(struct vmw_validation_context *ctx, 26364ad2abfSThomas Hellstrom unsigned int size); 264038ecc50SThomas Hellstrom #endif 265