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