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