1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 /************************************************************************** 3 * 4 * Copyright © 2018 - 2022 VMware, Inc., Palo Alto, CA., USA 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25 * USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 #ifndef _VMWGFX_VALIDATION_H_ 29 #define _VMWGFX_VALIDATION_H_ 30 31 #include <linux/list.h> 32 #include <linux/hashtable.h> 33 #include <linux/ww_mutex.h> 34 35 #include <drm/ttm/ttm_execbuf_util.h> 36 37 #define VMW_RES_DIRTY_NONE 0 38 #define VMW_RES_DIRTY_SET BIT(0) 39 #define VMW_RES_DIRTY_CLEAR BIT(1) 40 41 /** 42 * struct vmw_validation_context - Per command submission validation context 43 * @ht: Hash table used to find resource- or buffer object duplicates 44 * @resource_list: List head for resource validation metadata 45 * @resource_ctx_list: List head for resource validation metadata for 46 * resources that need to be validated before those in @resource_list 47 * @bo_list: List head for buffer objects 48 * @page_list: List of pages used by the memory allocator 49 * @ticket: Ticked used for ww mutex locking 50 * @res_mutex: Pointer to mutex used for resource reserving 51 * @merge_dups: Whether to merge metadata for duplicate resources or 52 * buffer objects 53 * @mem_size_left: Free memory left in the last page in @page_list 54 * @page_address: Kernel virtual address of the last page in @page_list 55 * @vm: A pointer to the memory reservation interface or NULL if no 56 * memory reservation is needed. 57 * @vm_size_left: Amount of reserved memory that so far has not been allocated. 58 * @total_mem: Amount of reserved memory. 59 */ 60 struct vmw_validation_context { 61 struct vmw_sw_context *sw_context; 62 struct list_head resource_list; 63 struct list_head resource_ctx_list; 64 struct list_head bo_list; 65 struct list_head page_list; 66 struct ww_acquire_ctx ticket; 67 struct mutex *res_mutex; 68 unsigned int merge_dups; 69 unsigned int mem_size_left; 70 u8 *page_address; 71 struct vmw_validation_mem *vm; 72 size_t vm_size_left; 73 size_t total_mem; 74 }; 75 76 struct vmw_buffer_object; 77 struct vmw_resource; 78 struct vmw_fence_obj; 79 80 #if 0 81 /** 82 * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 83 * @_name: The name of the variable 84 * @_sw_context: Contains the hash table used to find dups or NULL if none 85 * @_merge_dups: Whether to merge duplicate buffer object- or resource 86 * entries. If set to true, ideally a hash table pointer should be supplied 87 * as well unless the number of resources and buffer objects per validation 88 * is known to be very small 89 */ 90 #endif 91 #define DECLARE_VAL_CONTEXT(_name, _sw_context, _merge_dups) \ 92 struct vmw_validation_context _name = \ 93 { .sw_context = _sw_context, \ 94 .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 95 .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 96 .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 97 .page_list = LIST_HEAD_INIT((_name).page_list), \ 98 .res_mutex = NULL, \ 99 .merge_dups = _merge_dups, \ 100 .mem_size_left = 0, \ 101 } 102 103 /** 104 * vmw_validation_has_bos - return whether the validation context has 105 * any buffer objects registered. 106 * 107 * @ctx: The validation context 108 * Returns: Whether any buffer objects are registered 109 */ 110 static inline bool 111 vmw_validation_has_bos(struct vmw_validation_context *ctx) 112 { 113 return !list_empty(&ctx->bo_list); 114 } 115 116 /** 117 * vmw_validation_bo_reserve - Reserve buffer objects registered with a 118 * validation context 119 * @ctx: The validation context 120 * @intr: Perform waits interruptible 121 * 122 * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 123 * code on failure 124 */ 125 static inline int 126 vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 127 bool intr) 128 { 129 return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 130 NULL); 131 } 132 133 /** 134 * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 135 * with a validation context 136 * @ctx: The validation context 137 * 138 * This function unreserves the buffer objects previously reserved using 139 * vmw_validation_bo_reserve, and fences them with a fence object. 140 */ 141 static inline void 142 vmw_validation_bo_fence(struct vmw_validation_context *ctx, 143 struct vmw_fence_obj *fence) 144 { 145 ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 146 (void *) fence); 147 } 148 149 /** 150 * vmw_validation_align - Align a validation memory allocation 151 * @val: The size to be aligned 152 * 153 * Returns: @val aligned to the granularity used by the validation memory 154 * allocator. 155 */ 156 static inline unsigned int vmw_validation_align(unsigned int val) 157 { 158 return ALIGN(val, sizeof(long)); 159 } 160 161 int vmw_validation_add_bo(struct vmw_validation_context *ctx, 162 struct vmw_buffer_object *vbo, 163 bool as_mob, bool cpu_blit); 164 int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 165 bool interruptible, 166 bool validate_as_mob); 167 int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 168 void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 169 int vmw_validation_add_resource(struct vmw_validation_context *ctx, 170 struct vmw_resource *res, 171 size_t priv_size, 172 u32 dirty, 173 void **p_node, 174 bool *first_usage); 175 void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 176 int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 177 bool intr); 178 void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 179 bool backoff); 180 void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 181 void *val_private, 182 struct vmw_buffer_object *vbo, 183 unsigned long backup_offset); 184 int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 185 186 int vmw_validation_prepare(struct vmw_validation_context *ctx, 187 struct mutex *mutex, bool intr); 188 void vmw_validation_revert(struct vmw_validation_context *ctx); 189 void vmw_validation_done(struct vmw_validation_context *ctx, 190 struct vmw_fence_obj *fence); 191 192 void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 193 unsigned int size); 194 int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 195 int vmw_validation_preload_res(struct vmw_validation_context *ctx, 196 unsigned int size); 197 void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, 198 void *val_private, u32 dirty); 199 void vmw_validation_bo_backoff(struct vmw_validation_context *ctx); 200 201 #endif 202