1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2016-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef _RM_POOL_ALLOC_H_
25 #define _RM_POOL_ALLOC_H_
26 
27 /*!
28  * @file pool_alloc.h
29  *
30  * @brief Describes utilities for creating pools for RM internal usage,
31  *        allocating memory from the pools, freeing memory to the pools
32  *        and destroying the pools.
33  *        Uses:
34  *        1. RM allocations for client page tables
35  *        2. Context-specific RM allocations like context buffers, instance memory, fault buffers, GR local buffers
36  *        3. Engine-specific RM allocations like runlist buffers and GR global buffers
37  */
38 
39 /* ---------------------------------Includes ------------------------------------ */
40 #include "core/core.h"
41 
42 /* ------------------------------- Public Interface ----------------------------- */
43 /*!
44  * Static configurations for various pools.
45  */
46 
47 typedef enum
48 {
49     POOL_CONFIG_GMMU_FMT_1,     // configure pool for client page tables with version = GMMU_FMT_VERSION_1
50     POOL_CONFIG_GMMU_FMT_2,     // configure pool for client page tables with version = GMMU_FMT_VERSION_2
51     POOL_CONFIG_CTXBUF_512M,    // configure pool for RM internal allocations like ctx buffers with 512MB page size
52     POOL_CONFIG_CTXBUF_2M,      // configure pool for RM internal allocations like ctx buffers with 2MB page size
53     POOL_CONFIG_CTXBUF_64K,     // configure pool for RM internal allocations like ctx buffers with 64KB page size
54     POOL_CONFIG_CTXBUF_4K,      // configure pool for RM internal allocations like ctx buffers with 4KB page size
55     POOL_CONFIG_MAX_SUPPORTED
56 
57 }POOL_CONFIG_MODE;
58 /* ------------------------------------ Datatypes ---------------------------------- */
59 
60 /*!
61  * Opaque library-defined state of a pool reserve.
62  */
63 typedef struct RM_POOL_ALLOC_MEM_RESERVE_INFO   RM_POOL_ALLOC_MEM_RESERVE_INFO;
64 
65 /*!
66  * Opaque user-defined state describing a block of physical memory.
67  * We reference these as the backing memory for the allocation.
68  */
69 typedef struct RM_POOL_ALLOC_MEMDESC            RM_POOL_ALLOC_MEMDESC;
70 
71 /* ------------------------------- Public Interface ----------------------------- */
72 
73 /*!
74  * @brief Sets up the memory pool and the tracking structure.
75  *
76  * @param[in] pCtx              Pointer to some user context data
77  * @param[in] ppMemReserveInfo  Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
78  * @param[in] configMode        Mode to configure the pool
79  *
80  * @return
81  *      NV_OK:
82  *          Internal memory allocation failed.
83  */
84 NV_STATUS rmMemPoolSetup(void *pCtx, RM_POOL_ALLOC_MEM_RESERVE_INFO **ppMemReserve, POOL_CONFIG_MODE configMode);
85 
86 /*!
87  * @brief Reserve memory for the allocation in vidmem. Physical frames are
88  *        added to the memory pool on need basis only when a mapping is
89  *        made in the VAS.
90  *
91  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
92  * @param[in] poolSize        pool size
93  * @param[in] flags           VASpace flags to skip scrubbing in PMA for internal clients
94  *
95  * @return
96  *      NV_ERR_NO_MEMORY:
97  *          Internal memory allocation failed
98  *      NV_ERR_INVALID_ARGUMENT:
99  *          Invalid argument
100  */
101 NV_STATUS rmMemPoolReserve(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserve,
102                                NvU64 poolSize, NvU32 flags);
103 
104 /*!
105  * @brief Releases the memory pool memory to the PMA once all allocations are
106  *        returned back to it.
107  *
108  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
109  * @param[in] flags           VASpace flags to skip scrubbing in PMA for internal clients
110  *
111  * @return
112  */
113 void      rmMemPoolRelease(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo, NvU32 flags);
114 
115 /*!
116  * @brief Returns any unused nodes from the topmost level of a pool hierarchy
117  *        back to PMA.
118  *
119  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
120  * @param[in] nodesToPreserve Number of nodes to preserve in the topmost pool
121  * @param[in] flags           VASpace flags to skip scrubbing in PMA for internal clients
122 
123  * @return
124  */
125 void      rmMemPoolTrim (RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo,
126                              NvU32 nodesToPreserve, NvU32 flags);
127 
128 /*!
129  * @brief Suballocate memory for an allocation from the pool created
130  *        by @see rmMemPoolReserve.
131  *
132  * @param[in] pMemReserveInfo    Pointer to RM_POOL_ALLOC_MEM_RESERVE_INFO data
133  * @param[in] pMemDesc           Pointer to the allocations mem descriptor
134  *
135  * @return
136  *      NV_ERR_NO_MEMORY:
137  *          Internal memory allocation failed.
138  *      NV_ERR_GENERIC:
139  *          Unexpected error.
140  */
141 NV_STATUS rmMemPoolAllocate(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo,
142                                 RM_POOL_ALLOC_MEMDESC *pPoolMemDesc);
143 
144 /*!
145  * @brief Returns the allocation's memory back to the pool from
146  *        which it was borrowed.
147  *
148  * @param[in] pMemReserveInfo    Pointer to RM_POOL_ALLOC_MEM_RESERVE_INFO data
149  * @param[in] pMemDesc           Pointer to the allocations mem descriptor
150  * @param[in] flags              VASpace flags to skip scrubbing in PMA for internal clients
151  *
152  * @return
153  */
154 void      rmMemPoolFree(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo,
155                             RM_POOL_ALLOC_MEMDESC *pPoolMemDesc, NvU32 flags);
156 
157 /*!
158  * @brief Destroys the memory pool once all allocations are returned
159  *        back to it.
160  *
161  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
162  *
163  * @return
164  */
165 void      rmMemPoolDestroy(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo);
166 
167 /*!
168  * @brief Setup pool to skip scrubber.
169  *
170  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
171  * @param[in] bSkipScrub      skip scrubber
172  *
173  * @return
174  */
175 void      rmMemPoolSkipScrub(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo, NvBool bSkipScrub);
176 
177 /*!
178  * @brief Get pool setting for skipping scrubber.
179  *
180  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
181  *
182  * @return
183  *      NV_TRUE  Scrubbing is skipped
184  *      NV_FALSE Scrubbing not skipped
185  */
186 NvBool    rmMemPoolIsScrubSkipped(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo);
187 
188 /*!
189  * @brief Get page size and chunk size for a pool
190  *
191  * @param[in] pMemReserveInfo Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
192  * @param[out] chunkSize
193  * @param[out] pageSize
194  *
195  * @return
196  *    NV_ERR_INVALID_ARGUMENT
197  *    NV_OK
198  */
199 NV_STATUS      rmMemPoolGetChunkAndPageSize(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo, NvU64*, NvU64*);
200 
201 /*!
202  * @brief Indicate that pool should be allocated in protected video memory in
203  *        case memory protection is enabled
204  *
205  * @param[in] pMemReserveInfo  Pointer to the RM_POOL_ALLOC_MEM_RESERVE_INFO data
206  * @param[in] bProtected       Allocate in protected memory
207  *
208  * @return
209  */
210 void           rmMemPoolAllocateProtectedMemory(RM_POOL_ALLOC_MEM_RESERVE_INFO *pMemReserveInfo, NvBool bProtected);
211 
212 #endif //_RM_POOL_ALLOC_
213