545.29.06

This commit is contained in:
Maneet Singh 2023-11-21 13:38:23 -08:00
parent be3cd9abcb
commit 4c29105335
No known key found for this signature in database
28 changed files with 2105 additions and 531 deletions

View File

@ -2,6 +2,12 @@
## Release 545 Entries
### [545.29.06] 2023-11-22
#### Fixed
- The brightness control of NVIDIA seems to be broken, [#573](https://github.com/NVIDIA/open-gpu-kernel-modules/issues/573)
### [545.29.02] 2023-10-31
### [545.23.06] 2023-10-17
@ -16,6 +22,8 @@
## Release 535 Entries
### [535.129.03] 2023-10-31
### [535.113.01] 2023-09-21
#### Fixed
@ -64,10 +72,14 @@
## Release 525 Entries
### [525.147.05] 2023-10-31
#### Fixed
- Fix nvidia_p2p_get_pages(): Fix double-free in register-callback error path, [#557](https://github.com/NVIDIA/open-gpu-kernel-modules/pull/557) by @BrendanCunningham
### [525.125.06] 2023-06-26
### [525.116.04] 2023-05-09
### [525.116.03] 2023-04-25

View File

@ -1,7 +1,7 @@
# NVIDIA Linux Open GPU Kernel Module Source
This is the source release of the NVIDIA Linux open GPU kernel modules,
version 545.29.02.
version 545.29.06.
## How to Build
@ -17,7 +17,7 @@ as root:
Note that the kernel modules built here must be used with GSP
firmware and user-space NVIDIA GPU driver components from a corresponding
545.29.02 driver release. This can be achieved by installing
545.29.06 driver release. This can be achieved by installing
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
option. E.g.,
@ -188,7 +188,7 @@ encountered specific to them.
For details on feature support and limitations, see the NVIDIA GPU driver
end user README here:
https://us.download.nvidia.com/XFree86/Linux-x86_64/545.29.02/README/kernel_open.html
https://us.download.nvidia.com/XFree86/Linux-x86_64/545.29.06/README/kernel_open.html
In the below table, if three IDs are listed, the first is the PCI Device
ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI
@ -750,8 +750,8 @@ Subsystem Device ID.
| NVIDIA H100 PCIe | 2331 10DE 1626 |
| NVIDIA H100 | 2339 10DE 17FC |
| NVIDIA H800 NVL | 233A 10DE 183A |
| GH200 120GB | 2342 10DE 16EB |
| GH200 480GB | 2342 10DE 1809 |
| NVIDIA GH200 120GB | 2342 10DE 16EB |
| NVIDIA GH200 480GB | 2342 10DE 1809 |
| NVIDIA GeForce RTX 3060 Ti | 2414 |
| NVIDIA GeForce RTX 3080 Ti Laptop GPU | 2420 |
| NVIDIA RTX A5500 Laptop GPU | 2438 |

View File

@ -72,7 +72,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc
EXTRA_CFLAGS += -I$(src)
EXTRA_CFLAGS += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args
EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"545.29.02\"
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"545.29.06\"
ifneq ($(SYSSRCHOST1X),)
EXTRA_CFLAGS += -I$(SYSSRCHOST1X)

View File

@ -218,9 +218,23 @@ static inline int nvkms_read_trylock_pm_lock(void)
static inline void nvkms_read_lock_pm_lock(void)
{
while (!down_read_trylock(&nvkms_pm_lock)) {
try_to_freeze();
cond_resched();
if ((current->flags & PF_NOFREEZE)) {
/*
* Non-freezable tasks (i.e. kthreads in this case) don't have to worry
* about being frozen during system suspend, but do need to block so
* that the CPU can go idle during s2idle. Do a normal uninterruptible
* blocking wait for the PM lock.
*/
down_read(&nvkms_pm_lock);
} else {
/*
* For freezable tasks, make sure we give the kernel an opportunity to
* freeze if taking the PM lock fails.
*/
while (!down_read_trylock(&nvkms_pm_lock)) {
try_to_freeze();
cond_resched();
}
}
}

View File

@ -43,18 +43,18 @@
#endif
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r545/r545_96-120"
#define NV_BUILD_CHANGELIST_NUM (33457372)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r545/r545_96-124"
#define NV_BUILD_CHANGELIST_NUM (33538619)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "rel/gpu_drv/r545/r545_96-120"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (33457372)
#define NV_BUILD_NAME "rel/gpu_drv/r545/r545_96-124"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (33538619)
#else /* Windows builds */
#define NV_BUILD_BRANCH_VERSION "r545_96-2"
#define NV_BUILD_CHANGELIST_NUM (33457372)
#define NV_BUILD_BRANCH_VERSION "r545_96-8"
#define NV_BUILD_CHANGELIST_NUM (33517029)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "546.01"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (33457372)
#define NV_BUILD_NAME "546.17"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (33517029)
#define NV_BUILD_BRANCH_BASE_VERSION R545
#endif
// End buildmeister python edited section

View File

@ -4,7 +4,7 @@
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
#define NV_VERSION_STRING "545.29.02"
#define NV_VERSION_STRING "545.29.06"
#else

View File

@ -403,6 +403,45 @@ typedef struct NV2080_CTRL_KGR_GET_CTX_BUFFER_PTES_PARAMS {
NvBool bNoMorePages;
} NV2080_CTRL_KGR_GET_CTX_BUFFER_PTES_PARAMS;
/*!
* NV2080_CTRL_INTERNAL_MEMDESC_INFO
*
* A generic container structure representing a memory region to be used as a
* component of other control call parameters.
*
*/
typedef struct NV2080_CTRL_INTERNAL_MEMDESC_INFO {
NV_DECLARE_ALIGNED(NvU64 base, 8);
NV_DECLARE_ALIGNED(NvU64 size, 8);
NV_DECLARE_ALIGNED(NvU64 alignment, 8);
NvU32 addressSpace;
NvU32 cpuCacheAttrib;
} NV2080_CTRL_INTERNAL_MEMDESC_INFO;
/*
* NV2080_CTRL_CMD_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY
*
* Set memory for use by the video event buffer
*
* memDescInfo
* Information to set up memory descriptor on GSP
*
* engDesc
* Video engdesc to find correct engine
*
* bEngineFound
* Bool for whether or not the engine is actually assigned to a video object
*/
#define NV2080_CTRL_CMD_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY (0x20800a29) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS_MESSAGE_ID" */
#define NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS_MESSAGE_ID (0x29U)
typedef struct NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS {
NV_DECLARE_ALIGNED(NV2080_CTRL_INTERNAL_MEMDESC_INFO memDescInfo, 8);
NvU32 engDesc;
NvBool bEngineFound;
} NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS;
/*!
* @ref NV0080_CTRL_CMD_GR_GET_INFO
* @ref NV0080_CTRL_CMD_GR_GET_INFO_V2
@ -1071,22 +1110,6 @@ typedef struct NV2080_CTRL_INTERNAL_STATIC_MIGMGR_GET_PARTITIONABLE_ENGINES_PARA
NV_DECLARE_ALIGNED(NvU64 engineMask, 8);
} NV2080_CTRL_INTERNAL_STATIC_MIGMGR_GET_PARTITIONABLE_ENGINES_PARAMS;
/*!
* NV2080_CTRL_INTERNAL_MEMDESC_INFO
*
* A generic container structure representing a memory region to be used as a
* component of other control call parameters.
*
*/
typedef struct NV2080_CTRL_INTERNAL_MEMDESC_INFO {
NV_DECLARE_ALIGNED(NvU64 base, 8);
NV_DECLARE_ALIGNED(NvU64 size, 8);
NV_DECLARE_ALIGNED(NvU64 alignment, 8);
NvU32 addressSpace;
NvU32 cpuCacheAttrib;
} NV2080_CTRL_INTERNAL_MEMDESC_INFO;
#define NV2080_CTRL_INTERNAL_FIFO_MAX_RUNLIST_BUFFERS 2
#define NV2080_CTRL_INTERNAL_FIFO_MAX_RUNLIST_ID 64
/*!

View File

@ -67,6 +67,7 @@ static NvBool DpySetBacklightBrightness(NVDpyEvoRec *pDpyEvo, NvS64 brightness)
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = nvDpyEvoGetConnectorId(pDpyEvo);
params.brightness = brightness;
params.brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
ret = nvRmApiControl(
nvEvoGlobal.clientHandle,
@ -97,6 +98,7 @@ static NvBool DpyGetBacklightBrightness(const NVDpyEvoRec *pDpyEvo,
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = nvDpyEvoGetConnectorId(pDpyEvo);
params.brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
ret = nvRmApiControl(
nvEvoGlobal.clientHandle,

View File

@ -5467,6 +5467,7 @@ void nvRmRegisterBacklight(NVDispEvoRec *pDispEvo)
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = displayId;
params.brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
status = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,

View File

@ -6451,6 +6451,7 @@ NvBool nvKmsGetBacklight(NvU32 display_id, void *drv_priv, NvU32 *brightness)
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = display_id;
params.brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
status = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
@ -6474,6 +6475,7 @@ NvBool nvKmsSetBacklight(NvU32 display_id, void *drv_priv, NvU32 brightness)
params.subDeviceInstance = pDispEvo->displayOwner;
params.displayId = display_id;
params.brightness = brightness;
params.brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100;
status = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,

View File

@ -389,12 +389,6 @@ void __nvoc_init_dataField_OBJGPU(OBJGPU *pThis) {
}
pThis->bIsGspOwnedFaultBuffersEnabled = ((NvBool)(0 != 0));
// Hal field -- bVideoTraceLogSupported
if (( ((chipHal_HalVarIdx >> 5) == 1UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x11f0ffe0UL) )) /* ChipHal: TU102 | TU104 | TU106 | TU116 | TU117 | GA100 | GA102 | GA103 | GA104 | GA106 | GA107 | AD102 | AD103 | AD104 | AD106 | AD107 | GH100 */
{
pThis->bVideoTraceLogSupported = ((NvBool)(0 == 0));
}
}
NV_STATUS __nvoc_ctor_Object(Object* );

View File

@ -99,6 +99,8 @@ typedef struct GPUATTACHARG GPUATTACHARG;
#include "kernel/gpu/gr/fecs_event_list.h"
#include "class/cl90cdfecs.h"
#include "gpuvideo/videoeventlist.h"
#include "gpu/gpu_fabric_probe.h"
#include "nv_arch.h"
@ -1199,6 +1201,8 @@ struct OBJGPU {
EventBufferMap vgpuFecsTraceStagingBindings;
FecsEventBufferBindMultiMap fecsEventBufferBindingsUid;
TMR_EVENT *pFecsTimerEvent;
VideoEventBufferBindMultiMap videoEventBufferBindingsUid;
TMR_EVENT *pVideoTimerEvent;
struct OBJVASPACE *pFabricVAS;
NvBool bPipelinedPteMemEnabled;
NvBool bIsBarPteInSysmemSupported;
@ -1231,7 +1235,6 @@ struct OBJGPU {
NvBool bGpuNvEncAv1Supported;
_GPU_SLI_PEER peer[2];
NvBool bIsGspOwnedFaultBuffersEnabled;
NvBool bVideoTraceLogSupported;
_GPU_GC6_STATE gc6State;
};
@ -4073,17 +4076,6 @@ static inline NV_STATUS gpuGetConstructedFalcon(struct OBJGPU *pGpu, NvU32 arg0,
#define gpuGetConstructedFalcon(pGpu, arg0, arg1) gpuGetConstructedFalcon_IMPL(pGpu, arg0, arg1)
#endif //__nvoc_gpu_h_disabled
NvBool gpuIsVideoTraceLogSupported_IMPL(struct OBJGPU *pGpu);
#ifdef __nvoc_gpu_h_disabled
static inline NvBool gpuIsVideoTraceLogSupported(struct OBJGPU *pGpu) {
NV_ASSERT_FAILED_PRECOMP("OBJGPU was disabled!");
return NV_FALSE;
}
#else //__nvoc_gpu_h_disabled
#define gpuIsVideoTraceLogSupported(pGpu) gpuIsVideoTraceLogSupported_IMPL(pGpu)
#endif //__nvoc_gpu_h_disabled
NV_STATUS gpuGetSparseTextureComputeMode_IMPL(struct OBJGPU *pGpu, NvU32 *arg0, NvU32 *arg1, NvU32 *arg2);
#ifdef __nvoc_gpu_h_disabled

View File

@ -15,10 +15,10 @@ extern const struct NVOC_CLASS_DEF __nvoc_class_def_KernelVideoEngine;
extern const struct NVOC_CLASS_DEF __nvoc_class_def_Object;
void __nvoc_init_KernelVideoEngine(KernelVideoEngine*);
void __nvoc_init_funcTable_KernelVideoEngine(KernelVideoEngine*);
NV_STATUS __nvoc_ctor_KernelVideoEngine(KernelVideoEngine*, struct OBJGPU * arg_pGpu, ENGDESCRIPTOR arg_physEngDesc);
void __nvoc_init_dataField_KernelVideoEngine(KernelVideoEngine*);
void __nvoc_init_KernelVideoEngine(KernelVideoEngine*, RmHalspecOwner* );
void __nvoc_init_funcTable_KernelVideoEngine(KernelVideoEngine*, RmHalspecOwner* );
NV_STATUS __nvoc_ctor_KernelVideoEngine(KernelVideoEngine*, RmHalspecOwner* , struct OBJGPU * arg_pGpu, ENGDESCRIPTOR arg_physEngDesc);
void __nvoc_init_dataField_KernelVideoEngine(KernelVideoEngine*, RmHalspecOwner* );
void __nvoc_dtor_KernelVideoEngine(KernelVideoEngine*);
extern const struct NVOC_EXPORT_INFO __nvoc_export_info_KernelVideoEngine;
@ -69,16 +69,21 @@ void __nvoc_dtor_KernelVideoEngine(KernelVideoEngine *pThis) {
PORT_UNREFERENCED_VARIABLE(pThis);
}
void __nvoc_init_dataField_KernelVideoEngine(KernelVideoEngine *pThis) {
void __nvoc_init_dataField_KernelVideoEngine(KernelVideoEngine *pThis, RmHalspecOwner *pRmhalspecowner) {
RmVariantHal *rmVariantHal = &pRmhalspecowner->rmVariantHal;
const unsigned long rmVariantHal_HalVarIdx = (unsigned long)rmVariantHal->__nvoc_HalVarIdx;
PORT_UNREFERENCED_VARIABLE(pThis);
PORT_UNREFERENCED_VARIABLE(pRmhalspecowner);
PORT_UNREFERENCED_VARIABLE(rmVariantHal);
PORT_UNREFERENCED_VARIABLE(rmVariantHal_HalVarIdx);
}
NV_STATUS __nvoc_ctor_Object(Object* );
NV_STATUS __nvoc_ctor_KernelVideoEngine(KernelVideoEngine *pThis, struct OBJGPU * arg_pGpu, ENGDESCRIPTOR arg_physEngDesc) {
NV_STATUS __nvoc_ctor_KernelVideoEngine(KernelVideoEngine *pThis, RmHalspecOwner *pRmhalspecowner, struct OBJGPU * arg_pGpu, ENGDESCRIPTOR arg_physEngDesc) {
NV_STATUS status = NV_OK;
status = __nvoc_ctor_Object(&pThis->__nvoc_base_Object);
if (status != NV_OK) goto __nvoc_ctor_KernelVideoEngine_fail_Object;
__nvoc_init_dataField_KernelVideoEngine(pThis);
__nvoc_init_dataField_KernelVideoEngine(pThis, pRmhalspecowner);
status = __nvoc_kvidengConstruct(pThis, arg_pGpu, arg_physEngDesc);
if (status != NV_OK) goto __nvoc_ctor_KernelVideoEngine_fail__init;
@ -92,26 +97,32 @@ __nvoc_ctor_KernelVideoEngine_exit:
return status;
}
static void __nvoc_init_funcTable_KernelVideoEngine_1(KernelVideoEngine *pThis) {
static void __nvoc_init_funcTable_KernelVideoEngine_1(KernelVideoEngine *pThis, RmHalspecOwner *pRmhalspecowner) {
RmVariantHal *rmVariantHal = &pRmhalspecowner->rmVariantHal;
const unsigned long rmVariantHal_HalVarIdx = (unsigned long)rmVariantHal->__nvoc_HalVarIdx;
PORT_UNREFERENCED_VARIABLE(pThis);
PORT_UNREFERENCED_VARIABLE(pRmhalspecowner);
PORT_UNREFERENCED_VARIABLE(rmVariantHal);
PORT_UNREFERENCED_VARIABLE(rmVariantHal_HalVarIdx);
}
void __nvoc_init_funcTable_KernelVideoEngine(KernelVideoEngine *pThis) {
__nvoc_init_funcTable_KernelVideoEngine_1(pThis);
void __nvoc_init_funcTable_KernelVideoEngine(KernelVideoEngine *pThis, RmHalspecOwner *pRmhalspecowner) {
__nvoc_init_funcTable_KernelVideoEngine_1(pThis, pRmhalspecowner);
}
void __nvoc_init_Object(Object*);
void __nvoc_init_KernelVideoEngine(KernelVideoEngine *pThis) {
void __nvoc_init_KernelVideoEngine(KernelVideoEngine *pThis, RmHalspecOwner *pRmhalspecowner) {
pThis->__nvoc_pbase_KernelVideoEngine = pThis;
pThis->__nvoc_pbase_Object = &pThis->__nvoc_base_Object;
__nvoc_init_Object(&pThis->__nvoc_base_Object);
__nvoc_init_funcTable_KernelVideoEngine(pThis);
__nvoc_init_funcTable_KernelVideoEngine(pThis, pRmhalspecowner);
}
NV_STATUS __nvoc_objCreate_KernelVideoEngine(KernelVideoEngine **ppThis, Dynamic *pParent, NvU32 createFlags, struct OBJGPU * arg_pGpu, ENGDESCRIPTOR arg_physEngDesc) {
NV_STATUS status;
Object *pParentObj;
KernelVideoEngine *pThis;
RmHalspecOwner *pRmhalspecowner;
status = __nvoc_handleObjCreateMemAlloc(createFlags, sizeof(KernelVideoEngine), (void**)&pThis, (void**)ppThis);
if (status != NV_OK)
@ -133,8 +144,12 @@ NV_STATUS __nvoc_objCreate_KernelVideoEngine(KernelVideoEngine **ppThis, Dynamic
pThis->__nvoc_base_Object.pParent = NULL;
}
__nvoc_init_KernelVideoEngine(pThis);
status = __nvoc_ctor_KernelVideoEngine(pThis, arg_pGpu, arg_physEngDesc);
if ((pRmhalspecowner = dynamicCast(pParent, RmHalspecOwner)) == NULL)
pRmhalspecowner = objFindAncestorOfType(RmHalspecOwner, pParent);
NV_ASSERT_OR_RETURN(pRmhalspecowner != NULL, NV_ERR_INVALID_ARGUMENT);
__nvoc_init_KernelVideoEngine(pThis, pRmhalspecowner);
status = __nvoc_ctor_KernelVideoEngine(pThis, pRmhalspecowner, arg_pGpu, arg_physEngDesc);
if (status != NV_OK) goto __nvoc_objCreate_KernelVideoEngine_cleanup;
*ppThis = pThis;

View File

@ -36,6 +36,8 @@ extern "C" {
#include "kernel/core/core.h"
#include "kernel/gpu/eng_desc.h"
#include "kernel/gpu/gpu.h"
#include "kernel/gpu/gpu_halspec.h"
#include "kernel/mem_mgr/mem.h"
#include "kernel/gpuvideo/video_event.h"
@ -115,10 +117,14 @@ NV_STATUS __nvoc_objCreate_KernelVideoEngine(KernelVideoEngine**, Dynamic*, NvU3
#define __objCreate_KernelVideoEngine(ppNewObj, pParent, createFlags, arg_pGpu, arg_physEngDesc) \
__nvoc_objCreate_KernelVideoEngine((ppNewObj), staticCast((pParent), Dynamic), (createFlags), arg_pGpu, arg_physEngDesc)
NV_STATUS kvidengConstruct_IMPL(struct KernelVideoEngine *arg_pKernelVideoEngine, struct OBJGPU *arg_pGpu, ENGDESCRIPTOR arg_physEngDesc);
NvBool kvidengIsVideoTraceLogSupported_IMPL(struct OBJGPU *pGpu);
#define kvidengIsVideoTraceLogSupported(pGpu) kvidengIsVideoTraceLogSupported_IMPL(pGpu)
#define kvidengIsVideoTraceLogSupported_HAL(pGpu) kvidengIsVideoTraceLogSupported(pGpu)
NV_STATUS kvidengInitLogging_KERNEL(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine);
#define __nvoc_kvidengConstruct(arg_pKernelVideoEngine, arg_pGpu, arg_physEngDesc) kvidengConstruct_IMPL(arg_pKernelVideoEngine, arg_pGpu, arg_physEngDesc)
NV_STATUS kvidengInitLogging_IMPL(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine);
#ifdef __nvoc_kernel_video_engine_h_disabled
static inline NV_STATUS kvidengInitLogging(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine) {
@ -126,17 +132,56 @@ static inline NV_STATUS kvidengInitLogging(struct OBJGPU *pGpu, struct KernelVid
return NV_ERR_NOT_SUPPORTED;
}
#else //__nvoc_kernel_video_engine_h_disabled
#define kvidengInitLogging(pGpu, pKernelVideoEngine) kvidengInitLogging_IMPL(pGpu, pKernelVideoEngine)
#define kvidengInitLogging(pGpu, pKernelVideoEngine) kvidengInitLogging_KERNEL(pGpu, pKernelVideoEngine)
#endif //__nvoc_kernel_video_engine_h_disabled
void kvidengFreeLogging_IMPL(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine);
#define kvidengInitLogging_HAL(pGpu, pKernelVideoEngine) kvidengInitLogging(pGpu, pKernelVideoEngine)
void kvidengFreeLogging_KERNEL(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine);
#ifdef __nvoc_kernel_video_engine_h_disabled
static inline void kvidengFreeLogging(struct OBJGPU *pGpu, struct KernelVideoEngine *pKernelVideoEngine) {
NV_ASSERT_FAILED_PRECOMP("KernelVideoEngine was disabled!");
}
#else //__nvoc_kernel_video_engine_h_disabled
#define kvidengFreeLogging(pGpu, pKernelVideoEngine) kvidengFreeLogging_IMPL(pGpu, pKernelVideoEngine)
#define kvidengFreeLogging(pGpu, pKernelVideoEngine) kvidengFreeLogging_KERNEL(pGpu, pKernelVideoEngine)
#endif //__nvoc_kernel_video_engine_h_disabled
#define kvidengFreeLogging_HAL(pGpu, pKernelVideoEngine) kvidengFreeLogging(pGpu, pKernelVideoEngine)
NV_STATUS kvidengRingbufferMakeSpace_IMPL(struct OBJGPU *pGpu, NvU32 oldReadPtr, NvU32 size, VIDEO_TRACE_RING_BUFFER *pTraceBuffer);
#define kvidengRingbufferMakeSpace(pGpu, oldReadPtr, size, pTraceBuffer) kvidengRingbufferMakeSpace_IMPL(pGpu, oldReadPtr, size, pTraceBuffer)
NvU32 kvidengRingbufferGetDataSize_IMPL(struct OBJGPU *pGpu, VIDEO_TRACE_RING_BUFFER *arg0);
#define kvidengRingbufferGetDataSize(pGpu, arg0) kvidengRingbufferGetDataSize_IMPL(pGpu, arg0)
struct KernelVideoEngine *kvidengFromEngDesc_IMPL(struct OBJGPU *pGpu, NvU32 engDesc);
#define kvidengFromEngDesc(pGpu, engDesc) kvidengFromEngDesc_IMPL(pGpu, engDesc)
NV_STATUS kvidengConstruct_IMPL(struct KernelVideoEngine *arg_pKernelVideoEngine, struct OBJGPU *arg_pGpu, ENGDESCRIPTOR arg_physEngDesc);
#define __nvoc_kvidengConstruct(arg_pKernelVideoEngine, arg_pGpu, arg_physEngDesc) kvidengConstruct_IMPL(arg_pKernelVideoEngine, arg_pGpu, arg_physEngDesc)
NvU32 kvidengRingbufferGet_IMPL(struct OBJGPU *arg0, struct KernelVideoEngine *arg1, NvU8 *pDataOut, NvU32 sizeOut, VIDEO_TRACE_RING_BUFFER *arg2);
#ifdef __nvoc_kernel_video_engine_h_disabled
static inline NvU32 kvidengRingbufferGet(struct OBJGPU *arg0, struct KernelVideoEngine *arg1, NvU8 *pDataOut, NvU32 sizeOut, VIDEO_TRACE_RING_BUFFER *arg2) {
NV_ASSERT_FAILED_PRECOMP("KernelVideoEngine was disabled!");
return 0;
}
#else //__nvoc_kernel_video_engine_h_disabled
#define kvidengRingbufferGet(arg0, arg1, pDataOut, sizeOut, arg2) kvidengRingbufferGet_IMPL(arg0, arg1, pDataOut, sizeOut, arg2)
#endif //__nvoc_kernel_video_engine_h_disabled
NvU32 kvidengEventbufferGetRecord_IMPL(struct OBJGPU *arg0, struct KernelVideoEngine *arg1, VIDEO_TRACE_RING_BUFFER *pTraceBuffer, VIDEO_ENGINE_EVENT__RECORD *pRecord, NvU32 magic_hi, NvU32 magic_lo);
#ifdef __nvoc_kernel_video_engine_h_disabled
static inline NvU32 kvidengEventbufferGetRecord(struct OBJGPU *arg0, struct KernelVideoEngine *arg1, VIDEO_TRACE_RING_BUFFER *pTraceBuffer, VIDEO_ENGINE_EVENT__RECORD *pRecord, NvU32 magic_hi, NvU32 magic_lo) {
NV_ASSERT_FAILED_PRECOMP("KernelVideoEngine was disabled!");
return 0;
}
#else //__nvoc_kernel_video_engine_h_disabled
#define kvidengEventbufferGetRecord(arg0, arg1, pTraceBuffer, pRecord, magic_hi, magic_lo) kvidengEventbufferGetRecord_IMPL(arg0, arg1, pTraceBuffer, pRecord, magic_hi, magic_lo)
#endif //__nvoc_kernel_video_engine_h_disabled
#undef PRIVATE_FIELD

View File

@ -901,8 +901,8 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x2331, 0x1626, 0x10de, "NVIDIA H100 PCIe" },
{ 0x2339, 0x17fc, 0x10de, "NVIDIA H100" },
{ 0x233A, 0x183a, 0x10de, "NVIDIA H800 NVL" },
{ 0x2342, 0x16eb, 0x10de, "GH200 120GB" },
{ 0x2342, 0x1809, 0x10de, "GH200 480GB" },
{ 0x2342, 0x16eb, 0x10de, "NVIDIA GH200 120GB" },
{ 0x2342, 0x1809, 0x10de, "NVIDIA GH200 480GB" },
{ 0x2414, 0x0000, 0x0000, "NVIDIA GeForce RTX 3060 Ti" },
{ 0x2420, 0x0000, 0x0000, "NVIDIA GeForce RTX 3080 Ti Laptop GPU" },
{ 0x2438, 0x0000, 0x0000, "NVIDIA RTX A5500 Laptop GPU" },

File diff suppressed because it is too large Load Diff

View File

@ -427,6 +427,7 @@ struct Subdevice {
NV_STATUS (*__subdeviceCtrlCmdEventSetMemoryNotifies__)(struct Subdevice *, NV2080_CTRL_EVENT_SET_MEMORY_NOTIFIES_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdEventSetSemaphoreMemory__)(struct Subdevice *, NV2080_CTRL_EVENT_SET_SEMAPHORE_MEMORY_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdEventSetSemaMemValidation__)(struct Subdevice *, NV2080_CTRL_EVENT_SET_SEMA_MEM_VALIDATION_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdEventVideoBindEvtbuf__)(struct Subdevice *, NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdTimerCancel__)(struct Subdevice *);
NV_STATUS (*__subdeviceCtrlCmdTimerSchedule__)(struct Subdevice *, NV2080_CTRL_CMD_TIMER_SCHEDULE_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdTimerGetTime__)(struct Subdevice *, NV2080_CTRL_TIMER_GET_TIME_PARAMS *);
@ -470,6 +471,7 @@ struct Subdevice {
NV_STATUS (*__subdeviceCtrlCmdFlcnGetCtxBufferInfo__)(struct Subdevice *, NV2080_CTRL_FLCN_GET_CTX_BUFFER_INFO_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdFlcnGetCtxBufferSize__)(struct Subdevice *, NV2080_CTRL_FLCN_GET_CTX_BUFFER_SIZE_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdInternalFlcnSetVideoEventBufferFlags__)(struct Subdevice *, NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_FLAGS_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory__)(struct Subdevice *, NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdEccGetClientExposedCounters__)(struct Subdevice *, NV2080_CTRL_ECC_GET_CLIENT_EXPOSED_COUNTERS_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdGpuQueryEccConfiguration__)(struct Subdevice *, NV2080_CTRL_GPU_QUERY_ECC_CONFIGURATION_PARAMS *);
NV_STATUS (*__subdeviceCtrlCmdGpuSetEccConfiguration__)(struct Subdevice *, NV2080_CTRL_GPU_SET_ECC_CONFIGURATION_PARAMS *);
@ -1028,6 +1030,7 @@ NV_STATUS __nvoc_objCreate_Subdevice(Subdevice**, Dynamic*, NvU32, struct CALL_C
#define subdeviceCtrlCmdEventSetMemoryNotifies(pSubdevice, pSetMemoryNotifiesParams) subdeviceCtrlCmdEventSetMemoryNotifies_DISPATCH(pSubdevice, pSetMemoryNotifiesParams)
#define subdeviceCtrlCmdEventSetSemaphoreMemory(pSubdevice, pSetSemMemoryParams) subdeviceCtrlCmdEventSetSemaphoreMemory_DISPATCH(pSubdevice, pSetSemMemoryParams)
#define subdeviceCtrlCmdEventSetSemaMemValidation(pSubdevice, pSetSemaMemValidationParams) subdeviceCtrlCmdEventSetSemaMemValidation_DISPATCH(pSubdevice, pSetSemaMemValidationParams)
#define subdeviceCtrlCmdEventVideoBindEvtbuf(pSubdevice, pBindParams) subdeviceCtrlCmdEventVideoBindEvtbuf_DISPATCH(pSubdevice, pBindParams)
#define subdeviceCtrlCmdTimerCancel(pSubdevice) subdeviceCtrlCmdTimerCancel_DISPATCH(pSubdevice)
#define subdeviceCtrlCmdTimerSchedule(pSubdevice, pParams) subdeviceCtrlCmdTimerSchedule_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdTimerGetTime(pSubdevice, pParams) subdeviceCtrlCmdTimerGetTime_DISPATCH(pSubdevice, pParams)
@ -1071,6 +1074,7 @@ NV_STATUS __nvoc_objCreate_Subdevice(Subdevice**, Dynamic*, NvU32, struct CALL_C
#define subdeviceCtrlCmdFlcnGetCtxBufferInfo(pSubdevice, pParams) subdeviceCtrlCmdFlcnGetCtxBufferInfo_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdFlcnGetCtxBufferSize(pSubdevice, pParams) subdeviceCtrlCmdFlcnGetCtxBufferSize_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdInternalFlcnSetVideoEventBufferFlags(pSubdevice, pParams) subdeviceCtrlCmdInternalFlcnSetVideoEventBufferFlags_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory(pSubdevice, pParams) subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdEccGetClientExposedCounters(pSubdevice, pParams) subdeviceCtrlCmdEccGetClientExposedCounters_DISPATCH(pSubdevice, pParams)
#define subdeviceCtrlCmdGpuQueryEccConfiguration(pSubdevice, pConfig) subdeviceCtrlCmdGpuQueryEccConfiguration_DISPATCH(pSubdevice, pConfig)
#define subdeviceCtrlCmdGpuSetEccConfiguration(pSubdevice, pConfig) subdeviceCtrlCmdGpuSetEccConfiguration_DISPATCH(pSubdevice, pConfig)
@ -3125,6 +3129,12 @@ static inline NV_STATUS subdeviceCtrlCmdEventSetSemaMemValidation_DISPATCH(struc
return pSubdevice->__subdeviceCtrlCmdEventSetSemaMemValidation__(pSubdevice, pSetSemaMemValidationParams);
}
NV_STATUS subdeviceCtrlCmdEventVideoBindEvtbuf_IMPL(struct Subdevice *pSubdevice, NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_PARAMS *pBindParams);
static inline NV_STATUS subdeviceCtrlCmdEventVideoBindEvtbuf_DISPATCH(struct Subdevice *pSubdevice, NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_PARAMS *pBindParams) {
return pSubdevice->__subdeviceCtrlCmdEventVideoBindEvtbuf__(pSubdevice, pBindParams);
}
NV_STATUS subdeviceCtrlCmdTimerCancel_IMPL(struct Subdevice *pSubdevice);
static inline NV_STATUS subdeviceCtrlCmdTimerCancel_DISPATCH(struct Subdevice *pSubdevice) {
@ -3383,6 +3393,12 @@ static inline NV_STATUS subdeviceCtrlCmdInternalFlcnSetVideoEventBufferFlags_DIS
return pSubdevice->__subdeviceCtrlCmdInternalFlcnSetVideoEventBufferFlags__(pSubdevice, pParams);
}
NV_STATUS subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory_IMPL(struct Subdevice *pSubdevice, NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS *pParams);
static inline NV_STATUS subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory_DISPATCH(struct Subdevice *pSubdevice, NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS *pParams) {
return pSubdevice->__subdeviceCtrlCmdInternalFlcnSetVideoEventBufferMemory__(pSubdevice, pParams);
}
NV_STATUS subdeviceCtrlCmdEccGetClientExposedCounters_IMPL(struct Subdevice *pSubdevice, NV2080_CTRL_ECC_GET_CLIENT_EXPOSED_COUNTERS_PARAMS *pParams);
static inline NV_STATUS subdeviceCtrlCmdEccGetClientExposedCounters_DISPATCH(struct Subdevice *pSubdevice, NV2080_CTRL_ECC_GET_CLIENT_EXPOSED_COUNTERS_PARAMS *pParams) {

View File

@ -0,0 +1,127 @@
#ifndef _G_VIDEOEVENTLIST_NVOC_H_
#define _G_VIDEOEVENTLIST_NVOC_H_
#include "nvoc/runtime.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "g_videoeventlist_nvoc.h"
#ifndef VIDEO_EVENT_LIST_H
#define VIDEO_EVENT_LIST_H
/*!
* @file videoeventlist.h
* @brief Provides definition for video tracelog callback on EventBuffer, as well as a list holding the subscribers to the event
*/
#include "core/core.h"
#include "containers/multimap.h"
#include "resserv/resserv.h"
#include "kernel/gpu/eng_desc.h"
#include "class/cl90cdvideo.h"
#include "ctrl/ctrl2080/ctrl2080event.h"
struct EventBuffer;
#ifndef __NVOC_CLASS_EventBuffer_TYPEDEF__
#define __NVOC_CLASS_EventBuffer_TYPEDEF__
typedef struct EventBuffer EventBuffer;
#endif /* __NVOC_CLASS_EventBuffer_TYPEDEF__ */
#ifndef __nvoc_class_id_EventBuffer
#define __nvoc_class_id_EventBuffer 0x63502b
#endif /* __nvoc_class_id_EventBuffer */
struct KernelChannel;
#ifndef __NVOC_CLASS_KernelChannel_TYPEDEF__
#define __NVOC_CLASS_KernelChannel_TYPEDEF__
typedef struct KernelChannel KernelChannel;
#endif /* __NVOC_CLASS_KernelChannel_TYPEDEF__ */
#ifndef __nvoc_class_id_KernelChannel
#define __nvoc_class_id_KernelChannel 0x5d8d70
#endif /* __nvoc_class_id_KernelChannel */
typedef struct
{
struct EventBuffer *pEventBuffer;
NvHandle hClient;
NvHandle hNotifier;
NvHandle hEventBuffer;
NvU64 pUserInfo;
NvBool bAdmin;
NvBool bKernel;
NvBool eventMask;
} NV_EVENT_BUFFER_BIND_POINT_VIDEO;
MAKE_MULTIMAP(VideoEventBufferBindMultiMap, NV_EVENT_BUFFER_BIND_POINT_VIDEO);
/*!
* Data-structure for notify video events.
*/
typedef struct {
#if PORT_IS_MODULE_SUPPORTED(crypto)
PORT_CRYPTO_PRNG *pVideoLogPrng;
#endif
NvU64 noisyTimestampStart;
void *pEventData;
} NOTIFY_VIDEO_EVENT;
NV_STATUS videoAddBindpoint
(
OBJGPU *pGpu,
struct RsClient *pClient,
RsResourceRef *pEventBufferRef,
NvHandle hNotifier,
NvBool bAllUsers,
NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD levelOfDetail,
NvU32 eventFilter
);
void videoBufferTeardown(OBJGPU *pGpu);
void videoRemoveAllBindpoints(struct EventBuffer *pEventBuffer);
void videoRemoveBindpoint(OBJGPU *pGpu, NvU64 uid, NV_EVENT_BUFFER_BIND_POINT_VIDEO *pBind);
void videoRemoveAllBindpointsForGpu(OBJGPU *pGpu);
/* The callback function that transfers video tracelog buffer entries to user eventbuffers */
void nvEventBufferVideoCallback(OBJGPU *pGpu, void *pArgs);
NV_STATUS videoEventTraceCtxInit(OBJGPU *pGpu, struct KernelChannel *pKernelChannel, ENGDESCRIPTOR engDesc);
#endif // VIDEO_EVENT_LIST_H
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _G_VIDEOEVENTLIST_NVOC_H_

View File

@ -0,0 +1,57 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_TRIGGER,
RMCTRL_FLAGS(NON_PRIVILEGED))
NV_STATUS subdeviceCtrlCmdEventSetTrigger(Subdevice *pSubdevice);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_TRIGGER_FIFO,
RMCTRL_FLAGS(NO_GPUS_LOCK, NON_PRIVILEGED))
NV_STATUS subdeviceCtrlCmdEventSetTriggerFifo(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_SET_TRIGGER_FIFO_PARAMS *pTriggerFifoParams);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
RMCTRL_FLAGS(NON_PRIVILEGED, API_LOCK_READONLY, GPU_LOCK_DEVICE_ONLY))
NV_STATUS subdeviceCtrlCmdEventSetNotification(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *pSetEventParams);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_MEMORY_NOTIFIES,
RMCTRL_FLAGS(NON_PRIVILEGED))
NV_STATUS subdeviceCtrlCmdEventSetMemoryNotifies(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_SET_MEMORY_NOTIFIES_PARAMS *pSetMemoryNotifiesParams);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_SEMAPHORE_MEMORY,
RMCTRL_FLAGS(NON_PRIVILEGED))
NV_STATUS subdeviceCtrlCmdEventSetSemaphoreMemory(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_SET_SEMAPHORE_MEMORY_PARAMS *pSetSemMemoryParams);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_SET_SEMA_MEM_VALIDATION,
RMCTRL_FLAGS(NON_PRIVILEGED))
NV_STATUS subdeviceCtrlCmdEventSetSemaMemValidation(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_SET_SEMA_MEM_VALIDATION_PARAMS *pSetSemaMemValidationParams);
RMCTRL_EXPORT(NV2080_CTRL_CMD_EVENT_VIDEO_BIND_EVTBUF,
RMCTRL_FLAGS(NON_PRIVILEGED, API_LOCK_READONLY, GPU_LOCK_DEVICE_ONLY))
NV_STATUS subdeviceCtrlCmdEventVideoBindEvtbuf(Subdevice *pSubdevice,
NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_PARAMS *pBindParams);

View File

@ -0,0 +1,91 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "g_videoeventlist_nvoc.h"
#ifndef VIDEO_EVENT_LIST_H
#define VIDEO_EVENT_LIST_H
/*!
* @file videoeventlist.h
* @brief Provides definition for video tracelog callback on EventBuffer, as well as a list holding the subscribers to the event
*/
#include "core/core.h"
#include "containers/multimap.h"
#include "resserv/resserv.h"
#include "kernel/gpu/eng_desc.h"
#include "class/cl90cdvideo.h"
#include "ctrl/ctrl2080/ctrl2080event.h"
class EventBuffer;
class KernelChannel;
typedef struct
{
EventBuffer *pEventBuffer;
NvHandle hClient;
NvHandle hNotifier;
NvHandle hEventBuffer;
NvU64 pUserInfo;
NvBool bAdmin;
NvBool bKernel;
NvBool eventMask;
} NV_EVENT_BUFFER_BIND_POINT_VIDEO;
MAKE_MULTIMAP(VideoEventBufferBindMultiMap, NV_EVENT_BUFFER_BIND_POINT_VIDEO);
/*!
* Data-structure for notify video events.
*/
typedef struct {
#if PORT_IS_MODULE_SUPPORTED(crypto)
PORT_CRYPTO_PRNG *pVideoLogPrng;
#endif
NvU64 noisyTimestampStart;
void *pEventData;
} NOTIFY_VIDEO_EVENT;
NV_STATUS videoAddBindpoint
(
OBJGPU *pGpu,
RsClient *pClient,
RsResourceRef *pEventBufferRef,
NvHandle hNotifier,
NvBool bAllUsers,
NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD levelOfDetail,
NvU32 eventFilter
);
void videoBufferTeardown(OBJGPU *pGpu);
void videoRemoveAllBindpoints(EventBuffer *pEventBuffer);
void videoRemoveBindpoint(OBJGPU *pGpu, NvU64 uid, NV_EVENT_BUFFER_BIND_POINT_VIDEO *pBind);
void videoRemoveAllBindpointsForGpu(OBJGPU *pGpu);
/* The callback function that transfers video tracelog buffer entries to user eventbuffers */
void nvEventBufferVideoCallback(OBJGPU *pGpu, void *pArgs);
NV_STATUS videoEventTraceCtxInit(OBJGPU *pGpu, KernelChannel *pKernelChannel, ENGDESCRIPTOR engDesc);
#endif // VIDEO_EVENT_LIST_H

View File

@ -277,6 +277,8 @@ NV_STATUS kflcnAllocContext_IMPL
NV_ASSERT_OK_OR_RETURN(_kflcnAllocAndMapCtxBuffer(pGpu, pKernelFalcon, pKernelChannel));
NV_CHECK(LEVEL_ERROR, videoEventTraceCtxInit(pGpu, pKernelChannel, pKernelFalcon->physEngDesc) == NV_OK);
return _kflcnPromoteContext(pGpu, pKernelFalcon, pKernelChannel);
}

View File

@ -512,6 +512,8 @@ NV_STATUS gpuConstruct_IMPL
// allocate OS-specific GPU extension area
osInitOSHwInfo(pGpu);
multimapInit(&pGpu->videoEventBufferBindingsUid, portMemAllocatorGetGlobalNonPaged());
return gpuConstructPhysical(pGpu);
}
@ -1495,6 +1497,8 @@ gpuDestruct_IMPL
pGpu->numSubdeviceBackReferences = 0;
pGpu->maxSubdeviceBackReferences = 0;
multimapDestroy(&pGpu->videoEventBufferBindingsUid);
gpuDestructPhysical(pGpu);
}
@ -4548,15 +4552,6 @@ void gpuDestroyGenericKernelFalconList_IMPL(OBJGPU *pGpu)
pGpu->numGenericKernelFalcons = 0;
}
NvBool
gpuIsVideoTraceLogSupported
(
OBJGPU *pGpu
)
{
return !RMCFG_FEATURE_PLATFORM_MODS && !IS_SIMULATION(pGpu) && pGpu->bVideoTraceLogSupported;
}
NV_STATUS gpuBuildKernelVideoEngineList_IMPL(OBJGPU *pGpu)
{
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
@ -4635,6 +4630,9 @@ void gpuFreeVideoLogging_IMPL(OBJGPU *pGpu)
void gpuDestroyKernelVideoEngineList_IMPL(OBJGPU *pGpu)
{
NvU32 i;
videoRemoveAllBindpointsForGpu(pGpu);
for (i = 0; i < NV_ARRAY_ELEMENTS(pGpu->kernelVideoEngines); i++)
{
objDelete(pGpu->kernelVideoEngines[i]);

View File

@ -0,0 +1,698 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/***************************************************************************\
* *
* Module: videoeventlist.c *
* Description: *
* This module contains an implementation of the Event Buffer *
* callback for video events *
* *
\***************************************************************************/
#include "rmapi/client.h"
#include "rmapi/event.h"
#include "rmapi/event_buffer.h"
#include "resserv/rs_server.h"
#include "core/locks.h"
#include "os/os.h"
#include "gpuvideo/video_event.h"
#include "gpuvideo/videoeventlist.h"
#include "objtmr.h"
#include "kernel/gpu/video/kernel_video_engine.h"
#include "kernel/gpu/fifo/kernel_channel_group.h"
#include "kernel/gpu/bus/kern_bus.h"
#include "class/cl90cd.h"
#include "class/cl90cdtypes.h"
#include "class/cl90cdvideo.h"
#include "ctrl/ctrl2080/ctrl2080internal.h"
#define NV_VIDEO_TRACE_CALLBACK_TIME_NS 50000000 // Approximating 20Hz callback
/*!
* This helper function initializes the context used for video event trace.
*/
NV_STATUS
videoEventTraceCtxInit
(
OBJGPU *pGpu,
KernelChannel *pKernelChannel,
ENGDESCRIPTOR engDesc
)
{
KernelVideoEngine *pKernelVideoEngine;
MEMORY_DESCRIPTOR *pCtxMemDesc;
VIDEO_ENGINE_EVENT__LOG_INFO logInfo;
if (RMCFG_FEATURE_PLATFORM_GSP || !IS_VIDEO_ENGINE(engDesc) || !kvidengIsVideoTraceLogSupported(pGpu))
return NV_OK;
pKernelVideoEngine = kvidengFromEngDesc(pGpu, engDesc);
NV_CHECK_OR_RETURN(LEVEL_ERROR, pKernelVideoEngine != NULL, NV_OK);
NV_CHECK_OR_RETURN(LEVEL_SILENT, pKernelVideoEngine->bVideoTraceEnabled, NV_OK);
// Fill some channel specific information for event logging
logInfo.userInfo = (NvU64)(NvUPtr)pKernelChannel->pUserInfo;
logInfo.pid = pKernelChannel->ProcessID;
logInfo.context_id = kchannelGetCid(pKernelChannel);
logInfo.engine_id = ENGDESC_FIELD(engDesc, _INST);
logInfo.gfid = kchannelGetGfid(pKernelChannel);
kchangrpGetEngineContextMemDesc(pGpu,
pKernelChannel->pKernelChannelGroupApi->pKernelChannelGroup,
&pCtxMemDesc);
if (pCtxMemDesc != NULL)
{
NvU8 *pInstMem;
NvU32 i;
NvU32 *pLogInfo = (NvU32 *)&logInfo;
// Is context allocation too small to hold the client info for event trace?
NV_CHECK_OR_RETURN(LEVEL_INFO,
memdescGetSize(pCtxMemDesc) >= (VIDEO_ENGINE_EVENT__LOG_INFO__OFFSET + VIDEO_ENGINE_EVENT__LOG_INFO__SIZE),
NV_ERR_BUFFER_TOO_SMALL);
pInstMem = kbusMapRmAperture_HAL(pGpu, pCtxMemDesc);
NV_CHECK_OR_RETURN(LEVEL_ERROR, pInstMem != NULL, NV_ERR_INSUFFICIENT_RESOURCES);
for (i = 0; i < sizeof(VIDEO_ENGINE_EVENT__LOG_INFO); i += 4)
{
// Initialize client information in context allocation.
MEM_WR32(pInstMem + VIDEO_ENGINE_EVENT__LOG_INFO__OFFSET + i, pLogInfo[i / sizeof(NvU32)]);
}
kbusUnmapRmAperture_HAL(pGpu, pCtxMemDesc, &pInstMem, NV_TRUE);
}
return NV_OK;
}
static
NV_STATUS
_videoEventBufferAdd
(
OBJGPU *pGpu,
NV_EVENT_BUFFER_BIND_POINT_VIDEO *pBind,
NOTIFY_VIDEO_EVENT *pNotifyRecord,
NvU32 *pLogData,
NvBool bSanitizeUser,
NvBool bSanitizeKernel
)
{
NV_STATUS status;
NvBool bNotify;
NvP64 notificationHandle;
EVENT_BUFFER_PRODUCER_DATA notifyEvent;
NvU32 notifyIndex = NV_EVENT_BUFFER_RECORD_TYPE_VIDEO_TRACE;
VIDEO_ENGINE_EVENT__RECORD const * pRecord;
if (pNotifyRecord == NULL)
{
return NV_OK;
}
pRecord = (VIDEO_ENGINE_EVENT__RECORD const *)(pNotifyRecord->pEventData);
portMemSet(&notifyEvent, 0, sizeof(notifyEvent));
notifyEvent.pVardata = NV_PTR_TO_NvP64(NULL);
notifyEvent.vardataSize = 0;
NV_EVENT_BUFFER_VIDEO_RECORD_V1 videoRecord;
portMemSet(&videoRecord, 0, sizeof(videoRecord));
videoRecord.event_id = pRecord->event_id;
videoRecord.vmid = pRecord->gfid;
videoRecord.timestamp = pRecord->ts;
videoRecord.seqno = pRecord->seq_no;
videoRecord.context_id = pRecord->context_id;
videoRecord.pid = pRecord->pid;
videoRecord.api_id = pRecord->api_id;
if (bSanitizeKernel)
{
videoRecord.pid = NV_EVENT_BUFFER_VIDEO_KERNEL_PID;
videoRecord.context_id = NV_EVENT_BUFFER_VIDEO_KERNEL_CONTEXT;
videoRecord.api_id = NV_EVENT_BUFFER_VIDEO_KERNEL_CONTEXT;
}
else if (bSanitizeUser)
{
videoRecord.pid = NV_EVENT_BUFFER_VIDEO_HIDDEN_PID;
videoRecord.context_id = NV_EVENT_BUFFER_VIDEO_HIDDEN_CONTEXT;
videoRecord.api_id = NV_EVENT_BUFFER_VIDEO_HIDDEN_CONTEXT;
}
#if PORT_IS_MODULE_SUPPORTED(crypto)
// Randomized timestamp if sanitization is needed
if (bSanitizeKernel || bSanitizeUser)
{
//
// pNotifyRecord->noisyTimestampStart is copied from pKernelVideoEngine->videoTraceInfo->noisyTimestampStart which is initialized to 0
// during engine initialization when trace surface is allocated before session starts. pKernelVideoEngine->videoTraceInfo->noisyTimestampStart
// is recorded with the timestamp of a SESSION_START event. Engine will always log event in sequence and every SESSION_END event
// should have a SESSION_START event in front of it. Also, we are assuming NSight will discard a SESSION_END event
// without a SESSION_START event before it.
//
if ((pNotifyRecord->noisyTimestampStart != videoRecord.timestamp) && (pNotifyRecord->pVideoLogPrng != NULL))
{
NvU64 noisyTimestampRange;
// The range is always non-zero since we had check
// (pNotifyRecord->noisyTimestampStart != videoRecord.timestamp)
// above.
noisyTimestampRange = (videoRecord.timestamp >= pNotifyRecord->noisyTimestampStart)
? (videoRecord.timestamp - pNotifyRecord->noisyTimestampStart)
: (((NvU64)(-1) - pNotifyRecord->noisyTimestampStart) + videoRecord.timestamp);
videoRecord.timestamp = pNotifyRecord->noisyTimestampStart
+ portCryptoPseudoRandomGeneratorGetU32(pNotifyRecord->pVideoLogPrng) % noisyTimestampRange;
}
}
#endif // PORT_IS_MODULE_SUPPORTED(crypto)
switch (pRecord->event_id)
{
case VIDEO_ENGINE_EVENT_ID__SESSION_START:
videoRecord.session.engine_type = pRecord->event_start.engine_type;
videoRecord.session.engine_id = pRecord->event_start.engine_id;
videoRecord.session.codec_id = pRecord->event_start.codec_id;
break;
case VIDEO_ENGINE_EVENT_ID__SESSION_END:
videoRecord.session.engine_type = pRecord->event_start.engine_type;
videoRecord.session.engine_id = pRecord->event_end.engine_id;
videoRecord.session.codec_id = pRecord->event_end.codec_id;
videoRecord.session.status = pRecord->event_end.status;
break;
case VIDEO_ENGINE_EVENT_ID__POWER_STATE_CHANGE:
videoRecord.stateChange.to = pRecord->event_pstate_change.to;
videoRecord.stateChange.from = pRecord->event_pstate_change.from;
break;
case VIDEO_ENGINE_EVENT_ID__LOG_DATA:
videoRecord.logData.engine_type = pRecord->event_start.engine_type;
videoRecord.logData.engine_id = pRecord->event_start.engine_id;
videoRecord.logData.codec_id = pRecord->event_start.codec_id;
videoRecord.logData.size = pRecord->event_log_data.size;
notifyEvent.pVardata = NV_PTR_TO_NvP64(pLogData);
notifyEvent.vardataSize = videoRecord.logData.size;
break;
default:
videoRecord.event_data = pRecord->event_data;
}
notifyEvent.pPayload = NV_PTR_TO_NvP64(&videoRecord);
notifyEvent.payloadSize = sizeof(videoRecord);
status = eventBufferAdd(pBind->pEventBuffer, &notifyEvent, notifyIndex, &bNotify, &notificationHandle);
if ((status == NV_OK) && bNotify && notificationHandle)
{
osEventNotification(pGpu,
pBind->pEventBuffer->pListeners,
notifyIndex,
&notifyEvent,
0); // Do not copy structure -- embedded pointers.
pBind->pEventBuffer->bNotifyPending = NV_TRUE;
}
return status;
}
static void _notifyEventBuffers
(
OBJGPU *pGpu,
VideoEventBufferBindMultiMapSubmap *pSubmap,
NOTIFY_VIDEO_EVENT *pNotifyRecord,
NvU32 *pLogData
)
{
VIDEO_ENGINE_EVENT__RECORD const * pRecord = (VIDEO_ENGINE_EVENT__RECORD const *)pNotifyRecord->pEventData;
if (pSubmap != NULL)
{
VideoEventBufferBindMultiMapIter iter = multimapSubmapIterItems(&pGpu->videoEventBufferBindingsUid, pSubmap);
while (multimapItemIterNext(&iter))
{
NV_EVENT_BUFFER_BIND_POINT_VIDEO* pBind = iter.pValue;
NvBool bSanitizeKernel = (!pBind->bKernel) && (pRecord->userInfo == 0);
NvBool bSanitizeUser = (!pBind->bAdmin) && (pBind->pUserInfo != pRecord->userInfo);
if (!(NVBIT(pRecord->event_id) & pBind->eventMask))
continue;
_videoEventBufferAdd(pGpu, pBind, pNotifyRecord, pLogData, bSanitizeUser, bSanitizeKernel);
}
}
}
static void _videoGetTraceEvents
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine,
VideoEventBufferBindMultiMapSubmap *pSubmapAll
)
{
VideoEventBufferBindMultiMapSubmap *pSubmapUserOnly = NULL;
NvU64 cachedUserInfo = 0;
NvU32 magicHi = ENG_VIDEO_TRACE_EVENT_MAGIC_HI;
NvU32 magicLo = ENG_VIDEO_TRACE_EVENT_MAGIC_LO;
VIDEO_TRACE_RING_BUFFER *pRingbuffer;
VIDEO_ENGINE_EVENT__RECORD videoRecord;
NvU32 gotSize;
NV_ASSERT_OR_RETURN_VOID(pKernelVideoEngine != NULL);
NV_CHECK_OR_RETURN_VOID(LEVEL_INFO, pKernelVideoEngine->bVideoTraceEnabled);
pRingbuffer = pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine;
if (pRingbuffer == NULL)
return;
while (kvidengRingbufferGetDataSize(pGpu, pRingbuffer) >= sizeof(VIDEO_ENGINE_EVENT__RECORD))
{
NOTIFY_VIDEO_EVENT notifyRecord;
NvU32 oldReadPtr = pRingbuffer->readPtr;
gotSize = kvidengEventbufferGetRecord(pGpu,
pKernelVideoEngine,
pRingbuffer,
&videoRecord,
magicHi,
magicLo);
// If the read pointer was not moved by us, this record may be invalid
if ((oldReadPtr + sizeof(VIDEO_ENGINE_EVENT__RECORD)) != pRingbuffer->readPtr)
continue;
if (gotSize == 0)
continue;
if (videoRecord.event_id == VIDEO_ENGINE_EVENT_ID__SESSION_START)
{
pKernelVideoEngine->videoTraceInfo.noisyTimestampStart = videoRecord.ts;
}
notifyRecord.noisyTimestampStart = pKernelVideoEngine->videoTraceInfo.noisyTimestampStart;
notifyRecord.pVideoLogPrng = pKernelVideoEngine->videoTraceInfo.pVideoLogPrng;
notifyRecord.pEventData = (void *)(&videoRecord);
if (videoRecord.userInfo != 0)
{
if (cachedUserInfo != videoRecord.userInfo)
{
pSubmapUserOnly = multimapFindSubmap(&pGpu->videoEventBufferBindingsUid, videoRecord.userInfo);
cachedUserInfo = videoRecord.userInfo;
}
_notifyEventBuffers(pGpu,
pSubmapUserOnly,
&notifyRecord,
(NvU32 *)(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData));
}
_notifyEventBuffers(pGpu,
pSubmapAll,
&notifyRecord,
(NvU32 *)(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData));
}
}
static NV_STATUS
_videoEventBufferSetFlag(OBJGPU *pGpu, NvU32 flag)
{
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_FLAGS_PARAMS params = {0};
params.flags = flag;
NV_ASSERT_OK_OR_RETURN(
pRmApi->Control(pRmApi,
pGpu->hInternalClient,
pGpu->hInternalSubdevice,
NV2080_CTRL_CMD_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_FLAGS,
&params,
sizeof(params)));
return NV_OK;
}
static void
_videoOsWorkItem
(
NvU32 gpuInstance,
void *data
)
{
OBJGPU *pGpu = gpumgrGetGpu(gpuInstance);
nvEventBufferVideoCallback(pGpu, NULL);
}
static NV_STATUS
_videoTimerCallback
(
OBJGPU *pGpu,
OBJTMR *pTmr,
TMR_EVENT *pTmrEvent
)
{
NV_STATUS status;
NV_CHECK_OK(status, LEVEL_ERROR, osQueueWorkItemWithFlags(pGpu, _videoOsWorkItem, NULL, OS_QUEUE_WORKITEM_FLAGS_LOCK_GPU_GROUP_DEVICE_RW));
// TMR_FLAG_RECUR does not work, so reschedule it here.
NV_CHECK_OK_OR_CAPTURE_FIRST_ERROR(status, LEVEL_ERROR, tmrEventScheduleRel(pTmr, pTmrEvent, NV_VIDEO_TRACE_CALLBACK_TIME_NS));
return status;
}
static NV_STATUS
_videoTimerCreate
(
OBJGPU *pGpu
)
{
OBJTMR *pTmr = GPU_GET_TIMER(pGpu);
NvU32 timerFlags = TMR_FLAG_RECUR;
// Unix needs to use the OS timer to avoid corrupting records, but Windows doesn't have an OS timer implementation
timerFlags |= TMR_FLAG_USE_OS_TIMER;
NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
tmrEventCreate(pTmr, &pGpu->pVideoTimerEvent, _videoTimerCallback, NULL, timerFlags));
// This won't be a true 20Hz timer as the callbacks are scheduled from the time they're called
NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
tmrEventScheduleRel(pTmr, pGpu->pVideoTimerEvent, NV_VIDEO_TRACE_CALLBACK_TIME_NS));
return NV_OK;
}
static void
_videoTimerDestroy
(
OBJGPU *pGpu
)
{
if (pGpu->pVideoTimerEvent != NULL)
{
OBJTMR *pTmr = GPU_GET_TIMER(pGpu);
tmrEventCancel(pTmr, pGpu->pVideoTimerEvent);
tmrEventDestroy(pTmr, pGpu->pVideoTimerEvent);
pGpu->pVideoTimerEvent = NULL;
}
}
void
nvEventBufferVideoCallback
(
OBJGPU *pGpu,
void *pArgs
)
{
VideoEventBufferBindMultiMapSubmap *pSubmapAll = NULL;
NvU8 i;
if (!rmDeviceGpuLockIsOwner(pGpu->gpuInstance))
{
NV_ASSERT(0);
return;
}
if (pGpu->videoCtxswLogConsumerCount <= 0)
{
NV_ASSERT(pGpu->videoCtxswLogConsumerCount >= 0);
return;
}
pSubmapAll = multimapFindSubmap(&pGpu->videoEventBufferBindingsUid, 0);
if (pSubmapAll == NULL)
return;
for (i = 0; i < pGpu->numKernelVideoEngines; i++)
{
KernelVideoEngine *pKernelVideoEngine = pGpu->kernelVideoEngines[i];
_videoGetTraceEvents(pGpu, pKernelVideoEngine, pSubmapAll);
}
}
void
videoRemoveBindpoint
(
OBJGPU *pGpu,
NvU64 uid,
NV_EVENT_BUFFER_BIND_POINT_VIDEO* pBind
)
{
EventBuffer *pEventBuffer = pBind->pEventBuffer;
--pGpu->videoCtxswLogConsumerCount;
if (pGpu->videoCtxswLogConsumerCount == 0)
{
// When last client is unbound, disable engine event logging.
_videoEventBufferSetFlag(pGpu, 0);
}
unregisterEventNotificationWithData(&pEventBuffer->pListeners,
pBind->hClient,
pBind->hNotifier,
pBind->hEventBuffer,
NV_TRUE,
pEventBuffer->producerInfo.notificationHandle);
multimapRemoveItemByKey(&pGpu->videoEventBufferBindingsUid,
uid,
(NvU64)(NvUPtr)pEventBuffer);
}
NV_STATUS
videoAddBindpoint
(
OBJGPU *pGpu,
RsClient *pClient,
RsResourceRef *pEventBufferRef,
NvHandle hNotifier,
NvBool bAllUsers,
NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD levelOfDetail,
NvU32 eventFilter
)
{
NV_STATUS status;
NvHandle hClient = pClient->hClient;
RmClient *pRmClient = dynamicCast(pClient, RmClient);
NvHandle hEventBuffer = pEventBufferRef->hResource;
EventBuffer *pEventBuffer;
NvBool bVideoBindingActive = (pGpu->videoCtxswLogConsumerCount > 0);
NvU64 targetUser;
NvBool bAdmin = osIsAdministrator();
NvBool bKernel;
NvU32 eventMask = 0;
NvBool bSelectLOD;
CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
NV_ASSERT_OR_RETURN(pCallContext != NULL, NV_ERR_INVALID_STATE);
bKernel = pCallContext->secInfo.privLevel >= RS_PRIV_LEVEL_KERNEL;
bSelectLOD = bKernel;
#if defined(DEBUG) || defined(DEVELOP) || defined(NV_VERIF_FEATURES)
bSelectLOD = NV_TRUE;
#endif
LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
if (!kvidengIsVideoTraceLogSupported(pGpu))
return NV_ERR_NOT_SUPPORTED;
if (bSelectLOD)
{
switch(levelOfDetail)
{
case NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD_FULL:
eventMask = ~0;
break;
case NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD_CUSTOM:
eventMask = eventFilter;
break;
case NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_LOD_SIMPLE:
default:
// Default to SIMPLIFIED level-of-detail
eventMask |= NV_EVENT_BUFFER_VIDEO_BITMASK_TAG_ENGINE_START |
NV_EVENT_BUFFER_VIDEO_BITMASK_TAG_ENGINE_END;
}
}
else
{
// Default to SIMPLIFIED level-of-detail
eventMask |= NV_EVENT_BUFFER_VIDEO_BITMASK_TAG_ENGINE_START |
NV_EVENT_BUFFER_VIDEO_BITMASK_TAG_ENGINE_END;
}
if (bAllUsers)
{
targetUser = 0;
}
else
{
// Clients requesting only their own events will not work
NV_ASSERT_OR_RETURN(bAllUsers, NV_ERR_INVALID_ARGUMENT);
}
pEventBuffer = dynamicCast(pEventBufferRef->pResource, EventBuffer);
if (NULL == pEventBuffer)
return NV_ERR_INVALID_ARGUMENT;
if (NULL == multimapFindSubmap(&pGpu->videoEventBufferBindingsUid, targetUser))
{
if (NULL == multimapInsertSubmap(&pGpu->videoEventBufferBindingsUid, targetUser))
{
NV_PRINTF(LEVEL_ERROR, "failed to add UID binding!\n");
return NV_ERR_INSUFFICIENT_RESOURCES;
}
}
// If the binding exists already, we're done
if (NULL != multimapFindItem(&pGpu->videoEventBufferBindingsUid, targetUser, (NvU64)(NvUPtr)pEventBuffer))
return NV_OK;
NV_EVENT_BUFFER_BIND_POINT_VIDEO* pBind = multimapInsertItemNew(&pGpu->videoEventBufferBindingsUid, 0, (NvU64)(NvUPtr)pEventBuffer);
if (pBind == NULL)
return NV_ERR_INVALID_ARGUMENT;
pBind->hClient = hClient;
pBind->hNotifier = hNotifier;
pBind->hEventBuffer = hEventBuffer;
pBind->pEventBuffer = pEventBuffer;
pBind->pUserInfo = (NvU64)(NvUPtr)pRmClient->pUserInfo;
pBind->bAdmin = bAdmin;
pBind->eventMask = eventMask;
pBind->bKernel = bKernel;
++pGpu->videoCtxswLogConsumerCount;
if (pGpu->videoCtxswLogConsumerCount == 1)
{
// When first client is bound, enable engine event logging.
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
_videoEventBufferSetFlag(pGpu, VIDEO_TRACE_FLAG__LOGGING_ENABLED),
done);
}
status = registerEventNotification(&pEventBuffer->pListeners,
pClient,
hNotifier,
hEventBuffer,
NV_EVENT_BUFFER_RECORD_TYPE_VIDEO_TRACE | NV01_EVENT_WITHOUT_EVENT_DATA,
NV_EVENT_BUFFER_BIND,
pEventBuffer->producerInfo.notificationHandle,
NV_FALSE);
if (status != NV_OK)
goto done;
if (!bVideoBindingActive)
{
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR, _videoTimerCreate(pGpu), done);
}
done:
if (status != NV_OK)
{
videoRemoveBindpoint(pGpu, 0, pBind);
_videoTimerDestroy(pGpu);
}
return status;
}
void
videoRemoveAllBindpointsForGpu
(
OBJGPU *pGpu
)
{
NvS16 prevConsumerCount = pGpu->videoCtxswLogConsumerCount;
VideoEventBufferBindMultiMapSupermapIter iter;
if (pGpu->videoEventBufferBindingsUid.real.base.map.pAllocator == NULL)
return;
iter = multimapSubmapIterAll(&pGpu->videoEventBufferBindingsUid);
while (multimapSubmapIterNext(&iter))
{
VideoEventBufferBindMultiMapSubmap *pSubmap = iter.pValue;
VideoEventBufferBindMultiMapIter subIter = multimapSubmapIterItems(&pGpu->videoEventBufferBindingsUid, pSubmap);
NvU64 uid = mapKey_IMPL(iter.iter.pMap, pSubmap);
while (multimapItemIterNext(&subIter))
{
NV_EVENT_BUFFER_BIND_POINT_VIDEO* pBind = subIter.pValue;
videoRemoveBindpoint(pGpu, uid, pBind);
subIter = multimapSubmapIterItems(&pGpu->videoEventBufferBindingsUid, pSubmap);
}
}
if ((prevConsumerCount != 0) && (pGpu->videoCtxswLogConsumerCount == 0))
videoBufferTeardown(pGpu);
}
void
videoRemoveAllBindpoints
(
EventBuffer *pEventBuffer
)
{
OBJGPU *pGpu = NULL;
NvU32 gpuMask = 0;
NvU32 gpuIndex = 0;
VideoEventBufferBindMultiMapSupermapIter iter;
gpumgrGetGpuAttachInfo(NULL, &gpuMask);
while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuIndex)) != NULL)
{
iter = multimapSubmapIterAll(&pGpu->videoEventBufferBindingsUid);
while (multimapSubmapIterNext(&iter))
{
VideoEventBufferBindMultiMapSubmap *pSubmap = iter.pValue;
NV_EVENT_BUFFER_BIND_POINT_VIDEO* pBind = NULL;
NvU64 uid = mapKey_IMPL(iter.iter.pMap, pSubmap);
while ((pBind = multimapFindItem(&pGpu->videoEventBufferBindingsUid,
uid,
(NvU64)(NvUPtr)pEventBuffer)) != NULL)
{
videoRemoveBindpoint(pGpu, uid, pBind);
}
}
if (pGpu->videoCtxswLogConsumerCount == 0)
videoBufferTeardown(pGpu);
}
}
void
videoBufferTeardown
(
OBJGPU *pGpu
)
{
_videoTimerDestroy(pGpu);
}

View File

@ -277,3 +277,33 @@ subdeviceCtrlCmdEventSetSemaMemValidation_IMPL
return rmStatus;
}
NV_STATUS
subdeviceCtrlCmdEventVideoBindEvtbuf_IMPL
(
Subdevice *pSubdevice,
NV2080_CTRL_EVENT_VIDEO_BIND_EVTBUF_PARAMS *pParams
)
{
NV_STATUS status;
RsClient *pClient = RES_GET_CLIENT(pSubdevice);
RsResourceRef *pEventBufferRef = NULL;
OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
NvHandle hNotifier = RES_GET_HANDLE(pSubdevice);
LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
NV_ASSERT_OK_OR_RETURN(serverutilGetResourceRefWithType(hClient,
pParams->hEventBuffer,
classId(EventBuffer),
&pEventBufferRef));
status = videoAddBindpoint(pGpu,
pClient,
pEventBufferRef,
hNotifier,
pParams->bAllUsers,
pParams->levelOfDetail,
pParams->eventFilter);
return status;
}

View File

@ -28,6 +28,32 @@
#include "kernel/os/os.h"
#include "nvrm_registry.h"
KernelVideoEngine *
kvidengFromEngDesc
(
OBJGPU *pGpu,
NvU32 engDesc
)
{
NvU32 i;
for (i = 0; i < pGpu->numKernelVideoEngines; i++)
{
if (engDesc == pGpu->kernelVideoEngines[i]->physEngDesc)
return pGpu->kernelVideoEngines[i];
}
return NULL;
}
NvBool
kvidengIsVideoTraceLogSupported_IMPL
(
OBJGPU *pGpu
)
{
return !IS_VIRTUAL(pGpu) && !RMCFG_FEATURE_PLATFORM_MODS && !IS_SIMULATION(pGpu);
}
NV_STATUS kvidengConstruct_IMPL
(
KernelVideoEngine *pKernelVideoEngine,
@ -36,10 +62,11 @@ NV_STATUS kvidengConstruct_IMPL
)
{
pKernelVideoEngine->physEngDesc = physEngDesc;
pKernelVideoEngine->bVideoTraceEnabled = NV_FALSE;
return NV_OK;
}
NV_STATUS kvidengInitLogging_IMPL
NV_STATUS kvidengInitLogging_KERNEL
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine
@ -47,13 +74,11 @@ NV_STATUS kvidengInitLogging_IMPL
{
NV_STATUS status;
NvU32 data = NV_REG_STR_RM_VIDEO_EVENT_TRACE_DISABLED;
NvBool alwaysLogging;
NvBool bAlwaysLogging;
if (!gpuIsVideoTraceLogSupported(pGpu))
if (!kvidengIsVideoTraceLogSupported(pGpu))
return NV_OK;
NV_ASSERT_OR_RETURN(pKernelVideoEngine != NULL, NV_ERR_INVALID_STATE);
status = osReadRegistryDword(pGpu, NV_REG_STR_RM_VIDEO_EVENT_TRACE, &data);
if (status != NV_OK)
{
@ -63,7 +88,7 @@ NV_STATUS kvidengInitLogging_IMPL
DRF_NUM(_REG_STR, _RM_VIDEO_EVENT_TRACE, _EVENT_BUFFER_SIZE_IN_4k, 0x8);
}
alwaysLogging = DRF_VAL(_REG_STR, _RM_VIDEO_EVENT_TRACE, _ALWAYS_LOG, (data)) ==
bAlwaysLogging = DRF_VAL(_REG_STR, _RM_VIDEO_EVENT_TRACE, _ALWAYS_LOG, (data)) ==
NV_REG_STR_RM_VIDEO_EVENT_TRACE_ALWAYS_LOG_ENABLED;
if (data != NV_REG_STR_RM_VIDEO_EVENT_TRACE_DISABLED)
@ -72,7 +97,7 @@ NV_STATUS kvidengInitLogging_IMPL
VIDEO_TRACE_RING_BUFFER *pTraceBuf;
NvU64 seed;
NvBool bIsFbBroken = NV_FALSE;
NV_ADDRESS_SPACE videoBufferAddressSpace = ADDR_FBMEM;
NV_ADDRESS_SPACE addressSpace = ADDR_FBMEM;
eventBufferSize = DRF_VAL(_REG_STR, _RM_VIDEO_EVENT_TRACE, _EVENT_BUFFER_SIZE_IN_4k, (data)) * 0x1000;
@ -80,7 +105,7 @@ NV_STATUS kvidengInitLogging_IMPL
pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_ALL_INST_IN_SYSMEM);
if (bIsFbBroken)
videoBufferAddressSpace = ADDR_SYSMEM;
addressSpace = ADDR_SYSMEM;
// Allocate the staging buffer
NV_ASSERT_OK_OR_GOTO(
@ -90,7 +115,7 @@ NV_STATUS kvidengInitLogging_IMPL
eventBufferSize,
0,
NV_TRUE,
videoBufferAddressSpace,
addressSpace,
NV_MEMORY_UNCACHED,
MEMDESC_FLAGS_NONE),
exit);
@ -108,14 +133,43 @@ NV_STATUS kvidengInitLogging_IMPL
// clear trace buffer
portMemSet(pTraceBuf, 0, eventBufferSize);
pTraceBuf->bufferSize = eventBufferSize - sizeof(VIDEO_TRACE_RING_BUFFER);
pTraceBuf->readPtr = 0;
pTraceBuf->writePtr = 0;
pTraceBuf->flags = alwaysLogging ? VIDEO_TRACE_FLAG__LOGGING_ENABLED : 0;
pTraceBuf->flags = bAlwaysLogging ? VIDEO_TRACE_FLAG__LOGGING_ENABLED : 0;
pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine = pTraceBuf;
if (IS_GSP_CLIENT(pGpu))
{
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NV2080_CTRL_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY_PARAMS params = {0};
params.memDescInfo.base = memdescGetPhysAddr(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc, AT_GPU, 0);
params.memDescInfo.size = pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc->ActualSize;
params.memDescInfo.alignment = pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc->Alignment;
params.memDescInfo.addressSpace = addressSpace;
params.memDescInfo.cpuCacheAttrib = NV_MEMORY_UNCACHED;
params.engDesc = pKernelVideoEngine->physEngDesc;
NV_ASSERT_OK_OR_GOTO(
status,
pRmApi->Control(pRmApi,
pGpu->hInternalClient,
pGpu->hInternalSubdevice,
NV2080_CTRL_CMD_INTERNAL_FLCN_SET_VIDEO_EVENT_BUFFER_MEMORY,
&params,
sizeof(params)),
exit);
if (!params.bEngineFound)
{
kvidengFreeLogging(pGpu, pKernelVideoEngine);
goto exit;
}
}
// Allocate allocate scratch pad for variable data
pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData = portMemAllocNonPaged(RM_VIDEO_TRACE_MAX_VARIABLE_DATA_SIZE);
@ -131,25 +185,20 @@ NV_STATUS kvidengInitLogging_IMPL
*/
osGetCurrentTick(&seed);
pKernelVideoEngine->videoTraceInfo.pVideoLogPrng = portCryptoPseudoRandomGeneratorCreate(seed);
pKernelVideoEngine->bVideoTraceEnabled = NV_TRUE;
}
exit:
if (status != NV_OK)
{
kvidengFreeLogging(pGpu, pKernelVideoEngine);
if (status == NV_WARN_NOTHING_TO_DO)
status = NV_OK;
}
else
{
pKernelVideoEngine->bVideoTraceEnabled = NV_TRUE;
}
return status;
}
void kvidengFreeLogging_IMPL
void kvidengFreeLogging_KERNEL
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine
@ -163,12 +212,9 @@ void kvidengFreeLogging_IMPL
pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine = NULL;
}
if (pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc != NULL)
{
memdescFree(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc);
memdescDestroy(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc);
pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc = NULL;
}
memdescFree(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc);
memdescDestroy(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc);
pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc = NULL;
portMemFree(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData);
pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData = NULL;
@ -181,3 +227,370 @@ void kvidengFreeLogging_IMPL
pKernelVideoEngine->bVideoTraceEnabled = NV_FALSE;
}
/*!
* This helper function is responsible for freeing the space from ringbuffer by advancing the read pointer.
*
* @param[in] pGpu
* @param[in] oldReadPtr read pointer of the starting point for free
* @param[in] size size to be freed in NvU32
* @param[in] pTraceBuffer pointer to ringbuffer to get data from.
*
* @return NV_STATUS to indicate if free is successful.
*/
NV_STATUS
kvidengRingbufferMakeSpace
(
OBJGPU *pGpu,
NvU32 oldReadPtr,
NvU32 size,
VIDEO_TRACE_RING_BUFFER *pTraceBuffer
)
{
NV_STATUS status = NV_OK;
NvU32 hasSize = 0;
NvU32 oldWritePtr;
NvU64 adjustedReadPtr;
NV_ASSERT_OR_RETURN(pTraceBuffer != NULL, NV_ERR_INVALID_ARGUMENT);
// Read in writePtr first so that we don't need to worry about sync between driver and uCode.
oldWritePtr = pTraceBuffer->writePtr;
adjustedReadPtr = (NvU64)oldReadPtr;
if (oldWritePtr < oldReadPtr)
{
// Cross over 32bit boundary
hasSize = (0xFFFFFFFF - oldReadPtr) + oldWritePtr + 1;
}
else
{
hasSize = oldWritePtr - oldReadPtr;
}
if (hasSize > pTraceBuffer->bufferSize)
{
hasSize = pTraceBuffer->bufferSize;
}
// Make sure we are not free pass over the write pointer.
if (size > hasSize)
size = hasSize;
// Get newly adjusted readPtr in 64bits
adjustedReadPtr += size;
if (oldReadPtr != pTraceBuffer->readPtr)
{
NvU64 newReadPtr = 0;
if (oldReadPtr > pTraceBuffer->readPtr)
{
// 32bit turn over
newReadPtr = (NvU64)(pTraceBuffer->readPtr) + 0x100000000ULL;
}
// Only adjust the read pointer if newly freed space by other readers is not enough.
if (adjustedReadPtr > newReadPtr)
{
pTraceBuffer->readPtr = oldReadPtr + size;
}
}
else
{
pTraceBuffer->readPtr += size;
}
return status;
}
/*!
* This function is responsible for reading data from ringbuffer
*
* @param[in] pGpu
* @param[in] pKernelVideoEngine
* @param[in] pDataOut output data pointer
* @param[in] sizeOut output size in NvU32
* @param[in] pTraceBuffer pointer to ringbuffer to get data from.
*
* @return size of data read successfully.
*/
NvU32
kvidengRingbufferGet_IMPL
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine,
NvU8 *pDataOut,
NvU32 sizeOut,
VIDEO_TRACE_RING_BUFFER *pTraceBuffer
)
{
NV_ASSERT_OR_RETURN(pDataOut != NULL, 0);
NV_ASSERT_OR_RETURN(pTraceBuffer != NULL, 0);
// Read in writePtr first so that we don't need to worry about sync between driver and uCode.
NvU32 oldWritePtr = pTraceBuffer->writePtr;
NvU32 oldReadPtr = pTraceBuffer->readPtr;
NvU32 usedReadPtr = pTraceBuffer->readPtr;
NvU32 writeOffset = 0;
NvU32 readOffset = 0;
NvU32 size2Top = 0;
NvU32 hasSize = 0;
if (oldWritePtr < oldReadPtr)
{
// Cross over 32bit boundary
hasSize = (0xFFFFFFFF - oldReadPtr) + oldWritePtr + 1;
}
else
{
hasSize = oldWritePtr - oldReadPtr;
}
if (hasSize >= pTraceBuffer->bufferSize)
{
// The reader is too far behind, the data is over-written and invalid. Adjust read pointer used.
hasSize = pTraceBuffer->bufferSize;
if (oldWritePtr >= pTraceBuffer->bufferSize)
{
usedReadPtr = oldWritePtr - pTraceBuffer->bufferSize;
}
else
{
usedReadPtr = (0xFFFFFFFF - (pTraceBuffer->bufferSize - oldWritePtr)) + 1;
}
}
if ((sizeOut > hasSize) || (oldWritePtr == usedReadPtr))
{
// Not enough data.
return 0;
}
writeOffset = oldWritePtr % pTraceBuffer->bufferSize;
readOffset = usedReadPtr % pTraceBuffer->bufferSize;
size2Top = pTraceBuffer->bufferSize - readOffset;
if ((writeOffset > readOffset) || ((writeOffset <= readOffset) && (sizeOut <= size2Top)))
{
portMemCopy(pDataOut, sizeOut, &(pTraceBuffer->pData[readOffset]), sizeOut);
// Update read pointer, however we need to make sure read pointer is not updated by "free" call
// so that the data got was validated. If the read pointer is changed by free call,
// we can not guarantee the data read is valid. Therefore, 0 will be returned
// to indicate the data read is not valid.
if (pTraceBuffer->readPtr == oldReadPtr)
{
pTraceBuffer->readPtr = usedReadPtr + sizeOut;
}
else
{
// Output data could be corrupted. Invalidate the output by return 0.
sizeOut = 0;
}
}
else if ((writeOffset <= readOffset) && (sizeOut > size2Top))
{
// Has data accross top of the buffer, do 2 chunk read.
kvidengRingbufferGet(pGpu, pKernelVideoEngine, pDataOut, size2Top, pTraceBuffer);
kvidengRingbufferGet(pGpu, pKernelVideoEngine, &(pDataOut[size2Top]), sizeOut - size2Top, pTraceBuffer);
}
return sizeOut;
}
/*!
* This helper function is looking for starting point of an event record.
*
* @param[in] pGpu
* @param[in] pKernelVideoEngine
* @param[in] magic_hi magic Hi identifying types of records
* @param[in] magic_lo magic Lo identifying types of records
* @param[in] pTraceBuffer pointer to ringbuffer to get data from.
*
* @return NV_STATUS to indicate if free is successful.
*/
static NV_STATUS
_eventbufferGotoNextRecord
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine,
NvU32 magic_hi,
NvU32 magic_lo,
VIDEO_TRACE_RING_BUFFER *pTraceBuffer
)
{
NV_ASSERT_OR_RETURN(pTraceBuffer != NULL, NV_ERR_INVALID_ARGUMENT);
NvU32 i = 0;
NvU32 oldReadPtr = pTraceBuffer->readPtr;
NvU32 offset = oldReadPtr;
NvU32 hasSize = kvidengRingbufferGetDataSize(pGpu, pTraceBuffer);
if (hasSize < 8)
{
// Not enough for record magic, empty the buffer!
offset += hasSize;
}
else
{
union {
struct {
NvU32 lo;
NvU32 hi;
};
NvU64 val64bits;
} magic;
magic.hi =
(pTraceBuffer->pData[(offset + 7) % pTraceBuffer->bufferSize] << 24) +
(pTraceBuffer->pData[(offset + 6) % pTraceBuffer->bufferSize] << 16) +
(pTraceBuffer->pData[(offset + 5) % pTraceBuffer->bufferSize] << 8) +
(pTraceBuffer->pData[(offset + 4) % pTraceBuffer->bufferSize]);
magic.lo =
(pTraceBuffer->pData[(offset + 3) % pTraceBuffer->bufferSize] << 24) +
(pTraceBuffer->pData[(offset + 2) % pTraceBuffer->bufferSize] << 16) +
(pTraceBuffer->pData[(offset + 1) % pTraceBuffer->bufferSize] << 8) +
(pTraceBuffer->pData[offset % pTraceBuffer->bufferSize]);
for (i = 0; i < hasSize - 8; i++)
{
if ((magic.lo == magic_lo) && (magic.hi == magic_hi))
{
break;
}
magic.val64bits = (magic.val64bits >> 8) | (((NvU64)(pTraceBuffer->pData[(offset + i + 8) % pTraceBuffer->bufferSize])) << 56);
}
offset += i;
if (i == (hasSize - 8))
{
// Did not find magic. Empty the buffer
offset += 8;
}
}
if (offset != oldReadPtr)
{
NvU32 skipSize = 0;
if (offset < pTraceBuffer->readPtr)
{
// 32bit turn over
skipSize = offset + (0xFFFFFFFFUL - oldReadPtr) + 1UL;
}
else
{
skipSize = offset - oldReadPtr;
}
kvidengRingbufferMakeSpace(pGpu, oldReadPtr, skipSize, pTraceBuffer);
}
return NV_OK;
}
/*!
* This function is to get one record from a trace buffer.
*
* @param[in] pGpu
* @param[in] pKernelVideoEngine
* @param[in] pTraceBuffer pointer to source ringbuffer to get data from.
* @param[in] pRecord pointer to a trace record to copy data to.
* @param[in] magic_hi magic Hi identifying types of records
* @param[in] magic_lo magic Lo identifying types of records
*
* @return size of data copied successfully.
*/
NvU32
kvidengEventbufferGetRecord_IMPL
(
OBJGPU *pGpu,
KernelVideoEngine *pKernelVideoEngine,
VIDEO_TRACE_RING_BUFFER *pTraceBuffer,
VIDEO_ENGINE_EVENT__RECORD *pRecord,
NvU32 magic_hi,
NvU32 magic_lo
)
{
if (!pKernelVideoEngine->bVideoTraceEnabled)
{
return 0;
}
NV_ASSERT_OR_RETURN(pTraceBuffer != NULL, 0);
NV_ASSERT_OR_RETURN(pRecord != NULL, 0);
NV_ASSERT_OR_RETURN(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData != NULL, 0);
NvU32 size = 0;
_eventbufferGotoNextRecord(pGpu, pKernelVideoEngine, magic_hi, magic_lo, pTraceBuffer);
size = kvidengRingbufferGet(pGpu, pKernelVideoEngine, (NvU8*)pRecord, sizeof(VIDEO_ENGINE_EVENT__RECORD), pTraceBuffer);
if (size != sizeof(VIDEO_ENGINE_EVENT__RECORD))
{
return 0;
}
if (pRecord->event_id == VIDEO_ENGINE_EVENT_ID__LOG_DATA)
{
NvU32 dataSize = 0;
if (pRecord->event_log_data.size > RM_VIDEO_TRACE_MAX_VARIABLE_DATA_SIZE)
{
// Corrupted size.
return 0;
}
dataSize = kvidengRingbufferGet(pGpu, pKernelVideoEngine, pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData, pRecord->event_log_data.size, pTraceBuffer);
if (dataSize != pRecord->event_log_data.size)
{
// Corrupted data
return 0;
}
size += dataSize;
}
// Got a record and return total size of the data;
return size;
}
/*!
* This function gets the data size of a ringbuffer for external caller to peek data size of a ringbugger
*
* @param[in] pGpu
* @param[in] pKernelVideoEngine
* @param[in] pTraceBuffer pointer to a ringbuffer
*
* @return size of data in the ringbuffer
*/
NvU32
kvidengRingbufferGetDataSize_IMPL
(
OBJGPU *pGpu,
VIDEO_TRACE_RING_BUFFER *pTraceBuffer
)
{
NV_ASSERT_OR_RETURN(pTraceBuffer != NULL, 0);
// Read in read/write Ptrs first so that we don't need to worry about sync between driver and uCode.
NvU32 oldReadPtr = pTraceBuffer->readPtr;
NvU32 oldWritePtr = pTraceBuffer->writePtr;
NvU32 hasSize = 0;
if (oldWritePtr < oldReadPtr)
{
// Cross over 32bit boundary
hasSize = (0xFFFFFFFF - oldReadPtr) + oldWritePtr + 1;
}
else
{
hasSize = oldWritePtr - oldReadPtr;
}
if (hasSize > pTraceBuffer->bufferSize)
{
hasSize = pTraceBuffer->bufferSize;
}
return hasSize;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -475,6 +475,8 @@ eventbufferDestruct_IMPL
osDereferenceObjectCount(notificationHandle);
}
// Clean-up all bind points
videoRemoveAllBindpoints(pEventBuffer);
fecsRemoveAllBindpoints(pEventBuffer);
_unmapAndFreeMemory(pEventBuffer->pHeaderDesc, bKernel, pKernelMap->headerAddr,
@ -584,6 +586,7 @@ eventbuffertBufferCtrlCmdFlush_IMPL
while ((pGpu = gpumgrGetNextGpu(gpuMask, &gpuIndex)) != NULL)
{
nvEventBufferFecsCallback(pGpu, NULL);
nvEventBufferVideoCallback(pGpu, NULL);
}
return NV_OK;
}

View File

@ -445,6 +445,7 @@ SRCS += src/kernel/gpu/gpu_suspend.c
SRCS += src/kernel/gpu/gpu_timeout.c
SRCS += src/kernel/gpu/gpu_user_shared_data.c
SRCS += src/kernel/gpu/gpu_uuid.c
SRCS += src/kernel/gpu/gpuvideo/videoeventlist.c
SRCS += src/kernel/gpu/gr/arch/ampere/kgrmgr_ga100.c
SRCS += src/kernel/gpu/gr/arch/maxwell/kgraphics_gm200.c
SRCS += src/kernel/gpu/gr/arch/pascal/kgraphics_gp100.c

View File

@ -1,4 +1,4 @@
NVIDIA_VERSION = 545.29.02
NVIDIA_VERSION = 545.29.06
# This file.
VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))