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 */ 52struct 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 */ 77struct 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 93struct vmw_buffer_object; 94struct vmw_resource; 95struct 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 */ 127static inline bool 128vmw_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 */ 141static inline void 142vmw_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 */ 155static 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 */ 170static inline int 171vmw_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 */ 186static inline void 187vmw_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 */ 201static inline void 202vmw_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 */ 217static inline unsigned int vmw_validation_align(unsigned int val) 218{ 219 return round_up(val, sizeof(long)); 220} 221 222int vmw_validation_add_bo(struct vmw_validation_context *ctx, 223 struct vmw_buffer_object *vbo, 224 bool as_mob, bool cpu_blit); 225int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 226 bool interruptible, 227 bool validate_as_mob); 228int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 229void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 230int 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); 236void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 237int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 238 bool intr); 239void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 240 bool backoff); 241void 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); 245int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 246 247int vmw_validation_prepare(struct vmw_validation_context *ctx, 248 struct mutex *mutex, bool intr); 249void vmw_validation_revert(struct vmw_validation_context *ctx); 250void vmw_validation_done(struct vmw_validation_context *ctx, 251 struct vmw_fence_obj *fence); 252 253void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, 254 unsigned int size); 255int vmw_validation_preload_bo(struct vmw_validation_context *ctx); 256int vmw_validation_preload_res(struct vmw_validation_context *ctx, 257 unsigned int size); 258void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, 259 void *val_private, u32 dirty); 260void vmw_validation_bo_backoff(struct vmw_validation_context *ctx); 261 262#endif 263