18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR MIT 28c2ecf20Sopenharmony_ci/************************************************************************** 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright 2014-2015 VMware, Inc., Palo Alto, CA., USA 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 78c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the 88c2ecf20Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 98c2ecf20Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 108c2ecf20Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 118c2ecf20Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 128c2ecf20Sopenharmony_ci * the following conditions: 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the 158c2ecf20Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 168c2ecf20Sopenharmony_ci * of the Software. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 198c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 208c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 218c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 228c2ecf20Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 238c2ecf20Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 248c2ecf20Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci **************************************************************************/ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include "vmwgfx_drv.h" 298c2ecf20Sopenharmony_ci#include "vmwgfx_resource_priv.h" 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define VMW_CMDBUF_RES_MAN_HT_ORDER 12 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/** 348c2ecf20Sopenharmony_ci * struct vmw_cmdbuf_res - Command buffer managed resource entry. 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci * @res: Refcounted pointer to a struct vmw_resource. 378c2ecf20Sopenharmony_ci * @hash: Hash entry for the manager hash table. 388c2ecf20Sopenharmony_ci * @head: List head used either by the staging list or the manager list 398c2ecf20Sopenharmony_ci * of commited resources. 408c2ecf20Sopenharmony_ci * @state: Staging state of this resource entry. 418c2ecf20Sopenharmony_ci * @man: Pointer to a resource manager for this entry. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_cistruct vmw_cmdbuf_res { 448c2ecf20Sopenharmony_ci struct vmw_resource *res; 458c2ecf20Sopenharmony_ci struct drm_hash_item hash; 468c2ecf20Sopenharmony_ci struct list_head head; 478c2ecf20Sopenharmony_ci enum vmw_cmdbuf_res_state state; 488c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res_manager *man; 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * struct vmw_cmdbuf_res_manager - Command buffer resource manager. 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * @resources: Hash table containing staged and commited command buffer 558c2ecf20Sopenharmony_ci * resources 568c2ecf20Sopenharmony_ci * @list: List of commited command buffer resources. 578c2ecf20Sopenharmony_ci * @dev_priv: Pointer to a device private structure. 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * @resources and @list are protected by the cmdbuf mutex for now. 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_cistruct vmw_cmdbuf_res_manager { 628c2ecf20Sopenharmony_ci struct drm_open_hash resources; 638c2ecf20Sopenharmony_ci struct list_head list; 648c2ecf20Sopenharmony_ci struct vmw_private *dev_priv; 658c2ecf20Sopenharmony_ci}; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/** 698c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_lookup - Look up a command buffer resource 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * @man: Pointer to the command buffer resource manager 728c2ecf20Sopenharmony_ci * @resource_type: The resource type, that combined with the user key 738c2ecf20Sopenharmony_ci * identifies the resource. 748c2ecf20Sopenharmony_ci * @user_key: The user key. 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * Returns a valid refcounted struct vmw_resource pointer on success, 778c2ecf20Sopenharmony_ci * an error pointer on failure. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_cistruct vmw_resource * 808c2ecf20Sopenharmony_civmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man, 818c2ecf20Sopenharmony_ci enum vmw_cmdbuf_res_type res_type, 828c2ecf20Sopenharmony_ci u32 user_key) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci struct drm_hash_item *hash; 858c2ecf20Sopenharmony_ci int ret; 868c2ecf20Sopenharmony_ci unsigned long key = user_key | (res_type << 24); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci ret = drm_ht_find_item(&man->resources, key, &hash); 898c2ecf20Sopenharmony_ci if (unlikely(ret != 0)) 908c2ecf20Sopenharmony_ci return ERR_PTR(ret); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/** 968c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_free - Free a command buffer resource. 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * @man: Pointer to the command buffer resource manager 998c2ecf20Sopenharmony_ci * @entry: Pointer to a struct vmw_cmdbuf_res. 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * Frees a struct vmw_cmdbuf_res entry and drops its reference to the 1028c2ecf20Sopenharmony_ci * struct vmw_resource. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_cistatic void vmw_cmdbuf_res_free(struct vmw_cmdbuf_res_manager *man, 1058c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *entry) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci list_del(&entry->head); 1088c2ecf20Sopenharmony_ci WARN_ON(drm_ht_remove_item(&man->resources, &entry->hash)); 1098c2ecf20Sopenharmony_ci vmw_resource_unreference(&entry->res); 1108c2ecf20Sopenharmony_ci kfree(entry); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci/** 1148c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_commit - Commit a list of command buffer resource actions 1158c2ecf20Sopenharmony_ci * 1168c2ecf20Sopenharmony_ci * @list: Caller's list of command buffer resource actions. 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * This function commits a list of command buffer resource 1198c2ecf20Sopenharmony_ci * additions or removals. 1208c2ecf20Sopenharmony_ci * It is typically called when the execbuf ioctl call triggering these 1218c2ecf20Sopenharmony_ci * actions has commited the fifo contents to the device. 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_civoid vmw_cmdbuf_res_commit(struct list_head *list) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *entry, *next; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, next, list, head) { 1288c2ecf20Sopenharmony_ci list_del(&entry->head); 1298c2ecf20Sopenharmony_ci if (entry->res->func->commit_notify) 1308c2ecf20Sopenharmony_ci entry->res->func->commit_notify(entry->res, 1318c2ecf20Sopenharmony_ci entry->state); 1328c2ecf20Sopenharmony_ci switch (entry->state) { 1338c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_ADD: 1348c2ecf20Sopenharmony_ci entry->state = VMW_CMDBUF_RES_COMMITTED; 1358c2ecf20Sopenharmony_ci list_add_tail(&entry->head, &entry->man->list); 1368c2ecf20Sopenharmony_ci break; 1378c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_DEL: 1388c2ecf20Sopenharmony_ci vmw_resource_unreference(&entry->res); 1398c2ecf20Sopenharmony_ci kfree(entry); 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci default: 1428c2ecf20Sopenharmony_ci BUG(); 1438c2ecf20Sopenharmony_ci break; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci } 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/** 1498c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_revert - Revert a list of command buffer resource actions 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * @man: Pointer to the command buffer resource manager 1528c2ecf20Sopenharmony_ci * @list: Caller's list of command buffer resource action 1538c2ecf20Sopenharmony_ci * 1548c2ecf20Sopenharmony_ci * This function reverts a list of command buffer resource 1558c2ecf20Sopenharmony_ci * additions or removals. 1568c2ecf20Sopenharmony_ci * It is typically called when the execbuf ioctl call triggering these 1578c2ecf20Sopenharmony_ci * actions failed for some reason, and the command stream was never 1588c2ecf20Sopenharmony_ci * submitted. 1598c2ecf20Sopenharmony_ci */ 1608c2ecf20Sopenharmony_civoid vmw_cmdbuf_res_revert(struct list_head *list) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *entry, *next; 1638c2ecf20Sopenharmony_ci int ret; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, next, list, head) { 1668c2ecf20Sopenharmony_ci switch (entry->state) { 1678c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_ADD: 1688c2ecf20Sopenharmony_ci vmw_cmdbuf_res_free(entry->man, entry); 1698c2ecf20Sopenharmony_ci break; 1708c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_DEL: 1718c2ecf20Sopenharmony_ci ret = drm_ht_insert_item(&entry->man->resources, 1728c2ecf20Sopenharmony_ci &entry->hash); 1738c2ecf20Sopenharmony_ci list_del(&entry->head); 1748c2ecf20Sopenharmony_ci list_add_tail(&entry->head, &entry->man->list); 1758c2ecf20Sopenharmony_ci entry->state = VMW_CMDBUF_RES_COMMITTED; 1768c2ecf20Sopenharmony_ci break; 1778c2ecf20Sopenharmony_ci default: 1788c2ecf20Sopenharmony_ci BUG(); 1798c2ecf20Sopenharmony_ci break; 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/** 1858c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_add - Stage a command buffer managed resource for addition. 1868c2ecf20Sopenharmony_ci * 1878c2ecf20Sopenharmony_ci * @man: Pointer to the command buffer resource manager. 1888c2ecf20Sopenharmony_ci * @res_type: The resource type. 1898c2ecf20Sopenharmony_ci * @user_key: The user-space id of the resource. 1908c2ecf20Sopenharmony_ci * @res: Valid (refcount != 0) pointer to a struct vmw_resource. 1918c2ecf20Sopenharmony_ci * @list: The staging list. 1928c2ecf20Sopenharmony_ci * 1938c2ecf20Sopenharmony_ci * This function allocates a struct vmw_cmdbuf_res entry and adds the 1948c2ecf20Sopenharmony_ci * resource to the hash table of the manager identified by @man. The 1958c2ecf20Sopenharmony_ci * entry is then put on the staging list identified by @list. 1968c2ecf20Sopenharmony_ci */ 1978c2ecf20Sopenharmony_ciint vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man, 1988c2ecf20Sopenharmony_ci enum vmw_cmdbuf_res_type res_type, 1998c2ecf20Sopenharmony_ci u32 user_key, 2008c2ecf20Sopenharmony_ci struct vmw_resource *res, 2018c2ecf20Sopenharmony_ci struct list_head *list) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *cres; 2048c2ecf20Sopenharmony_ci int ret; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci cres = kzalloc(sizeof(*cres), GFP_KERNEL); 2078c2ecf20Sopenharmony_ci if (unlikely(!cres)) 2088c2ecf20Sopenharmony_ci return -ENOMEM; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci cres->hash.key = user_key | (res_type << 24); 2118c2ecf20Sopenharmony_ci ret = drm_ht_insert_item(&man->resources, &cres->hash); 2128c2ecf20Sopenharmony_ci if (unlikely(ret != 0)) { 2138c2ecf20Sopenharmony_ci kfree(cres); 2148c2ecf20Sopenharmony_ci goto out_invalid_key; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci cres->state = VMW_CMDBUF_RES_ADD; 2188c2ecf20Sopenharmony_ci cres->res = vmw_resource_reference(res); 2198c2ecf20Sopenharmony_ci cres->man = man; 2208c2ecf20Sopenharmony_ci list_add_tail(&cres->head, list); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ciout_invalid_key: 2238c2ecf20Sopenharmony_ci return ret; 2248c2ecf20Sopenharmony_ci} 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci/** 2278c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_remove - Stage a command buffer managed resource for removal. 2288c2ecf20Sopenharmony_ci * 2298c2ecf20Sopenharmony_ci * @man: Pointer to the command buffer resource manager. 2308c2ecf20Sopenharmony_ci * @res_type: The resource type. 2318c2ecf20Sopenharmony_ci * @user_key: The user-space id of the resource. 2328c2ecf20Sopenharmony_ci * @list: The staging list. 2338c2ecf20Sopenharmony_ci * @res_p: If the resource is in an already committed state, points to the 2348c2ecf20Sopenharmony_ci * struct vmw_resource on successful return. The pointer will be 2358c2ecf20Sopenharmony_ci * non ref-counted. 2368c2ecf20Sopenharmony_ci * 2378c2ecf20Sopenharmony_ci * This function looks up the struct vmw_cmdbuf_res entry from the manager 2388c2ecf20Sopenharmony_ci * hash table and, if it exists, removes it. Depending on its current staging 2398c2ecf20Sopenharmony_ci * state it then either removes the entry from the staging list or adds it 2408c2ecf20Sopenharmony_ci * to it with a staging state of removal. 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_ciint vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, 2438c2ecf20Sopenharmony_ci enum vmw_cmdbuf_res_type res_type, 2448c2ecf20Sopenharmony_ci u32 user_key, 2458c2ecf20Sopenharmony_ci struct list_head *list, 2468c2ecf20Sopenharmony_ci struct vmw_resource **res_p) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *entry; 2498c2ecf20Sopenharmony_ci struct drm_hash_item *hash; 2508c2ecf20Sopenharmony_ci int ret; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci ret = drm_ht_find_item(&man->resources, user_key | (res_type << 24), 2538c2ecf20Sopenharmony_ci &hash); 2548c2ecf20Sopenharmony_ci if (likely(ret != 0)) 2558c2ecf20Sopenharmony_ci return -EINVAL; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci switch (entry->state) { 2608c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_ADD: 2618c2ecf20Sopenharmony_ci vmw_cmdbuf_res_free(man, entry); 2628c2ecf20Sopenharmony_ci *res_p = NULL; 2638c2ecf20Sopenharmony_ci break; 2648c2ecf20Sopenharmony_ci case VMW_CMDBUF_RES_COMMITTED: 2658c2ecf20Sopenharmony_ci (void) drm_ht_remove_item(&man->resources, &entry->hash); 2668c2ecf20Sopenharmony_ci list_del(&entry->head); 2678c2ecf20Sopenharmony_ci entry->state = VMW_CMDBUF_RES_DEL; 2688c2ecf20Sopenharmony_ci list_add_tail(&entry->head, list); 2698c2ecf20Sopenharmony_ci *res_p = entry->res; 2708c2ecf20Sopenharmony_ci break; 2718c2ecf20Sopenharmony_ci default: 2728c2ecf20Sopenharmony_ci BUG(); 2738c2ecf20Sopenharmony_ci break; 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci return 0; 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/** 2808c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_man_create - Allocate a command buffer managed resource 2818c2ecf20Sopenharmony_ci * manager. 2828c2ecf20Sopenharmony_ci * 2838c2ecf20Sopenharmony_ci * @dev_priv: Pointer to a struct vmw_private 2848c2ecf20Sopenharmony_ci * 2858c2ecf20Sopenharmony_ci * Allocates and initializes a command buffer managed resource manager. Returns 2868c2ecf20Sopenharmony_ci * an error pointer on failure. 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_cistruct vmw_cmdbuf_res_manager * 2898c2ecf20Sopenharmony_civmw_cmdbuf_res_man_create(struct vmw_private *dev_priv) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res_manager *man; 2928c2ecf20Sopenharmony_ci int ret; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci man = kzalloc(sizeof(*man), GFP_KERNEL); 2958c2ecf20Sopenharmony_ci if (!man) 2968c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci man->dev_priv = dev_priv; 2998c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&man->list); 3008c2ecf20Sopenharmony_ci ret = drm_ht_create(&man->resources, VMW_CMDBUF_RES_MAN_HT_ORDER); 3018c2ecf20Sopenharmony_ci if (ret == 0) 3028c2ecf20Sopenharmony_ci return man; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci kfree(man); 3058c2ecf20Sopenharmony_ci return ERR_PTR(ret); 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci/** 3098c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_man_destroy - Destroy a command buffer managed resource 3108c2ecf20Sopenharmony_ci * manager. 3118c2ecf20Sopenharmony_ci * 3128c2ecf20Sopenharmony_ci * @man: Pointer to the manager to destroy. 3138c2ecf20Sopenharmony_ci * 3148c2ecf20Sopenharmony_ci * This function destroys a command buffer managed resource manager and 3158c2ecf20Sopenharmony_ci * unreferences / frees all command buffer managed resources and -entries 3168c2ecf20Sopenharmony_ci * associated with it. 3178c2ecf20Sopenharmony_ci */ 3188c2ecf20Sopenharmony_civoid vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci struct vmw_cmdbuf_res *entry, *next; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, next, &man->list, head) 3238c2ecf20Sopenharmony_ci vmw_cmdbuf_res_free(man, entry); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci drm_ht_remove(&man->resources); 3268c2ecf20Sopenharmony_ci kfree(man); 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/** 3308c2ecf20Sopenharmony_ci * 3318c2ecf20Sopenharmony_ci * vmw_cmdbuf_res_man_size - Return the size of a command buffer managed 3328c2ecf20Sopenharmony_ci * resource manager 3338c2ecf20Sopenharmony_ci * 3348c2ecf20Sopenharmony_ci * Returns the approximate allocation size of a command buffer managed 3358c2ecf20Sopenharmony_ci * resource manager. 3368c2ecf20Sopenharmony_ci */ 3378c2ecf20Sopenharmony_cisize_t vmw_cmdbuf_res_man_size(void) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci static size_t res_man_size; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci if (unlikely(res_man_size == 0)) 3428c2ecf20Sopenharmony_ci res_man_size = 3438c2ecf20Sopenharmony_ci ttm_round_pot(sizeof(struct vmw_cmdbuf_res_manager)) + 3448c2ecf20Sopenharmony_ci ttm_round_pot(sizeof(struct hlist_head) << 3458c2ecf20Sopenharmony_ci VMW_CMDBUF_RES_MAN_HT_ORDER); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci return res_man_size; 3488c2ecf20Sopenharmony_ci} 349