1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2015-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 #include "g_rs_resource_nvoc.h" 25 26 #ifndef _RS_RESOURCE_H_ 27 #define _RS_RESOURCE_H_ 28 29 #include "nvport/nvport.h" 30 #include "resserv/resserv.h" 31 #include "nvoc/object.h" 32 #include "resserv/rs_access_map.h" 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 class RsSession; 39 40 /** 41 * @defgroup RsResource 42 * @addtogroup RsResource 43 * @{*/ 44 45 #define ALLOC_STATE_INTERNAL_CLIENT_HANDLE NVBIT(5) 46 47 /* 48 * Locking operations for lock-metering 49 */ 50 #define RS_LOCK_TRACE_INVALID 1 51 #define RS_LOCK_TRACE_ACQUIRE 1 52 #define RS_LOCK_TRACE_RELEASE 2 53 #define RS_LOCK_TRACE_ALLOC 3 54 #define RS_LOCK_TRACE_FREE 4 55 #define RS_LOCK_TRACE_CTRL 5 56 #define RS_LOCK_TRACE_MAP 6 57 #define RS_LOCK_TRACE_UNMAP 7 58 59 /** 60 * Context information for top-level, resource-level, and client-level locking 61 * operations 62 */ 63 struct RS_LOCK_INFO 64 { 65 RsClient *pClient; ///< Pointer to client that was locked (if any) 66 RsClient *pSecondClient; ///< Pointer to second client, for dual-client locking 67 RsResourceRef *pContextRef; ///< User-defined reference 68 RsSession *pSession; ///< Session object to be locked, if any 69 NvU32 flags; ///< RS_LOCK_FLAGS_* 70 NvU32 state; ///< RS_LOCK_STATE_* 71 NvU32 gpuMask; 72 NvU8 traceOp; ///< RS_LOCK_TRACE_* operation for lock-metering 73 NvU32 traceClassId; ///< Class of initial resource that was locked for lock metering 74 }; 75 76 struct RS_RES_ALLOC_PARAMS_INTERNAL 77 { 78 NvHandle hClient; ///< [in] The handle of the resource's client 79 NvHandle hParent; ///< [in] The handle of the resource's parent. This may be a client or another resource. 80 NvHandle hResource; ///< [inout] Server will assign a handle if this is 0, or else try the value provided 81 NvU32 externalClassId; ///< [in] External class ID of resource 82 NvHandle hDomain; ///< UNUSED 83 84 // Internal use only 85 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 86 RsClient *pClient; ///< [out] Cached client 87 RsResourceRef *pResourceRef; ///< [out] Cached resource reference 88 NvU32 allocFlags; ///< [in] Allocation flags 89 NvU32 allocState; ///< [inout] Allocation state 90 API_SECURITY_INFO *pSecInfo; 91 92 void *pAllocParams; ///< [in] Copied-in allocation parameters 93 NvU32 paramsSize; ///< [in] Copied-in allocation parameters size 94 95 // ... Dupe alloc 96 RsClient *pSrcClient; ///< The client that is sharing the resource 97 RsResourceRef *pSrcRef; ///< Reference to the resource that will be shared 98 99 RS_ACCESS_MASK *pRightsRequested; ///< [in] Access rights requested on the new resource 100 // Buffer for storing contents of user mask. Do not use directly, use pRightsRequested instead. 101 RS_ACCESS_MASK rightsRequestedCopy; 102 103 RS_ACCESS_MASK *pRightsRequired; ///< [in] Access rights required to alloc this object type 104 }; 105 106 struct RS_RES_DUP_PARAMS_INTERNAL 107 { 108 NvHandle hClientSrc; ///< [in] The handle of the source resource's client 109 NvHandle hResourceSrc; ///< [in] The handle of the source resource. 110 NvHandle hClientDst; ///< [in] The handle of the destination resource's client (may be different from source client) 111 NvHandle hParentDst; ///< [in] The handle of the destination resource's parent. 112 NvHandle hResourceDst; ///< [inout] The handle of the destination resource. Generated if 0. 113 void *pShareParams; ///< [in] Copied-in sharing parameters 114 NvU32 flags; ///< [in] Flags to denote special cases ( Bug: 2859347 to track removal) 115 // Internal use only 116 RsClient *pSrcClient; 117 RsResourceRef *pSrcRef; 118 API_SECURITY_INFO *pSecInfo; ///< [in] Security info 119 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 120 }; 121 122 struct RS_RES_SHARE_PARAMS_INTERNAL 123 { 124 NvHandle hClient; ///< [in] The handle of the owner's client 125 NvHandle hResource; ///< [in] The handle of the resource. 126 RS_SHARE_POLICY *pSharePolicy; ///< [in] The policy to share with 127 128 // Internal use only 129 API_SECURITY_INFO *pSecInfo; ///< [in] Security info 130 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 131 }; 132 133 #define RS_IS_COPY_CTOR(pParams) ((pParams)->pSrcRef != NULL) 134 135 struct RS_RES_FREE_PARAMS_INTERNAL 136 { 137 NvHandle hClient; ///< [in] The handle of the resource's client 138 NvHandle hResource; ///< [in] The handle of the resource 139 NvBool bInvalidateOnly; ///< [in] Free the resource, but don't release its handle 140 NvHandle hDomain; ///< UNUSED 141 142 // Internal use only 143 NvBool bHiPriOnly; ///< [in] Only free if this is a high priority resources 144 NvBool bDisableOnly; ///< [in] Disable the target instead of freeing it (only applies to clients) 145 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 146 NvU32 freeFlags; ///< [in] Flags for the free operation 147 NvU32 freeState; ///< [inout] Free state 148 RsResourceRef *pResourceRef; ///< [inout] Cached RsResourceRef 149 NV_STATUS status; ///< [out] Status of free operation 150 API_SECURITY_INFO *pSecInfo; ///< [in] Security info 151 }; 152 153 struct NVOC_EXPORTED_METHOD_DEF; 154 class OBJGPU; 155 class OBJGPUGRP; 156 157 // 158 // RS_RES_CONTROL_PARAMS 159 // 160 // This structure encapsulates data sent to the cmd-specific rmctrl 161 // handlers. Along with the arguments supplied by the requesting 162 // client (hClient, hObject, cmd, pParams, paramSize). 163 // 164 struct RS_RES_CONTROL_PARAMS_INTERNAL 165 { 166 NvHandle hClient; // client-specified NV01_ROOT object handle 167 NvHandle hObject; // client-specified object handle 168 NvU32 cmd; // client-specified command # 169 NvU32 flags; // flags related to control call execution 170 void *pParams; // client-specified params (in kernel space) 171 NvU32 paramsSize; // client-specified size of pParams in bytes 172 173 NvHandle hParent; // handle of hObject parent 174 OBJGPU *pGpu; // ptr to OBJGPU struct if applicable 175 OBJGPUGRP *pGpuGrp; // ptr to OBJGPUGRP struct if applicable 176 RsResourceRef *pResourceRef; // ptr to RsResourceRef if object is managed by 177 // Resource Server 178 API_SECURITY_INFO secInfo; // information on privilege level and pointer location (user/kernel) 179 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 180 RS_CONTROL_COOKIE *pCookie; 181 NvBool bInternal; // True if control call was not issued from an external client 182 NvBool bDeferredApi; // Indicates ctrl is being dispatched via deferred API 183 184 struct RS_RES_CONTROL_PARAMS_INTERNAL *pLegacyParams; // RS-TODO removeme 185 }; 186 187 struct RS_RES_DTOR_PARAMS 188 { 189 CALL_CONTEXT *pFreeContext; 190 RS_RES_FREE_PARAMS_INTERNAL *pFreeParams; 191 }; 192 193 /** 194 * Base class for all resources. Mostly a pure virtual interface which 195 * should be overridden to implement resource specific behavior. 196 */ 197 NVOC_PREFIX(res) class RsResource : Object 198 { 199 public: 200 // private: 201 202 /** 203 * Back-reference to the RsResourceRef that owns this object 204 */ 205 RsResourceRef *pResourceRef; 206 207 /** 208 * Params for dtor 209 */ 210 RS_RES_DTOR_PARAMS dtorParams; 211 212 /** 213 * Flag that indicates whether the RsResource was constructed. If params to 214 * resConstruct are null the Resource ctor and dtor will be skipped. This is 215 * only added for migration where the entire class hierarchy can't be 216 * converted at once. 217 * 218 * RS-TODO: Remove once migrations are finished (added initially for 219 * DmaObject) 220 */ 221 NvBool bConstructed; 222 223 public: 224 225 /** 226 * Resource initializer 227 * @param[in] pResource Resource object to init 228 * @param[in] pCallContext 229 * @param[in] params Resource create parameters 230 */ 231 NV_STATUS resConstruct(RsResource *pResource, CALL_CONTEXT *pCallContext, RS_RES_ALLOC_PARAMS_INTERNAL *pParams); 232 233 /** 234 * Returns TRUE if the resource can be copied 235 */ 236 virtual NvBool resCanCopy(RsResource *pResource); 237 238 /** 239 * Returns TRUE if the resources are duplicates 240 */ 241 virtual NV_STATUS resIsDuplicate(RsResource *pResource, NvHandle hMemory, NvBool *pDuplicate); 242 243 /** 244 * Resource destructor 245 * @param[in] pResource Resource object to destruct 246 */ 247 void resDestruct(RsResource *pResource); 248 249 /** 250 * Resource destructor prologue (occurs before mappings are torn-down) 251 * @param[in] pResource Resource object to destruct 252 */ 253 virtual void resPreDestruct(RsResource *pResource); 254 255 /** 256 * Resource dtors take no parameters, so set them here. 257 * @param[in] pResource 258 * @param[in] pCallContext 259 * @param[in] params Resource destroy parameters 260 */ 261 NV_STATUS resSetFreeParams(RsResource *pResource, CALL_CONTEXT *pCallContext, RS_RES_FREE_PARAMS_INTERNAL *pParams); 262 263 /** 264 * Resource dtors take no parameters, so get them here. 265 * @param[in] pResource 266 * @param[out] ppCallContext 267 * @param[out] ppParams Resource destroy parameters 268 */ 269 NV_STATUS resGetFreeParams(RsResource *pResource, CALL_CONTEXT **ppCallContext, RS_RES_FREE_PARAMS_INTERNAL **ppParams); 270 271 /** 272 * Lookup a control call entry from a NVOC export table 273 * 274 * @param[in] pResource 275 * @param[in] pParams 276 * @param[out] ppEntry 277 */ 278 virtual NV_STATUS resControlLookup(RsResource *pResource, 279 RS_RES_CONTROL_PARAMS_INTERNAL *pParams, 280 const struct NVOC_EXPORTED_METHOD_DEF **ppEntry); 281 282 /** 283 * Dispatch resource control call 284 * @param[in] pResource 285 * @param[in] pCallContext 286 * @param[in] pParams 287 */ 288 virtual NV_STATUS resControl(RsResource *pResource, CALL_CONTEXT *pCallContext, 289 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 290 291 /** 292 * Early filter for control calls we don't want to service on a particular platform 293 * 294 * @param[in] pResource 295 * @param[in] pCallContext 296 * @param[in] pParams 297 */ 298 virtual NV_STATUS resControlFilter(RsResource *pResource, CALL_CONTEXT *pCallContext, 299 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 300 301 /** 302 * Serialize the control parameters if they are going to GSP/Host, not serialized, and support serialization 303 * Or 304 * Deserialize the control parameters if necessary and replace the inner params pointer with the deserialized params 305 * 306 * @param[in] pResource 307 * @param[in] pCallContext 308 * @param[in] pParams 309 */ 310 virtual NV_STATUS resControlSerialization_Prologue(RsResource *pResource, CALL_CONTEXT *pCallContext, 311 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 312 313 /** 314 * Deserialize the parameters returned from GSP if client did not pass serialized params 315 * Or 316 * Serialize the control parameters if client expects it and restore the original inner params pointer 317 * 318 * @param[in] pResource 319 * @param[in] pCallContext 320 * @param[in] pParams 321 */ 322 virtual void resControlSerialization_Epilogue(RsResource *pResource, CALL_CONTEXT *pCallContext, 323 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 324 325 /** 326 * Operations performed right before the control call is executed. Default stubbed. 327 * 328 * @param[in] pResource 329 * @param[in] pCallContext 330 * @param[in] pParams 331 */ 332 virtual NV_STATUS resControl_Prologue(RsResource *pResource, CALL_CONTEXT *pCallContext, 333 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 334 335 /** 336 * Operations performed right after the control call is executed. No return value. (void) 337 * 338 * @param[in] pResource 339 * @param[in] pCallContext 340 * @param[in] pParams 341 */ 342 virtual void resControl_Epilogue(RsResource *pResource, CALL_CONTEXT *pCallContext, 343 RS_RES_CONTROL_PARAMS_INTERNAL *pParams); 344 345 /** 346 * Creates a mapping of the underlying resource in the physical address space of the requested process. 347 * 348 * The difference between serverResMap and resMap is that resMap provides a locked physical address 349 * and serverResMap creates a virtual mapping to the physical address. For virtualization, the 350 * tandem resource servers should be able to map a host physical address in a guest user space 351 * VA without any resource-specific VA mapping code. 352 * 353 * Not all resources support mapping. 354 * 355 * @param[in] pResource Resource to map 356 * @param[in] pCallContext 357 * @param[inout] pCpuMapping 358 */ 359 virtual NV_STATUS resMap(RsResource *pResource, 360 CALL_CONTEXT *pCallContext, 361 RS_CPU_MAP_PARAMS *pParams, 362 RsCpuMapping *pCpuMapping); 363 364 /** 365 * Release a virtual address mapping 366 * @param[in] pResource Resource to map 367 * @param[in] pCallContext 368 * @param[in] pCpuMapping 369 */ 370 virtual NV_STATUS resUnmap(RsResource *pResource, CALL_CONTEXT *pCallContext, RsCpuMapping *pCpuMapping); 371 372 /** 373 * Maps to this resource from another resource 374 * Not all resources can be mapped to, in such a case returns NV_ERR_INVALID_OBJECT_HANDLE 375 * 376 * @param[in] pResource 377 * @param[inout] pParams 378 */ 379 virtual NV_STATUS resMapTo(RsResource *pResource, RS_RES_MAP_TO_PARAMS *pParams); 380 381 /** 382 * Unmaps a resource mapped to this resource 383 * Not all resources can be unmapped, in such a case returns NV_ERR_INVALID_OBJECT_HANDLE 384 * 385 * @param[in] pResource 386 * @param[in] pParams 387 */ 388 virtual NV_STATUS resUnmapFrom(RsResource *pResource, RS_RES_UNMAP_FROM_PARAMS *pParams); 389 390 /** 391 * Gets a refcount for any underlying shared resource 392 * @returns refcount 393 */ 394 virtual NvU32 resGetRefCount(RsResource *pResource); 395 396 /** 397 * Decides whether the invoking client should be granted an access right on this resource. 398 * 399 * The purpose of providing this function is to provide subclassed resources the ability 400 * to set custom policies for granting access rights. These policies can be implemented 401 * based on the ambient privilege of the caller, such as the PID. 402 * 403 * @param[in] pResource The resource for which the access right will be granted 404 * @param[in] pInvokingClient The client requesting the access right 405 * @param[in] pAllocParams The alloc params struct passed into the alloc call, 406 * NULL if called from outside the Alloc path 407 * @param[in] accessRight The access right to be granted 408 * @returns NV_TRUE if the access right should be granted, and NV_FALSE otherwise 409 */ 410 virtual NvBool resAccessCallback(RsResource *pResource, RsClient *pInvokingClient, void *pAllocParams, RsAccessRight accessRight); 411 412 /** 413 * Decides whether rights can be shared with a client under a certain policy. 414 * 415 * The purpose of this function is to provide subclasses the ability to set custom definitions 416 * for how certain policies will share. Certain share types can then be created to work based 417 * on components not stored directly in resserv, such as PID. 418 * 419 * @param[in] pResource The resource being shared 420 * @param[in] pInvokingClient The client being shared with 421 * @param[in] pParentRef dstParent if calling from DupObject, NULL otherwise 422 * @param[in] pSharePolicy The policy under which to share 423 * @returns NV_TRUE if the share policy applies and rights should be shared, NV_FALSE otherwise 424 */ 425 virtual NvBool resShareCallback(RsResource *pResource, RsClient *pInvokingClient, RsResourceRef *pParentRef, RS_SHARE_POLICY *pSharePolicy); 426 427 /** 428 * Adds dependants that aren't in childRefMap or depRefMap to the pending free list. 429 * 430 * Due to RAM constraints, some classes can add more dependants that aren't 431 * represented in childRefMap or depRefMap. They can override this function 432 * to put them in the pending free list while we are updating it. 433 * 434 * @param[in] pClient 435 * @param[in] pResource The RsResource with potential additional dependants 436 * @param[in] pReference The pReference to pass in to 437 * clientUpdatePendingFreeList() 438 */ 439 virtual void resAddAdditionalDependants(RsClient *pClient, RsResource *pResource, RsResourceRef *pReference); 440 }; 441 442 /* @} */ 443 444 class OBJGPU; 445 446 /** 447 * @defgroup RsCpuMapping 448 * @addtogroup RsCpuMapping 449 * @{*/ 450 struct RsCpuMapping 451 { 452 NvU64 offset; 453 NvU64 length; 454 NvU32 flags; 455 NvP64 pLinearAddress; 456 RsResourceRef *pContextRef; ///< Context resource that may be needed for the mapping 457 void *pContext; ///< Additional context data for the mapping 458 NvU32 processId; 459 460 RS_CPU_MAPPING_PRIVATE *pPrivate; ///< Opaque struct allocated and freed by resserv on behalf of the user 461 }; 462 MAKE_LIST(RsCpuMappingList, RsCpuMapping); 463 464 /** 465 * CPU mapping parameters 466 */ 467 struct RS_CPU_MAP_PARAMS 468 { 469 NvHandle hClient; 470 NvHandle hDevice; 471 NvHandle hMemory; 472 NvU64 offset; ///< [in] Offset into the resource 473 NvU64 length; ///< [in] Size of the region to map 474 NvP64 *ppCpuVirtAddr; 475 NvU32 flags; ///< [in] Resource-specific flags 476 477 // Passed from RM into CpuMapping 478 NvU32 protect; ///< [in] Protection flags 479 NvBool bKernel; 480 481 /// [in] hContext Handle of resource that provides a context for the mapping (e.g., subdevice for channel map) 482 NvHandle hContext; 483 484 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 485 API_SECURITY_INFO *pSecInfo; ///< [in] Security Info 486 }; 487 488 /** 489 * CPU unmapping params for resource server tests 490 */ 491 struct RS_CPU_UNMAP_PARAMS 492 { 493 NvHandle hClient; 494 NvHandle hDevice; 495 NvHandle hMemory; 496 NvP64 pLinearAddress; ///< [in] Address of mapped memory 497 NvU32 flags; ///< [in] Resource-specific flags 498 NvU32 processId; 499 NvBool bTeardown; ///< [in] Unmap operation is due to client teardown 500 501 /// [in] hContext Handle of resource that provides a context for the mapping (e.g., subdevice for channel map) 502 NvHandle hContext; 503 504 // RM-only 505 void *pProcessHandle; 506 507 NvBool (*fnFilter)(RsCpuMapping*); ///< [in] Mapping-filter function 508 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 509 API_SECURITY_INFO *pSecInfo; ///< [in] Security Info 510 }; 511 512 /** 513 * CPU mapping back-reference 514 */ 515 struct RS_CPU_MAPPING_BACK_REF 516 { 517 RsCpuMapping *pCpuMapping; ///< Mapping linked to this backref 518 RsResourceRef *pBackRef; ///< Resource reference with mapping 519 }; 520 MAKE_LIST(RsCpuMappingBackRefList, RS_CPU_MAPPING_BACK_REF); 521 /* @} */ 522 523 /** 524 * @defgroup RsInterMapping 525 * @addtogroup RsInterMapping 526 * @{*/ 527 struct RS_INTER_MAP_PARAMS 528 { 529 NvHandle hClient; 530 NvHandle hMapper; 531 NvHandle hMappable; 532 NvHandle hDevice; 533 NvU64 offset; 534 NvU64 length; 535 NvU32 flags; 536 NvU64 dmaOffset; ///< [inout] RS-TODO rename this 537 void *pMemDesc; ///< [out] 538 539 // Internal use only 540 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 541 API_SECURITY_INFO *pSecInfo; ///< [in] Security Info 542 543 RS_INTER_MAP_PRIVATE *pPrivate; ///< Opaque struct controlled by caller 544 }; 545 546 struct RS_INTER_UNMAP_PARAMS 547 { 548 NvHandle hClient; 549 NvHandle hMapper; 550 NvHandle hMappable; 551 NvHandle hDevice; 552 NvU32 flags; 553 NvU64 dmaOffset; ///< [in] RS-TODO rename this 554 void *pMemDesc; ///< MEMORY_DESCRIPTOR * 555 556 // Internal use only 557 RS_LOCK_INFO *pLockInfo; ///< [inout] Locking flags and state 558 API_SECURITY_INFO *pSecInfo; ///< [in] Security Info 559 560 RS_INTER_UNMAP_PRIVATE *pPrivate; ///< Opaque struct controlled by caller 561 }; 562 563 /** 564 * Inter-mapping information 565 * Used to keep track of inter-mappings and unmap them on free 566 */ 567 struct RsInterMapping 568 { 569 // RsResourceRef *pMapperRef ///< (Implied) the resource that created and owns this mapping (this resource) 570 RsResourceRef *pMappableRef; ///< The resource being mapped by the mapper (e.g. hMemory) 571 RsResourceRef *pContextRef; ///< A resource used to provide additional context for the mapping (e.g. hDevice) 572 NvU32 flags; ///< Flags passed when mapping, same flags also passed when unmapping 573 NvU64 dmaOffset; 574 void *pMemDesc; 575 }; 576 MAKE_LIST(RsInterMappingList, RsInterMapping); 577 578 /** 579 * Inter-mapping back-reference 580 */ 581 struct RS_INTER_MAPPING_BACK_REF 582 { 583 RsResourceRef *pMapperRef; ///< Resource reference with mapping 584 RsInterMapping *pMapping; ///< Pointer to the inter-mapping linked to this backref 585 }; 586 MAKE_LIST(RsInterMappingBackRefList, RS_INTER_MAPPING_BACK_REF); 587 /* @} */ 588 589 typedef struct RS_RESOURCE_DESC RS_RESOURCE_DESC; 590 RS_RESOURCE_DESC *RsResInfoByExternalClassId(NvU32); 591 NvU32 RsResInfoGetInternalClassId(const RS_RESOURCE_DESC *); 592 593 /** 594 * A reference to a resource that has been allocated in RM. 595 */ 596 struct RsResourceRef 597 { 598 RsClient *pClient; ///< Pointer to the client that owns the ref 599 RsResource *pResource; ///< Pointer to the actual resource 600 NvHandle hResource; ///< Resource handle 601 struct RsResourceRef *pParentRef; ///< Parent resource reference 602 RsIndex childRefMap; ///< Child reference multi-map: { internalClassId -> { handle -> RsResourceRef } } 603 604 /** 605 * Cached reference multi-map: { internalClassId -> { handle -> RsResourceRef } } 606 * 607 * The resource reference cache is a one-way association between this resource reference and 608 * any other resource reference. Resource server does not populate the cache so it is up to the 609 * resource implementation to manage it. clientRefIter can be used to iterate this cache. 610 */ 611 RsIndex cachedRefMap; 612 613 /** 614 * Dependants reference multi-map: { internalClassId -> { handle -> RsResourceRef } } 615 * 616 * A map of all resources that strongly depend on this resource. 617 */ 618 RsIndex depRefMap; 619 620 /** 621 * Dependants back-reference multi-map: { internalClassId -> { handle -> RsResourceRef } } 622 * 623 * AKA dependencies map 624 * 625 * A map of all resources that this resource strongly depends on. 626 */ 627 RsIndex depBackRefMap; 628 629 /** 630 * Policy under which this resource can be shared with other clients 631 */ 632 RsShareList sharePolicyList; 633 NvBool bSharePolicyListModified; 634 635 /** 636 * A mask of the access rights that the owner client has on this object. 637 */ 638 RS_ACCESS_MASK accessMask; 639 640 const RS_RESOURCE_DESC *pResourceDesc; ///< Cached pointer to the resource descriptor 641 NvU32 internalClassId; ///< Internal resource class id 642 NvU32 externalClassId; ///< External resource class id 643 NvU32 depth; ///< The depth of this reference in the resource graph 644 NvBool bInvalidated; ///< Reference has been freed but not removed yet 645 646 RsCpuMappingList cpuMappings; ///< List of CPU mappings to the resource from this resource reference 647 RsCpuMappingBackRefList backRefs; ///< List of references that have this reference as a mapping context 648 649 RsInterMappingList interMappings; ///< List of inter-resource mappings created by this resource 650 RsInterMappingBackRefList interBackRefs; ///< List of inter-resource mappings this resource has been mapped into 651 652 RsSession *pSession; ///< If set, this ref depends on a shared session 653 RsSession *pDependantSession; ///< If set, this ref is depended on by a shared session 654 655 ListNode freeNode; ///< Links to the client's pendingFreeList 656 }; 657 MAKE_MAP(RsRefMap, RsResourceRef); 658 MAKE_INTRUSIVE_LIST(RsRefFreeList, RsResourceRef, freeNode); 659 660 661 // Iterator data structure to save state while walking through a list 662 struct RS_ITERATOR 663 { 664 union 665 { 666 RsRefMapIter mapIt; ///< Map iterator for all resource references under a client 667 RsIndexIter idxIt; ///< Index iterator for child references of a resource reference 668 }; 669 670 RsClient *pClient; 671 RsResourceRef *pScopeRef; ///< Reference to the resource that limits the scope of iteration 672 NvU32 internalClassId; 673 RsResourceRef *pResourceRef; ///< Resource ref that is being iterated over 674 NvU8 type; ///< RS_ITERATE_* 675 NvBool bExactMatch; ///< If true, internalClassId must match exactly; if false, also match classes derived from the internalClassId 676 }; 677 678 // Iterator data structure to save state while walking through a resource tree in pre-order 679 struct RS_ORDERED_ITERATOR 680 { 681 NvS8 depth; ///< Depth of index stack; special value of -1 implies that the scope reference should be iterated over as well 682 RsIndexIter idxIt[RS_MAX_RESOURCE_DEPTH+1]; ///< Stack of index iterators for child references of a resource reference 683 684 RsClient *pClient; 685 RsResourceRef *pScopeRef; ///< Reference to the resource that limits the scope of iteration 686 NvU32 internalClassId; 687 NvBool bExactMatch; ///< If true, internalClassId must match exactly; if false, also match classes derived from the internalClassId 688 689 RsResourceRef *pResourceRef; ///< Resource ref that is being iterated over 690 }; 691 692 /** 693 * Macro for looking up a reference from a resource 694 */ 695 #define RES_GET_REF(pResource) (staticCast((pResource), RsResource)->pResourceRef) 696 697 /** 698 * Macro for looking up a resource handle from a resource 699 */ 700 #define RES_GET_HANDLE(pResource) (RES_GET_REF(pResource)->hResource) 701 702 /** 703 * Macro for looking up a resource's external class from a resource 704 */ 705 #define RES_GET_EXT_CLASS_ID(pResource) (RES_GET_REF(pResource)->externalClassId) 706 707 /** 708 * Macro for looking up a resource's parent handle from a resource 709 */ 710 #define RES_GET_PARENT_HANDLE(pResource) (RES_GET_REF(pResource)->pParentRef->hResource) 711 712 /** 713 * Macro for looking up a client from a resource 714 */ 715 #define RES_GET_CLIENT(pResource) (RES_GET_REF(pResource)->pClient) 716 717 /** 718 * Macro for looking up a client handle from a resource 719 */ 720 #define RES_GET_CLIENT_HANDLE(pResource) (RES_GET_REF(pResource)->pClient->hClient) 721 722 /** 723 * Find a CPU mapping owned by a resource reference 724 * 725 * @param[in] pResourceRef 726 * @param[in] pAddress The CPU virtual address of the mapping to search for 727 * @param[out] ppMapping The returned mapping 728 */ 729 NV_STATUS refFindCpuMapping(RsResourceRef *pResourceRef, NvP64 pAddress, RsCpuMapping **ppMapping); 730 731 /** 732 * Find a CPU mapping owned by a resource reference 733 * 734 * @param[in] pResourceRef 735 * @param[in] pAddress The CPU virtual address of the mapping to search for 736 * @param[in] fnFilter A user-provided filtering function that determines which mappings to ignore. 737 * If fnFilter is provided, then we will only return mappings for which fnFilter(mapping) returns NV_TRUE 738 * All mappings will be searched over if fnFilter is NULL. 739 * @param[out] ppMapping The returned mapping 740 * @param[in] fnFilter A user-provided filtering function that determines which mappings to ignore. 741 * If fnFilter is provided, then we will only return mappings for which fnFilter(mapping) returns NV_TRUE 742 * All mappings will be searched over if fnFilter is NULL. 743 */ 744 NV_STATUS refFindCpuMappingWithFilter(RsResourceRef *pResourceRef, NvP64 pAddress, NvBool (*fnFilter)(RsCpuMapping*), RsCpuMapping **ppMapping); 745 746 /** 747 * Find the first child object of given type 748 * 749 * @param[in] pParentRef 750 * @param[in] internalClassId 751 * @param[in] bExactMatch If true, internalClassId must match exactly; if false, also match classes derived from the internalClassId 752 * @param[out] pResourceRef The returned RsResourceRef (Optional) 753 */ 754 NV_STATUS refFindChildOfType(RsResourceRef *pParentRef, NvU32 internalClassId, NvBool bExactMatch, RsResourceRef **ppResourceRef); 755 756 /** 757 * Traverse up the reference parent-child hierarchy to find an ancestor reference of a given type 758 * 759 * @param[in] pDescendantRef 760 * @param[in] internalClassId 761 * @param[out] ppAncestorRef The returned RsResourceRef (Optional) 762 */ 763 NV_STATUS refFindAncestorOfType(RsResourceRef *pDescendantRef, NvU32 internalClassId, RsResourceRef **ppAncestorRef); 764 765 /** 766 * Traverse up the reference parent-child hierarchy to find if a ref is a descendant of a given ancestor ref 767 * 768 * @param[in] pDescendantRef The node to start searching from (not included in the search) 769 * @param[in] pAncestorRef The node to search for in the parent-child hierarchy 770 */ 771 NvBool refHasAncestor(RsResourceRef *pDescendantRef, RsResourceRef *pAncestorRef); 772 773 /** 774 * Add a new mapping to a reference's mapping list 775 * @param[in] pResourceRef The reference to add a mapping to 776 * @param[in] pMapParams The parameters used to initialize the mapping 777 * @param[in] pContextRef A reference to a resource that provides a context for the mapping 778 * @param[out] ppMapping Pointer to the allocated mapping [optional] 779 */ 780 NV_STATUS refAddMapping(RsResourceRef *pResourceRef, RS_CPU_MAP_PARAMS *pMapParams, 781 RsResourceRef *pContextRef, RsCpuMapping **ppMapping); 782 783 /** 784 * Remove an existing mapping from a reference's mapping list and remove back-references to the mapping. 785 * @param[in] pResourceRef The reference to add a mapping to 786 * @param[in] pMapping Pointer to the allocated mapping 787 */ 788 void refRemoveMapping(RsResourceRef *pResourceRef, RsCpuMapping *pMapping); 789 790 /** 791 * Allocate the user-controlled private pointer within the RsCpuMapping struct. 792 * Resserv will call this function to alloc the private struct when the mapping is created 793 * @param[in] pMapParams The parameters which were used to create the mapping 794 * @param[inout] pMapping Pointer to the mapping whose private struct should be allocated 795 */ 796 NV_STATUS refAllocCpuMappingPrivate(RS_CPU_MAP_PARAMS *pMapParams, RsCpuMapping *pMapping); 797 798 /** 799 * Free the user-controlled private pointer within the RsCpuMapping struct. 800 * Resserv will call this function to free the private struct when the mapping is removed 801 * @param[inout] pMapping Pointer to the mapping whose private struct should be freed 802 */ 803 void refFreeCpuMappingPrivate(RsCpuMapping *pMapping); 804 805 /** 806 * Add a dependency between this resource reference and a dependent reference. 807 * If this reference is freed, the dependent will be invalidated and torn down. 808 * 809 * @note Dependencies are implicit between a parent resource reference and child resource reference 810 * @note No circular dependency checking is performed 811 */ 812 NV_STATUS refAddDependant(RsResourceRef *pResourceRef, RsResourceRef *pDependantRef); 813 814 /** 815 * Remove the dependency between this resource reference and a dependent resource reference. 816 */ 817 void refRemoveDependant(RsResourceRef *pResourceRef, RsResourceRef *pDependantRef); 818 819 /** 820 * Find, Add, or Remove an inter-mapping between two resources to the Mapper's list of inter-mappings 821 * Inter-mappings are stored in the Mapper, and are matched by both the MappableRef and offset. 822 * 823 * @param[in] pMapperRef The reference which owns the inter-mapping 824 * @param[in] pMappableRef The reference which was mapped from to create the inter-mapping 825 * If NULL, will be ignored while matching inter-mappings 826 * @param[in] dmaOffset The offset value assigned while mapping, used to identify mappings 827 * @param[in] pContextRef A reference used during mapping and locking for additional context, used to identify mappings 828 * @param[inout] ppMapping Writes the resulting inter-mapping, if successfully created (Add) or found (Find) 829 * @param[in] pMapping The inter-mapping to remove (Remove) 830 */ 831 NV_STATUS refFindInterMapping(RsResourceRef *pMapperRef, RsResourceRef *pMappableRef, RsResourceRef *pContextRef, NvU64 dmaOffset, RsInterMapping **ppMapping); 832 NV_STATUS refAddInterMapping(RsResourceRef *pMapperRef, RsResourceRef *pMappableRef, RsResourceRef *pContextRef, RsInterMapping **ppMapping); 833 void refRemoveInterMapping(RsResourceRef *pMapperRef, RsInterMapping *pMapping); 834 835 /** 836 * Store a resource reference in another reference's cache. 837 * @param[in] pParentRef The resource reference that owns the cache 838 * @param[in] pResourceRef The resource reference to store in the cache 839 */ 840 NV_STATUS refCacheRef(RsResourceRef *pParentRef, RsResourceRef *pResourceRef); 841 842 /** 843 * Remove a resource reference from another reference's cache 844 * @param[in] pParentRef The resource reference that owns the cache 845 * @param[in] pResourceRef The resource reference to de-index 846 */ 847 NV_STATUS refUncacheRef(RsResourceRef *pParentRef, RsResourceRef *pResourceRef); 848 849 /** 850 * Determine whether a reference is queued for removal 851 * @param[in] pResourceRef 852 * @param[in] pClient 853 */ 854 NvBool refPendingFree(RsResourceRef *pResourceRef, RsClient *pClient); 855 856 857 #ifdef __cplusplus 858 } 859 #endif 860 861 #endif 862