Index: arch/arm/mach-tegra/nv/include/nvreftrack.h |
diff --git a/arch/arm/mach-tegra/nv/include/nvreftrack.h b/arch/arm/mach-tegra/nv/include/nvreftrack.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0b15d633b98cfa29d1d67252bbd1e6ffc1d53580 |
--- /dev/null |
+++ b/arch/arm/mach-tegra/nv/include/nvreftrack.h |
@@ -0,0 +1,474 @@ |
+/* |
+ * Copyright (c) 2009 NVIDIA Corporation. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are met: |
+ * |
+ * Redistributions of source code must retain the above copyright notice, |
+ * this list of conditions and the following disclaimer. |
+ * |
+ * Redistributions in binary form must reproduce the above copyright notice, |
+ * this list of conditions and the following disclaimer in the documentation |
+ * and/or other materials provided with the distribution. |
+ * |
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors |
+ * may be used to endorse or promote products derived from this software |
+ * without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+ * POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ */ |
+ |
+/** |
+ * \file nvreftrack.h |
+ * \brief NVIDIA kernel object reference tracking utility |
+ * |
+ * \mainpage |
+ * |
+ * NvRefTrack implements a database of client to object |
+ * references. The sole purpose of the utility is to provide a |
+ * mechanism for freeing up kernel mode driver objects on abnormal |
+ * client termination. |
+ * |
+ * This utility is intended to be used together with the NV IDL |
+ * automatic call dispatcher generation. 'refadd' and 'refdel' |
+ * modifiers for function parameters instruct the IDL generation to |
+ * instrument the dispatcher functions with appropriate calls to |
+ * NvRtStoreObjRef() and NvRtFreeObjRef(). |
+ * |
+ * The OS specific kernel driver's responsibility is to create the |
+ * NvRt context and to register and unregister clients (user mode |
+ * processes accessing the driver). Additionally the context and the |
+ * calling client handle need to be passed to the master dispatcher. |
+ */ |
+ |
+#ifndef INCLUDED_NVREFTRACK_H |
+#define INCLUDED_NVREFTRACK_H |
+ |
+#include "nvcommon.h" |
+#include "nverror.h" |
+ |
+#ifndef NVRT_ENABLE_LEAK_PRINT |
+#define NVRT_ENABLE_LEAK_PRINT NV_DEBUG |
+#endif |
+ |
+/*---------------------------------------------------------*/ |
+/** \defgroup objtype Tracked object types |
+ * |
+ * NvRefTrack must be able to identify the object types |
+ * stored in the database. As the IDL generator can not |
+ * produce a list of the types they are statically defined |
+ * here. Note that this list of enumerations is not actually |
+ * a part of the NvRefTrack public interface - it could be |
+ * stored separately. Ideally these enumerations would be |
+ * generated by the IDL dispatcher generator. |
+ * |
+ * The exact syntax of these enumerations is important, as |
+ * the IDL generator will refer to these names when creating |
+ * reference add/del code in the dispatcher. |
+ * |
+ * 1) There must a an enumeration for every package that |
+ * contains objects to be tracked. The enumeration should |
+ * be called NvRtObjType_<package>. |
+ * 2) For every object type tracked in the package (every |
+ * object type that may have refadd and refdel modifiers |
+ * in the idl description) there needs to be an entry in |
+ * the enumeration called NvRtObjType_<package>_<type>. |
+ * 3) The enumerations should start from value 0 and fill |
+ * the number space completely up to |
+ * NvRtObjType_<package>_Num, which will be equal to the |
+ * number of tracked object types in the package. |
+ */ |
+ |
+/** |
+ * Tracked object types for package NvRm |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvRm_NvRmMemHandle = 0, |
+ NvRtObjType_NvRm_Num, |
+ NvRtObjType_NvRm_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvRm; |
+ |
+/** |
+ * Tracked handles for package NvRmGraphics |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvRmGraphics_NvRmChannelHandle = 0, |
+ NvRtObjType_NvRmGraphics_NvRmContextHandle, |
+ NvRtObjType_NvRmGraphics_Num, |
+ NvRtObjType_NvRmGraphics_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvRmGraphics; |
+ |
+/** |
+ * Tracked handles for package NvMM |
+ * |
+ * Tentative handles to track: |
+ * - NvMMManagerHandle, this does not exist - API failure? |
+ * - NvMMIRAMScratchHandle, this does not exist - API failure? |
+ * Can possibly use references to CodecType, a bit dodgy |
+ * - pBlock, why is this not a handle? |
+ * - pClientId, why is this not a handle? |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvMM_NvmmPowerClientHandle = 0, |
+ NvRtObjType_NvMM_NvmmManagerHandle, |
+ NvRtObjType_NvMM_NvmmMgrBlockHandle, |
+ NvRtObjType_NvMM_Num, |
+ NvRtObjType_NvMM_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvMM; |
+ |
+/** |
+ * Tracked handles for package NvECPackage |
+ * |
+ * Tentative handles to track: |
+ * - NvEcHandle |
+ * - NvEcEventRegistrationHandle |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvECPackage_NvEcHandle = 0, |
+ NvRtObjType_NvECPackage_NvEcEventRegistrationHandle, |
+ NvRtObjType_NvECPackage_Num, |
+ NvRtObjType_NvECPackage_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvECPackage; |
+ |
+/** |
+ * Tracked handles for package NvStorManager |
+ * |
+ * Tentative handles to track: |
+ * - NvStorMgrFileHandle |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvStorManager_NvStorMgrFileHandle = 0, |
+ NvRtObjType_NvStorManager_Num, |
+ NvRtObjType_NvStorManager_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvStorManager; |
+ |
+/** |
+ * Tracked handles for package NvDDKAudio |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvDDKAudio_Num = 0, |
+ NvRtObjType_NvDDKAudio_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvDDKAudio; |
+ |
+/** |
+ * Tracked handles for package NvDispMgr |
+ * \ingroup objtype |
+ */ |
+typedef enum |
+{ |
+ NvRtObjType_NvDispMgr_Client = 0, |
+ NvRtObjType_NvDispMgr_Num, |
+ NvRtObjType_NvDispMgr_ForceWord = 0x7FFFFFFF |
+} NvRtObjType_NvDispMgr; |
+ |
+ |
+/*---------------------------------------------------------*/ |
+/** \defgroup os_driver Public interface for os driver */ |
+ |
+#if NVRT_ENABLE_LEAK_PRINT |
+#define NVRT_LEAK(driver, objtype, ptr) \ |
+ NvOsDebugPrintf("[%s] Leaked reference on client exit: (%s) 0x%08x\n", \ |
+ driver, objtype, ptr); |
+#else |
+#define NVRT_LEAK(driver, objtype, ptr) |
+#endif |
+ |
+ |
+typedef struct NvRtRec* NvRtHandle; |
+typedef NvU32 NvRtClientHandle; |
+typedef NvU32 NvRtObjRefHandle; |
+ |
+typedef struct |
+{ |
+ NvRtHandle Rt; |
+ NvRtClientHandle Client; |
+ NvU32 PackageIdx; |
+} NvDispatchCtx; |
+ |
+ |
+#if defined(__cplusplus) |
+extern "C" |
+{ |
+#endif |
+ |
+ /** |
+ * Create a reference tracking database. |
+ * |
+ * The OS driver should create a single database upon driver init for |
+ * all the IDL packages that the driver is responsible for. The |
+ * created handle should be stored in the global driver context. |
+ * |
+ * @param NumPackages Number of IDL packages that the driver is |
+ * responsible for. |
+ * @param NumObjTypesPerPackage A list of the amount of tracked handles |
+ * for each of the IDL packages. The order |
+ * of the list needs to match the package |
+ * indices passed in to the reference |
+ * manipulation functions. The XXX_Num value |
+ * of the object type enumerations can be used |
+ * in constructing the list. |
+ * @param RtOut A newly created reference database handle. |
+ * @return NvSuccess on success. |
+ * |
+ * \ingroup os_driver |
+ */ |
+NvError NvRtCreate( |
+ NvU32 NumPackages, |
+ const NvU32* NumObjTypesPerPackage, |
+ NvRtHandle* RtOut); |
+ |
+/** |
+ * Destroy a reference tracking database. |
+ * |
+ * This frees all resources associated to a reference database and should |
+ * be called on driver deinitialization. Note that this function makes no |
+ * attempt at freeing any outstanding references, the user must make sure |
+ * that references to driver objects have been freed prior to destroying |
+ * the database. |
+ * |
+ * @param Rt The reference database handle. |
+ * |
+ * \ingroup os_driver |
+ */ |
+void NvRtDestroy( |
+ NvRtHandle Rt); |
+ |
+/** |
+ * Register a new client to the reference database. |
+ * |
+ * For all practical purposes, a client refers to a single entity in the |
+ * system that uses the driver via the IDL interface and may terminate |
+ * unexpectedly, without freeing the driver resource references it holds. |
+ * It makes no sense, for example, to register potential kernel-side users |
+ * of the driver into the database as it should be impossible to terminate |
+ * such a client unexpectedly without resulting in a complete system failure. |
+ * Most commonly, but not necessarily, client == usermode process. |
+ * |
+ * The client ID returned by this function in the location pointed to by the |
+ * ClientOut parameter must be stored in a way that it can be passed along |
+ * to the master dispatcher function (in the NvDispatchCtx struct) for all |
+ * calls originating from the client. This may, for example, be the return |
+ * value from a file handle open (XXX_Open) operation passed back as the |
+ * "open context" parameter into XXX_Ioctl calls. |
+ * |
+ * @param Rt The reference database handle. |
+ * @param ClientOut A unique ID for the newly registered client. This |
+ * value never equals 0 on success. |
+ * @return NvSuccess on success. |
+ * |
+ * \ingroup os_driver |
+ */ |
+NvError NvRtRegisterClient( |
+ NvRtHandle Rt, |
+ NvRtClientHandle* ClientOut); |
+ |
+/** |
+ * Add a reference to the already registered client. |
+ * |
+ * Multiple references to a client may be needed when a single client |
+ * can be accessed from multiple entities (processes). |
+ * |
+ * @param Rt The reference database handle. |
+ * @param Client The unique ID of the client. |
+ * @return NvSuccess on success. |
+ * |
+ * \ingroup os_driver |
+ */ |
+NvError NvRtAddClientRef( |
+ NvRtHandle Rt, |
+ NvRtClientHandle Client); |
+ |
+/** |
+ * Unregister a client from the reference database. |
+ * |
+ * As client handles are refcounted the caller and nvreftrack must |
+ * conspire to know when to process possibly leaked resources. The library |
+ * signals the caller about the correct time to free leaked resources by |
+ * returning NV_TRUE (standing for: yes, please do cleanup now). |
+ * |
+ * Upon a return value of NV_TRUE, it is the responsibility of the OS driver to |
+ * iterate over the possibly remaining references and implement the tearing |
+ * down of those references appropriately. This is accomplished by calling |
+ * NvRtFreeObjRef() until no further object pointers are returned by it for |
+ * the given (client, package, objtype). After doing the cleanup, the caller |
+ * should call NvRtUnregisterClient() once more to actually free the client |
+ * handle. |
+ * |
+ * @param Rt The reference database handle. |
+ * @param Client The unique ID of the Client. |
+ * @return NV_TRUE if the caller should clean up leaked objects |
+ * and call NvRtUnregisterClient() again, NV_FALSE |
+ * otherwise. |
+ * |
+ * \ingroup os_driver |
+ */ |
+NvBool NvRtUnregisterClient( |
+ NvRtHandle Rt, |
+ NvRtClientHandle Client); |
+ |
+/** |
+ * Set/Get opaque user data associated to a client |
+ * |
+ * \ingroup os_driver |
+ */ |
+ |
+void NvRtSetClientUserData( |
+ NvRtHandle Rt, |
+ NvRtClientHandle Client, |
+ void* UserData); |
+void* NvRtGetClientUserData( |
+ NvRtHandle Rt, |
+ NvRtClientHandle Client); |
+ |
+/*---------------------------------------------------------*/ |
+/** \defgroup idl_iface Interface used by generated IDL code |
+ * |
+ * These functions are mainly intended to be called from the |
+ * generated IDL dispatcher code. It is of course possible |
+ * to use this interface directly from handwritten driver |
+ * code as well. |
+ * |
+ * An exception to this rule is the NvRtFreeObjRef(), which |
+ * the os driver uses to iterate over remaining object |
+ * references of a client to be unregistered. |
+ **/ |
+ |
+/** |
+ * Allocate an object reference handle. |
+ * |
+ * Adding an object reference is broken into two parts, |
+ * NvRtAllocObjRef() and NvRtStoreObjRef(). This is so that all |
+ * resource allocations for the object reference can be done in |
+ * advance to eliminate the need to be able to rollback a driver |
+ * object reference add in the generated IDL code. |
+ * |
+ * The caller must call one of NvRtDiscardObjRef() or |
+ * NvRtStoreObjRef() for a NvRtObjRefHandle returned by this |
+ * function. Failure to do so will unrecoverably leak the object |
+ * reference handle. |
+ * |
+ * @param Ctx The dispatcher context, filled by the OS driver |
+ * @param ObjRef A new handle to an object reference |
+ * |
+ * \ingroup idl_iface |
+ */ |
+NvError NvRtAllocObjRef( |
+ const NvDispatchCtx* Ctx, |
+ NvRtObjRefHandle* ObjRef); |
+ |
+ |
+/** |
+ * Discard an object reference handle. |
+ * |
+ * Frees a previously allocated object reference handle without storing |
+ * anything in the database. |
+ * |
+ * @param Ctx The dispatcher context, filled by the OS driver |
+ * @param ObjRef An object reference handle |
+ * |
+ * \ingroup idl_iface |
+ */ |
+void NvRtDiscardObjRef( |
+ const NvDispatchCtx* Ctx, |
+ NvRtObjRefHandle ObjRef); |
+ |
+/** |
+ * Store an object reference to the database. |
+ * |
+ * This function adds an object reference to the database. An object |
+ * is identified via the the attributes (Ctx.PackageIdx, ObjType, |
+ * ObjPtr). The reference is created from Ctx.Client. It is |
+ * completely valid to have multiple references to a given object from |
+ * the same client, or from multiple clients. |
+ * |
+ * After calling this function the NvRtObjRefHandle acquired by a call |
+ * to NvRtAllocObjRef becomes invalid and may no longer be used for |
+ * any other purpose. |
+ * |
+ * It is the caller's responsibility to make sure that the object type |
+ * is within range of the allocated object types for the package. In |
+ * practice if the NvRtObjType enumeration is well defined and the |
+ * NvRt database correctly initialized with the maximum amount of |
+ * objects for the package this should not be an issue. |
+ * |
+ * @param Ctx The dispatcher context, filled by the OS driver |
+ * @param ObjRef An object reference handle |
+ * @param ObjType The NvRtObjType of the object to be stored |
+ * @param ObjPtr A opaque pointer uniquely identifying the object |
+ * that this reference points to. NULL is not allowed. |
+ * |
+ * \ingroup idl_iface |
+ */ |
+void NvRtStoreObjRef( |
+ const NvDispatchCtx* Ctx, |
+ NvRtObjRefHandle ObjRef, |
+ NvU32 ObjType, |
+ void* ObjPtr); |
+ |
+/** |
+ * Find and free an object reference. |
+ * |
+ * The NvRt API provides no way of enumerating or querying the object |
+ * database without simultaneously freeing the object reference as |
+ * well. This is intentional - the utility is built for a very |
+ * specific purpose and optimized to do that in a fast and robust way. |
+ * |
+ * This function is used to free a previously stored object |
+ * reference. Upon locating an object reference from Ctx.Client to |
+ * (Ctx.PackageIdx, ObjType, ObjPtr) it immediately frees the object |
+ * reference from the database. |
+ * |
+ * Passing in NULL as ObjPtr means 'match any', the function will locate and |
+ * free the first object reference from Ctx.Client to (Ctx.PackageIdx, |
+ * ObjType). This can be used to free all outstanding references from a client, |
+ * iterate over all packages and object types that the client may have used, |
+ * call NvRtFreeObjRef() with a NULL ObjPtr parameter and free the returned |
+ * ObjPtr reference until no more references are returned. |
+ * |
+ * In any case, if an object reference was found and freed the ObjPtr |
+ * of the reference is returned. A NULL return value means that no reference |
+ * matching the criteria was found. Note that if the generated IDL code works |
+ * correctly this function should never get called with a ObjPtr parameter that |
+ * can't be found from the database. |
+ * |
+ * @param Ctx The dispatcher context, filled by the OS driver |
+ * @param ObjType The NvRtObjType of the object to be found |
+ * @param ObjPtr A opaque pointer of the object to be found |
+ * @return The ObjPtr of the reference free'd, NULL if not found |
+ * |
+ * \ingroup idl_iface |
+ */ |
+void* NvRtFreeObjRef( |
+ const NvDispatchCtx* Ctx, |
+ NvU32 ObjType, |
+ void* ObjPtr); |
+ |
+#if defined(__cplusplus) |
+} |
+#endif |
+ |
+#endif |