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