1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 /************************************************************************** 3 * 4 * Copyright © 2018 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 <drm/drm_hashtab.h> 32 #include <linux/list.h> 33 #include <linux/ww_mutex.h> 34 #include <drm/ttm/ttm_execbuf_util.h> 35 36 /** 37 * struct vmw_validation_context - Per command submission validation context 38 * @ht: Hash table used to find resource- or buffer object duplicates 39 * @resource_list: List head for resource validation metadata 40 * @resource_ctx_list: List head for resource validation metadata for 41 * resources that need to be validated before those in @resource_list 42 * @bo_list: List head for buffer objects 43 * @page_list: List of pages used by the memory allocator 44 * @ticket: Ticked used for ww mutex locking 45 * @res_mutex: Pointer to mutex used for resource reserving 46 * @merge_dups: Whether to merge metadata for duplicate resources or 47 * buffer objects 48 * @mem_size_left: Free memory left in the last page in @page_list 49 * @page_address: Kernel virtual address of the last page in @page_list 50 */ 51 struct vmw_validation_context { 52 struct drm_open_hash *ht; 53 struct list_head resource_list; 54 struct list_head resource_ctx_list; 55 struct list_head bo_list; 56 struct list_head page_list; 57 struct ww_acquire_ctx ticket; 58 struct mutex *res_mutex; 59 unsigned int merge_dups; 60 unsigned int mem_size_left; 61 u8 *page_address; 62 }; 63 64 struct vmw_buffer_object; 65 struct vmw_resource; 66 struct vmw_fence_obj; 67 68 #if 0 69 /** 70 * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 71 * @_name: The name of the variable 72 * @_ht: The hash table used to find dups or NULL if none 73 * @_merge_dups: Whether to merge duplicate buffer object- or resource 74 * entries. If set to true, ideally a hash table pointer should be supplied 75 * as well unless the number of resources and buffer objects per validation 76 * is known to be very small 77 */ 78 #endif 79 #define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ 80 struct vmw_validation_context _name = \ 81 { .ht = _ht, \ 82 .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 83 .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 84 .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 85 .page_list = LIST_HEAD_INIT((_name).page_list), \ 86 .res_mutex = NULL, \ 87 .merge_dups = _merge_dups, \ 88 .mem_size_left = 0, \ 89 } 90 91 /** 92 * vmw_validation_has_bos - return whether the validation context has 93 * any buffer objects registered. 94 * 95 * @ctx: The validation context 96 * Returns: Whether any buffer objects are registered 97 */ 98 static inline bool 99 vmw_validation_has_bos(struct vmw_validation_context *ctx) 100 { 101 return !list_empty(&ctx->bo_list); 102 } 103 104 /** 105 * vmw_validation_set_ht - Register a hash table for duplicate finding 106 * @ctx: The validation context 107 * @ht: Pointer to a hash table to use for duplicate finding 108 * This function is intended to be used if the hash table wasn't 109 * available at validation context declaration time 110 */ 111 static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, 112 struct drm_open_hash *ht) 113 { 114 ctx->ht = ht; 115 } 116 117 /** 118 * vmw_validation_bo_reserve - Reserve buffer objects registered with a 119 * validation context 120 * @ctx: The validation context 121 * @intr: Perform waits interruptible 122 * 123 * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 124 * code on failure 125 */ 126 static inline int 127 vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 128 bool intr) 129 { 130 return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 131 NULL); 132 } 133 134 /** 135 * vmw_validation_bo_backoff - Unreserve buffer objects registered with a 136 * validation context 137 * @ctx: The validation context 138 * 139 * This function unreserves the buffer objects previously reserved using 140 * vmw_validation_bo_reserve. It's typically used as part of an error path 141 */ 142 static inline void 143 vmw_validation_bo_backoff(struct vmw_validation_context *ctx) 144 { 145 ttm_eu_backoff_reservation(&ctx->ticket, &ctx->bo_list); 146 } 147 148 /** 149 * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 150 * with a validation context 151 * @ctx: The validation context 152 * 153 * This function unreserves the buffer objects previously reserved using 154 * vmw_validation_bo_reserve, and fences them with a fence object. 155 */ 156 static inline void 157 vmw_validation_bo_fence(struct vmw_validation_context *ctx, 158 struct vmw_fence_obj *fence) 159 { 160 ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 161 (void *) fence); 162 } 163 164 /** 165 * vmw_validation_context_init - Initialize a validation context 166 * @ctx: Pointer to the validation context to initialize 167 * 168 * This function initializes a validation context with @merge_dups set 169 * to false 170 */ 171 static inline void 172 vmw_validation_context_init(struct vmw_validation_context *ctx) 173 { 174 memset(ctx, 0, sizeof(*ctx)); 175 INIT_LIST_HEAD(&ctx->resource_list); 176 INIT_LIST_HEAD(&ctx->resource_ctx_list); 177 INIT_LIST_HEAD(&ctx->bo_list); 178 } 179 180 /** 181 * vmw_validation_align - Align a validation memory allocation 182 * @val: The size to be aligned 183 * 184 * Returns: @val aligned to the granularity used by the validation memory 185 * allocator. 186 */ 187 static inline unsigned int vmw_validation_align(unsigned int val) 188 { 189 return ALIGN(val, sizeof(long)); 190 } 191 192 int vmw_validation_add_bo(struct vmw_validation_context *ctx, 193 struct vmw_buffer_object *vbo, 194 bool as_mob, bool cpu_blit); 195 int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 196 bool interruptible, 197 bool validate_as_mob); 198 int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 199 void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 200 int vmw_validation_add_resource(struct vmw_validation_context *ctx, 201 struct vmw_resource *res, 202 size_t priv_size, 203 void **p_node, 204 bool *first_usage); 205 void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 206 int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 207 bool intr); 208 void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 209 bool backoff); 210 void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 211 void *val_private, 212 struct vmw_buffer_object *vbo, 213 unsigned long backup_offset); 214 int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 215 216 int vmw_validation_prepare(struct vmw_validation_context *ctx, 217 struct mutex *mutex, bool intr); 218 void vmw_validation_revert(struct vmw_validation_context *ctx); 219 void vmw_validation_done(struct vmw_validation_context *ctx, 220 struct vmw_fence_obj *fence); 221 222 void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 223 unsigned int size); 224 int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 225 int vmw_validation_preload_res(struct vmw_validation_context *ctx, 226 unsigned int size); 227 #endif 228