| 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
|
|
|