mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-04-28 10:11:19 +00:00
committed by
Gaurav Juvekar
parent
caa2dd11a0
commit
3084c04453
@@ -1,13 +1,20 @@
|
||||
|
||||
#ifndef _G_RS_SERVER_NVOC_H_
|
||||
#define _G_RS_SERVER_NVOC_H_
|
||||
#include "nvoc/runtime.h"
|
||||
|
||||
// Version of generated metadata structures
|
||||
#ifdef NVOC_METADATA_VERSION
|
||||
#undef NVOC_METADATA_VERSION
|
||||
#endif
|
||||
#define NVOC_METADATA_VERSION 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -29,6 +36,7 @@ extern "C" {
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "g_rs_server_nvoc.h"
|
||||
|
||||
#ifndef _RS_SERVER_H_
|
||||
@@ -43,6 +51,12 @@ extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum CLIENT_LOCK_TYPE
|
||||
{
|
||||
CLIENT_LOCK_SPECIFIC, // For locking specific RM clients encoded in the API
|
||||
CLIENT_LOCK_ALL // For locking all RM clients currently in use
|
||||
};
|
||||
|
||||
/**
|
||||
* @defgroup RsServer
|
||||
* @addtogroup RsServer
|
||||
@@ -57,12 +71,18 @@ struct CLIENT_ENTRY
|
||||
struct RsClient *pClient;
|
||||
NvHandle hClient;
|
||||
NvU64 lockOwnerTid; ///< Thread id of the lock owner
|
||||
NvU32 refCount;
|
||||
NvBool bPendingFree;
|
||||
ListNode node;
|
||||
|
||||
#if LOCK_VAL_ENABLED
|
||||
LOCK_VAL_LOCK lockVal;
|
||||
#endif
|
||||
};
|
||||
|
||||
MAKE_INTRUSIVE_LIST(RsClientList, CLIENT_ENTRY, node);
|
||||
MAKE_LIST(RsLockedClientList, CLIENT_ENTRY*);
|
||||
|
||||
/**
|
||||
* Base-class for objects that are shared among multiple
|
||||
* RsResources (including RsResources from other clients)
|
||||
@@ -77,11 +97,20 @@ struct CLIENT_ENTRY
|
||||
#define PRIVATE_FIELD(x) NVOC_PRIVATE_FIELD(x)
|
||||
#endif
|
||||
|
||||
|
||||
struct RsShared {
|
||||
|
||||
// Metadata
|
||||
const struct NVOC_RTTI *__nvoc_rtti;
|
||||
|
||||
// Parent (i.e. superclass or base class) object pointers
|
||||
struct Object __nvoc_base_Object;
|
||||
struct Object *__nvoc_pbase_Object;
|
||||
struct RsShared *__nvoc_pbase_RsShared;
|
||||
|
||||
// Ancestor object pointers for `staticCast` feature
|
||||
struct Object *__nvoc_pbase_Object; // obj super
|
||||
struct RsShared *__nvoc_pbase_RsShared; // shr
|
||||
|
||||
// Data members
|
||||
NvS32 refCount;
|
||||
struct MapNode node;
|
||||
};
|
||||
@@ -95,6 +124,7 @@ typedef struct RsShared RsShared;
|
||||
#define __nvoc_class_id_RsShared 0x830542
|
||||
#endif /* __nvoc_class_id_RsShared */
|
||||
|
||||
// Casting support
|
||||
extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsShared;
|
||||
|
||||
#define __staticCast_RsShared(pThis) \
|
||||
@@ -107,13 +137,16 @@ extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsShared;
|
||||
((RsShared*)__nvoc_dynamicCast(staticCast((pThis), Dynamic), classInfo(RsShared)))
|
||||
#endif //__nvoc_rs_server_h_disabled
|
||||
|
||||
|
||||
NV_STATUS __nvoc_objCreateDynamic_RsShared(RsShared**, Dynamic*, NvU32, va_list);
|
||||
|
||||
NV_STATUS __nvoc_objCreate_RsShared(RsShared**, Dynamic*, NvU32);
|
||||
#define __objCreate_RsShared(ppNewObj, pParent, createFlags) \
|
||||
__nvoc_objCreate_RsShared((ppNewObj), staticCast((pParent), Dynamic), (createFlags))
|
||||
|
||||
|
||||
// Wrapper macros
|
||||
|
||||
// Dispatch functions
|
||||
NV_STATUS shrConstruct_IMPL(struct RsShared *arg_pShared);
|
||||
|
||||
#define __nvoc_shrConstruct(arg_pShared) shrConstruct_IMPL(arg_pShared)
|
||||
@@ -140,14 +173,25 @@ MAKE_INTRUSIVE_MAP(RsSharedMap, RsShared, node);
|
||||
#define PRIVATE_FIELD(x) NVOC_PRIVATE_FIELD(x)
|
||||
#endif
|
||||
|
||||
|
||||
struct RsSession {
|
||||
|
||||
// Metadata
|
||||
const struct NVOC_RTTI *__nvoc_rtti;
|
||||
|
||||
// Parent (i.e. superclass or base class) object pointers
|
||||
struct RsShared __nvoc_base_RsShared;
|
||||
struct Object *__nvoc_pbase_Object;
|
||||
struct RsShared *__nvoc_pbase_RsShared;
|
||||
struct RsSession *__nvoc_pbase_RsSession;
|
||||
void (*__sessionRemoveDependant__)(struct RsSession *, struct RsResourceRef *);
|
||||
void (*__sessionRemoveDependency__)(struct RsSession *, struct RsResourceRef *);
|
||||
|
||||
// Ancestor object pointers for `staticCast` feature
|
||||
struct Object *__nvoc_pbase_Object; // obj super^2
|
||||
struct RsShared *__nvoc_pbase_RsShared; // shr super
|
||||
struct RsSession *__nvoc_pbase_RsSession; // session
|
||||
|
||||
// Vtable with 2 per-object function pointers
|
||||
void (*__sessionRemoveDependant__)(struct RsSession * /*this*/, struct RsResourceRef *); // virtual
|
||||
void (*__sessionRemoveDependency__)(struct RsSession * /*this*/, struct RsResourceRef *); // virtual
|
||||
|
||||
// Data members
|
||||
PORT_RWLOCK *pLock;
|
||||
NvBool bValid;
|
||||
RsResourceRefList dependencies;
|
||||
@@ -163,6 +207,7 @@ typedef struct RsSession RsSession;
|
||||
#define __nvoc_class_id_RsSession 0x830d90
|
||||
#endif /* __nvoc_class_id_RsSession */
|
||||
|
||||
// Casting support
|
||||
extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsSession;
|
||||
|
||||
#define __staticCast_RsSession(pThis) \
|
||||
@@ -175,27 +220,32 @@ extern const struct NVOC_CLASS_DEF __nvoc_class_def_RsSession;
|
||||
((RsSession*)__nvoc_dynamicCast(staticCast((pThis), Dynamic), classInfo(RsSession)))
|
||||
#endif //__nvoc_rs_server_h_disabled
|
||||
|
||||
|
||||
NV_STATUS __nvoc_objCreateDynamic_RsSession(RsSession**, Dynamic*, NvU32, va_list);
|
||||
|
||||
NV_STATUS __nvoc_objCreate_RsSession(RsSession**, Dynamic*, NvU32);
|
||||
#define __objCreate_RsSession(ppNewObj, pParent, createFlags) \
|
||||
__nvoc_objCreate_RsSession((ppNewObj), staticCast((pParent), Dynamic), (createFlags))
|
||||
|
||||
#define sessionRemoveDependant(pSession, pResourceRef) sessionRemoveDependant_DISPATCH(pSession, pResourceRef)
|
||||
#define sessionRemoveDependency(pSession, pResourceRef) sessionRemoveDependency_DISPATCH(pSession, pResourceRef)
|
||||
void sessionRemoveDependant_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
|
||||
|
||||
// Wrapper macros
|
||||
#define sessionRemoveDependant_FNPTR(pSession) pSession->__sessionRemoveDependant__
|
||||
#define sessionRemoveDependant(pSession, pResourceRef) sessionRemoveDependant_DISPATCH(pSession, pResourceRef)
|
||||
#define sessionRemoveDependency_FNPTR(pSession) pSession->__sessionRemoveDependency__
|
||||
#define sessionRemoveDependency(pSession, pResourceRef) sessionRemoveDependency_DISPATCH(pSession, pResourceRef)
|
||||
|
||||
// Dispatch functions
|
||||
static inline void sessionRemoveDependant_DISPATCH(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
|
||||
pSession->__sessionRemoveDependant__(pSession, pResourceRef);
|
||||
}
|
||||
|
||||
void sessionRemoveDependency_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
|
||||
|
||||
static inline void sessionRemoveDependency_DISPATCH(struct RsSession *pSession, struct RsResourceRef *pResourceRef) {
|
||||
pSession->__sessionRemoveDependency__(pSession, pResourceRef);
|
||||
}
|
||||
|
||||
void sessionRemoveDependant_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
|
||||
|
||||
void sessionRemoveDependency_IMPL(struct RsSession *pSession, struct RsResourceRef *pResourceRef);
|
||||
|
||||
NV_STATUS sessionConstruct_IMPL(struct RsSession *arg_pSession);
|
||||
|
||||
#define __nvoc_sessionConstruct(arg_pSession) sessionConstruct_IMPL(arg_pSession)
|
||||
@@ -282,7 +332,7 @@ struct RsServer
|
||||
NvBool bConstructed; ///< Determines whether the server is ready to be used
|
||||
PORT_MEM_ALLOCATOR *pAllocator; ///< Allocator to use for all objects allocated by the server
|
||||
|
||||
PORT_RWLOCK *pClientListLock; ///< Lock that needs to be taken when accessing the client list
|
||||
PORT_SPINLOCK *pClientListLock; ///< Lock that needs to be taken when accessing the client list
|
||||
|
||||
PORT_SPINLOCK *pShareMapLock; ///< Lock that needs to be taken when accessing the shared resource map
|
||||
RsSharedMap shareMap; ///< Map of shared resources
|
||||
@@ -314,6 +364,11 @@ struct RsServer
|
||||
*/
|
||||
NvBool bRsAccessEnabled;
|
||||
|
||||
/**
|
||||
* Set to thread ID of the thread that locked all clients.
|
||||
*/
|
||||
NvU64 allClientLockOwnerTid;
|
||||
|
||||
/**
|
||||
* Mask of interfaces (RS_API_*) that will use a read-only top lock by default
|
||||
*/
|
||||
@@ -334,6 +389,16 @@ struct RsServer
|
||||
RsDisabledClientList disabledClientList;
|
||||
struct RsClient *pNextDisabledClient;
|
||||
PORT_SPINLOCK *pDisabledClientListLock;
|
||||
|
||||
/**
|
||||
* List of client entries locked by serverLockAllClients
|
||||
* This list is required for locking all clients in order to avoid races with
|
||||
* other paths creating/destroying paths in parallel WITHOUT holding the API lock.
|
||||
* Ideally, there shouldn't be any other such paths but the RTD3/PM path does do
|
||||
* this. CORERM-6052 tracks investigating that and potentially fixing the locking
|
||||
* there.
|
||||
*/
|
||||
RsLockedClientList lockedClientList;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -745,6 +810,23 @@ extern NV_STATUS serverResLock_Prologue(RsServer *pServer, LOCK_ACCESS_TYPE acce
|
||||
*/
|
||||
extern void serverResLock_Epilogue(RsServer *pServer, LOCK_ACCESS_TYPE access, RS_LOCK_INFO *pLockInfo, NvU32 *pReleaseFlags);
|
||||
|
||||
/**
|
||||
* Acquire the client list lock. The caller is responsible for
|
||||
* ensuring that lock ordering is not violated (otherwise there can be
|
||||
* deadlock): the client list lock must always be released without acquiring any
|
||||
* subsequent locks.
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
*/
|
||||
void serverAcquireClientListLock(RsServer *pServer);
|
||||
|
||||
/**
|
||||
* Release the client list lock.
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
*/
|
||||
void serverReleaseClientListLock(RsServer *pServer);
|
||||
|
||||
/**
|
||||
* WAR for additional tasks that must be performed after resource-level locks are released. User-implemented.
|
||||
* @param[inout] status Allocation status
|
||||
@@ -949,6 +1031,15 @@ extern NV_STATUS serverControlLookupLockFlags(RsServer *pServer,
|
||||
RS_CONTROL_COOKIE *pCookie,
|
||||
LOCK_ACCESS_TYPE *pAccess);
|
||||
|
||||
/**
|
||||
* Lookup client locking flags for a control call
|
||||
*
|
||||
* @param[in] pCookie Control call cookie
|
||||
* @param[out] pClientLockType Client lock type
|
||||
*/
|
||||
extern NV_STATUS serverControlLookupClientLockFlags(RS_CONTROL_COOKIE *pCookie,
|
||||
enum CLIENT_LOCK_TYPE *pClientLockType);
|
||||
|
||||
/**
|
||||
*
|
||||
* Lookup locking flags for a map call
|
||||
@@ -1168,18 +1259,61 @@ void serverInterUnmap_Epilogue(RsServer *pServer, RS_INTER_UNMAP_PARAMS *pUnmapP
|
||||
* @param[in] pServer This server instance
|
||||
* @param[in] hClient The client to acquire
|
||||
* @param[in] lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
|
||||
* @param[out] ppClient Pointer to the RsClient
|
||||
* @param[out] ppClientEntry Pointer to the CLIENT_ENTRY
|
||||
*/
|
||||
NV_STATUS serverAcquireClient(RsServer *pServer, NvHandle hClient, LOCK_ACCESS_TYPE lockAccess, struct RsClient **ppClient);
|
||||
NV_STATUS serverAcquireClient(RsServer *pServer, NvHandle hClient, LOCK_ACCESS_TYPE lockAccess, CLIENT_ENTRY **ppClientEntry);
|
||||
|
||||
/**
|
||||
* Release a client pointer
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
* @param[in] lockAccess LOCK_ACCESS_READ or LOCK_ACCESS_WRITE
|
||||
* @param[in] pClient Pointer to the RsClient
|
||||
* @param[in] pClientEntry Pointer to the CLIENT_ENTRY
|
||||
*/
|
||||
NV_STATUS serverReleaseClient(RsServer *pServer, LOCK_ACCESS_TYPE lockAccess, struct RsClient *pClient);
|
||||
void serverReleaseClient(RsServer *pServer, LOCK_ACCESS_TYPE lockAccess, CLIENT_ENTRY *pClientEntry);
|
||||
|
||||
/**
|
||||
* Test is a client handle is currently locked for LOCK_ACCESS_WRITE or not.
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
* @param[in] hClient The client to acquire
|
||||
*/
|
||||
NvBool serverIsClientLocked(RsServer *pServer, NvHandle hClient);
|
||||
|
||||
/**
|
||||
* Test if a client handle is internal or not
|
||||
*
|
||||
* @param[in] hClient The client handle to test
|
||||
*/
|
||||
NvBool serverIsClientInternal(RsServer *pServer, NvHandle hClient);
|
||||
|
||||
/**
|
||||
* Lock all clients currently in use. While this function will lock the client handles
|
||||
* in the correct order, the caller is responsible for ensuring that lock ordering
|
||||
* is not violated (otherwise there can be a deadlock) with respect to other types
|
||||
* of locks. NOTE that this CANNOT be called when already holding one or more client
|
||||
* locks!
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
*/
|
||||
NV_STATUS serverLockAllClients(RsServer *pServer);
|
||||
|
||||
/**
|
||||
* Release locks on all clients.
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
*/
|
||||
NV_STATUS serverUnlockAllClients(RsServer *pServer);
|
||||
|
||||
/**
|
||||
* Check if we locked all clients
|
||||
*
|
||||
* @param[in] pServer This server instance
|
||||
*/
|
||||
static NV_INLINE NvBool serverAllClientsLockIsOwner(RsServer *pServer)
|
||||
{
|
||||
return (pServer->allClientLockOwnerTid == portThreadGetCurrentThreadId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a client pointer from a client handle without taking any locks.
|
||||
|
||||
Reference in New Issue
Block a user