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 */ 56 struct vmw_validation_context { 57 struct vmw_sw_context *sw_context; 58 struct list_head resource_list; 59 struct list_head resource_ctx_list; 60 struct list_head bo_list; 61 struct list_head page_list; 62 struct ww_acquire_ctx ticket; 63 struct mutex *res_mutex; 64 unsigned int merge_dups; 65 unsigned int mem_size_left; 66 u8 *page_address; 67 }; 68 69 struct vmw_bo; 70 struct vmw_resource; 71 struct vmw_fence_obj; 72 73 #if 0 74 /** 75 * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 76 * @_name: The name of the variable 77 * @_sw_context: Contains the hash table used to find dups or NULL if none 78 * @_merge_dups: Whether to merge duplicate buffer object- or resource 79 * entries. If set to true, ideally a hash table pointer should be supplied 80 * as well unless the number of resources and buffer objects per validation 81 * is known to be very small 82 */ 83 #endif 84 #define DECLARE_VAL_CONTEXT(_name, _sw_context, _merge_dups) \ 85 struct vmw_validation_context _name = \ 86 { .sw_context = _sw_context, \ 87 .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 88 .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 89 .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 90 .page_list = LIST_HEAD_INIT((_name).page_list), \ 91 .res_mutex = NULL, \ 92 .merge_dups = _merge_dups, \ 93 .mem_size_left = 0, \ 94 } 95 96 /** 97 * vmw_validation_has_bos - return whether the validation context has 98 * any buffer objects registered. 99 * 100 * @ctx: The validation context 101 * Returns: Whether any buffer objects are registered 102 */ 103 static inline bool 104 vmw_validation_has_bos(struct vmw_validation_context *ctx) 105 { 106 return !list_empty(&ctx->bo_list); 107 } 108 109 /** 110 * vmw_validation_bo_reserve - Reserve buffer objects registered with a 111 * validation context 112 * @ctx: The validation context 113 * @intr: Perform waits interruptible 114 * 115 * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 116 * code on failure 117 */ 118 static inline int 119 vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 120 bool intr) 121 { 122 return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 123 NULL); 124 } 125 126 /** 127 * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 128 * with a validation context 129 * @ctx: The validation context 130 * 131 * This function unreserves the buffer objects previously reserved using 132 * vmw_validation_bo_reserve, and fences them with a fence object. 133 */ 134 static inline void 135 vmw_validation_bo_fence(struct vmw_validation_context *ctx, 136 struct vmw_fence_obj *fence) 137 { 138 ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 139 (void *) fence); 140 } 141 142 /** 143 * vmw_validation_align - Align a validation memory allocation 144 * @val: The size to be aligned 145 * 146 * Returns: @val aligned to the granularity used by the validation memory 147 * allocator. 148 */ 149 static inline unsigned int vmw_validation_align(unsigned int val) 150 { 151 return ALIGN(val, sizeof(long)); 152 } 153 154 int vmw_validation_add_bo(struct vmw_validation_context *ctx, 155 struct vmw_bo *vbo); 156 int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 157 void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 158 int vmw_validation_add_resource(struct vmw_validation_context *ctx, 159 struct vmw_resource *res, 160 size_t priv_size, 161 u32 dirty, 162 void **p_node, 163 bool *first_usage); 164 void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 165 int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 166 bool intr); 167 void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 168 bool backoff); 169 void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 170 void *val_private, 171 struct vmw_bo *vbo, 172 unsigned long backup_offset); 173 int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 174 175 int vmw_validation_prepare(struct vmw_validation_context *ctx, 176 struct mutex *mutex, bool intr); 177 void vmw_validation_revert(struct vmw_validation_context *ctx); 178 void vmw_validation_done(struct vmw_validation_context *ctx, 179 struct vmw_fence_obj *fence); 180 181 void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 182 unsigned int size); 183 int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 184 int vmw_validation_preload_res(struct vmw_validation_context *ctx, 185 unsigned int size); 186 void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, 187 void *val_private, u32 dirty); 188 void vmw_validation_bo_backoff(struct vmw_validation_context *ctx); 189 190 #endif 191