1*038ecc50SThomas Hellstrom /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2*038ecc50SThomas Hellstrom /************************************************************************** 3*038ecc50SThomas Hellstrom * 4*038ecc50SThomas Hellstrom * Copyright © 2018 VMware, Inc., Palo Alto, CA., USA 5*038ecc50SThomas Hellstrom * All Rights Reserved. 6*038ecc50SThomas Hellstrom * 7*038ecc50SThomas Hellstrom * Permission is hereby granted, free of charge, to any person obtaining a 8*038ecc50SThomas Hellstrom * copy of this software and associated documentation files (the 9*038ecc50SThomas Hellstrom * "Software"), to deal in the Software without restriction, including 10*038ecc50SThomas Hellstrom * without limitation the rights to use, copy, modify, merge, publish, 11*038ecc50SThomas Hellstrom * distribute, sub license, and/or sell copies of the Software, and to 12*038ecc50SThomas Hellstrom * permit persons to whom the Software is furnished to do so, subject to 13*038ecc50SThomas Hellstrom * the following conditions: 14*038ecc50SThomas Hellstrom * 15*038ecc50SThomas Hellstrom * The above copyright notice and this permission notice (including the 16*038ecc50SThomas Hellstrom * next paragraph) shall be included in all copies or substantial portions 17*038ecc50SThomas Hellstrom * of the Software. 18*038ecc50SThomas Hellstrom * 19*038ecc50SThomas Hellstrom * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20*038ecc50SThomas Hellstrom * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21*038ecc50SThomas Hellstrom * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22*038ecc50SThomas Hellstrom * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23*038ecc50SThomas Hellstrom * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24*038ecc50SThomas Hellstrom * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25*038ecc50SThomas Hellstrom * USE OR OTHER DEALINGS IN THE SOFTWARE. 26*038ecc50SThomas Hellstrom * 27*038ecc50SThomas Hellstrom **************************************************************************/ 28*038ecc50SThomas Hellstrom #ifndef _VMWGFX_VALIDATION_H_ 29*038ecc50SThomas Hellstrom #define _VMWGFX_VALIDATION_H_ 30*038ecc50SThomas Hellstrom 31*038ecc50SThomas Hellstrom #include <drm/drm_hashtab.h> 32*038ecc50SThomas Hellstrom #include <linux/list.h> 33*038ecc50SThomas Hellstrom #include <linux/ww_mutex.h> 34*038ecc50SThomas Hellstrom #include <drm/ttm/ttm_execbuf_util.h> 35*038ecc50SThomas Hellstrom 36*038ecc50SThomas Hellstrom /** 37*038ecc50SThomas Hellstrom * struct vmw_validation_context - Per command submission validation context 38*038ecc50SThomas Hellstrom * @ht: Hash table used to find resource- or buffer object duplicates 39*038ecc50SThomas Hellstrom * @resource_list: List head for resource validation metadata 40*038ecc50SThomas Hellstrom * @resource_ctx_list: List head for resource validation metadata for 41*038ecc50SThomas Hellstrom * resources that need to be validated before those in @resource_list 42*038ecc50SThomas Hellstrom * @bo_list: List head for buffer objects 43*038ecc50SThomas Hellstrom * @ticket: Ticked used for ww mutex locking 44*038ecc50SThomas Hellstrom * @res_mutex: Pointer to mutex used for resource reserving 45*038ecc50SThomas Hellstrom * @merge_dups: Whether to merge metadata for duplicate resources or 46*038ecc50SThomas Hellstrom * buffer objects 47*038ecc50SThomas Hellstrom */ 48*038ecc50SThomas Hellstrom struct vmw_validation_context { 49*038ecc50SThomas Hellstrom struct drm_open_hash *ht; 50*038ecc50SThomas Hellstrom struct list_head resource_list; 51*038ecc50SThomas Hellstrom struct list_head resource_ctx_list; 52*038ecc50SThomas Hellstrom struct list_head bo_list; 53*038ecc50SThomas Hellstrom struct ww_acquire_ctx ticket; 54*038ecc50SThomas Hellstrom struct mutex *res_mutex; 55*038ecc50SThomas Hellstrom unsigned int merge_dups; 56*038ecc50SThomas Hellstrom }; 57*038ecc50SThomas Hellstrom 58*038ecc50SThomas Hellstrom struct vmw_buffer_object; 59*038ecc50SThomas Hellstrom struct vmw_resource; 60*038ecc50SThomas Hellstrom struct vmw_fence_obj; 61*038ecc50SThomas Hellstrom 62*038ecc50SThomas Hellstrom #if 0 63*038ecc50SThomas Hellstrom /** 64*038ecc50SThomas Hellstrom * DECLARE_VAL_CONTEXT - Declare a validation context with initialization 65*038ecc50SThomas Hellstrom * @_name: The name of the variable 66*038ecc50SThomas Hellstrom * @_ht: The hash table used to find dups or NULL if none 67*038ecc50SThomas Hellstrom * @_merge_dups: Whether to merge duplicate buffer object- or resource 68*038ecc50SThomas Hellstrom * entries. If set to true, ideally a hash table pointer should be supplied 69*038ecc50SThomas Hellstrom * as well unless the number of resources and buffer objects per validation 70*038ecc50SThomas Hellstrom * is known to be very small 71*038ecc50SThomas Hellstrom */ 72*038ecc50SThomas Hellstrom #endif 73*038ecc50SThomas Hellstrom #define DECLARE_VAL_CONTEXT(_name, _ht, _merge_dups) \ 74*038ecc50SThomas Hellstrom struct vmw_validation_context _name = \ 75*038ecc50SThomas Hellstrom { .ht = _ht, \ 76*038ecc50SThomas Hellstrom .resource_list = LIST_HEAD_INIT((_name).resource_list), \ 77*038ecc50SThomas Hellstrom .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \ 78*038ecc50SThomas Hellstrom .bo_list = LIST_HEAD_INIT((_name).bo_list), \ 79*038ecc50SThomas Hellstrom .merge_dups = _merge_dups, \ 80*038ecc50SThomas Hellstrom .res_mutex = NULL \ 81*038ecc50SThomas Hellstrom } 82*038ecc50SThomas Hellstrom 83*038ecc50SThomas Hellstrom /** 84*038ecc50SThomas Hellstrom * vmw_validation_has_bos - return whether the validation context has 85*038ecc50SThomas Hellstrom * any buffer objects registered. 86*038ecc50SThomas Hellstrom * 87*038ecc50SThomas Hellstrom * @ctx: The validation context 88*038ecc50SThomas Hellstrom * Returns: Whether any buffer objects are registered 89*038ecc50SThomas Hellstrom */ 90*038ecc50SThomas Hellstrom static inline bool 91*038ecc50SThomas Hellstrom vmw_validation_has_bos(struct vmw_validation_context *ctx) 92*038ecc50SThomas Hellstrom { 93*038ecc50SThomas Hellstrom return !list_empty(&ctx->bo_list); 94*038ecc50SThomas Hellstrom } 95*038ecc50SThomas Hellstrom 96*038ecc50SThomas Hellstrom /** 97*038ecc50SThomas Hellstrom * vmw_validation_set_ht - Register a hash table for duplicate finding 98*038ecc50SThomas Hellstrom * @ctx: The validation context 99*038ecc50SThomas Hellstrom * @ht: Pointer to a hash table to use for duplicate finding 100*038ecc50SThomas Hellstrom * This function is intended to be used if the hash table wasn't 101*038ecc50SThomas Hellstrom * available at validation context declaration time 102*038ecc50SThomas Hellstrom */ 103*038ecc50SThomas Hellstrom static inline void vmw_validation_set_ht(struct vmw_validation_context *ctx, 104*038ecc50SThomas Hellstrom struct drm_open_hash *ht) 105*038ecc50SThomas Hellstrom { 106*038ecc50SThomas Hellstrom ctx->ht = ht; 107*038ecc50SThomas Hellstrom } 108*038ecc50SThomas Hellstrom 109*038ecc50SThomas Hellstrom /** 110*038ecc50SThomas Hellstrom * vmw_validation_bo_reserve - Reserve buffer objects registered with a 111*038ecc50SThomas Hellstrom * validation context 112*038ecc50SThomas Hellstrom * @ctx: The validation context 113*038ecc50SThomas Hellstrom * @intr: Perform waits interruptible 114*038ecc50SThomas Hellstrom * 115*038ecc50SThomas Hellstrom * Return: Zero on success, -ERESTARTSYS when interrupted, negative error 116*038ecc50SThomas Hellstrom * code on failure 117*038ecc50SThomas Hellstrom */ 118*038ecc50SThomas Hellstrom static inline int 119*038ecc50SThomas Hellstrom vmw_validation_bo_reserve(struct vmw_validation_context *ctx, 120*038ecc50SThomas Hellstrom bool intr) 121*038ecc50SThomas Hellstrom { 122*038ecc50SThomas Hellstrom return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr, 123*038ecc50SThomas Hellstrom NULL); 124*038ecc50SThomas Hellstrom } 125*038ecc50SThomas Hellstrom 126*038ecc50SThomas Hellstrom /** 127*038ecc50SThomas Hellstrom * vmw_validation_bo_backoff - Unreserve buffer objects registered with a 128*038ecc50SThomas Hellstrom * validation context 129*038ecc50SThomas Hellstrom * @ctx: The validation context 130*038ecc50SThomas Hellstrom * 131*038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 132*038ecc50SThomas Hellstrom * vmw_validation_bo_reserve. It's typically used as part of an error path 133*038ecc50SThomas Hellstrom */ 134*038ecc50SThomas Hellstrom static inline void 135*038ecc50SThomas Hellstrom vmw_validation_bo_backoff(struct vmw_validation_context *ctx) 136*038ecc50SThomas Hellstrom { 137*038ecc50SThomas Hellstrom ttm_eu_backoff_reservation(&ctx->ticket, &ctx->bo_list); 138*038ecc50SThomas Hellstrom } 139*038ecc50SThomas Hellstrom 140*038ecc50SThomas Hellstrom /** 141*038ecc50SThomas Hellstrom * vmw_validation_bo_fence - Unreserve and fence buffer objects registered 142*038ecc50SThomas Hellstrom * with a validation context 143*038ecc50SThomas Hellstrom * @ctx: The validation context 144*038ecc50SThomas Hellstrom * 145*038ecc50SThomas Hellstrom * This function unreserves the buffer objects previously reserved using 146*038ecc50SThomas Hellstrom * vmw_validation_bo_reserve, and fences them with a fence object. 147*038ecc50SThomas Hellstrom */ 148*038ecc50SThomas Hellstrom static inline void 149*038ecc50SThomas Hellstrom vmw_validation_bo_fence(struct vmw_validation_context *ctx, 150*038ecc50SThomas Hellstrom struct vmw_fence_obj *fence) 151*038ecc50SThomas Hellstrom { 152*038ecc50SThomas Hellstrom ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list, 153*038ecc50SThomas Hellstrom (void *) fence); 154*038ecc50SThomas Hellstrom } 155*038ecc50SThomas Hellstrom 156*038ecc50SThomas Hellstrom /** 157*038ecc50SThomas Hellstrom * vmw_validation_context_init - Initialize a validation context 158*038ecc50SThomas Hellstrom * @ctx: Pointer to the validation context to initialize 159*038ecc50SThomas Hellstrom * 160*038ecc50SThomas Hellstrom * This function initializes a validation context with @merge_dups set 161*038ecc50SThomas Hellstrom * to false 162*038ecc50SThomas Hellstrom */ 163*038ecc50SThomas Hellstrom static inline void 164*038ecc50SThomas Hellstrom vmw_validation_context_init(struct vmw_validation_context *ctx) 165*038ecc50SThomas Hellstrom { 166*038ecc50SThomas Hellstrom memset(ctx, 0, sizeof(*ctx)); 167*038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_list); 168*038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->resource_ctx_list); 169*038ecc50SThomas Hellstrom INIT_LIST_HEAD(&ctx->bo_list); 170*038ecc50SThomas Hellstrom } 171*038ecc50SThomas Hellstrom 172*038ecc50SThomas Hellstrom int vmw_validation_add_bo(struct vmw_validation_context *ctx, 173*038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 174*038ecc50SThomas Hellstrom bool as_mob, bool cpu_blit); 175*038ecc50SThomas Hellstrom int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, 176*038ecc50SThomas Hellstrom bool interruptible, 177*038ecc50SThomas Hellstrom bool validate_as_mob); 178*038ecc50SThomas Hellstrom int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr); 179*038ecc50SThomas Hellstrom void vmw_validation_unref_lists(struct vmw_validation_context *ctx); 180*038ecc50SThomas Hellstrom int vmw_validation_add_resource(struct vmw_validation_context *ctx, 181*038ecc50SThomas Hellstrom struct vmw_resource *res, 182*038ecc50SThomas Hellstrom size_t priv_size, 183*038ecc50SThomas Hellstrom void **p_node, 184*038ecc50SThomas Hellstrom bool *first_usage); 185*038ecc50SThomas Hellstrom void vmw_validation_drop_ht(struct vmw_validation_context *ctx); 186*038ecc50SThomas Hellstrom int vmw_validation_res_reserve(struct vmw_validation_context *ctx, 187*038ecc50SThomas Hellstrom bool intr); 188*038ecc50SThomas Hellstrom void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, 189*038ecc50SThomas Hellstrom bool backoff); 190*038ecc50SThomas Hellstrom void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx, 191*038ecc50SThomas Hellstrom void *val_private, 192*038ecc50SThomas Hellstrom struct vmw_buffer_object *vbo, 193*038ecc50SThomas Hellstrom unsigned long backup_offset); 194*038ecc50SThomas Hellstrom int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr); 195*038ecc50SThomas Hellstrom 196*038ecc50SThomas Hellstrom int vmw_validation_prepare(struct vmw_validation_context *ctx, 197*038ecc50SThomas Hellstrom struct mutex *mutex, bool intr); 198*038ecc50SThomas Hellstrom void vmw_validation_revert(struct vmw_validation_context *ctx); 199*038ecc50SThomas Hellstrom void vmw_validation_done(struct vmw_validation_context *ctx, 200*038ecc50SThomas Hellstrom struct vmw_fence_obj *fence); 201*038ecc50SThomas Hellstrom 202*038ecc50SThomas Hellstrom #endif 203