Trace GPU activity
The firmware supports putting events (like when it starts/stops
processing activity) into a ringbuffer. Hook up tracing to the code that
reads and processes those events.
Bug: 13267
Change-Id: I2cc36bc1c322011ae9d8182355f5477f8f4bcb5d
diff --git a/BUILD.gn b/BUILD.gn
index af6ced5..01ad5ae 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -97,6 +97,7 @@
"services/server/env/fuchsia/pmr_os.cc",
"services/server/env/fuchsia/pvr_bridge_k.cc",
"services/server/env/fuchsia/pvr_debug.cc",
+ "services/server/env/fuchsia/pvr_gputrace.cc",
"services/system/common/env/fuchsia/dma_support.cc",
"services/system/fuchsia/sysconfig.cc",
]
diff --git a/fuchsia/msd_img_device.cc b/fuchsia/msd_img_device.cc
index 09f2959..bcdac29 100644
--- a/fuchsia/msd_img_device.cc
+++ b/fuchsia/msd_img_device.cc
@@ -16,6 +16,7 @@
#include "process_stats.h"
#include "pvrsrv.h"
#include "pvrsrv_error.h"
+#include "pvr_gputrace.h"
#include "rgxdevice.h"
#include "rgxinit.h"
#include "srvcore.h"
@@ -55,8 +56,18 @@
SORgxGpuUtilStatsUnregister(stats_user_);
}
#endif
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+ if (trace_observer_)
+ {
+ trace_observer_.reset();
+ PVRGpuTraceEnabledSet(IMG_FALSE);
+ }
+#endif
if (device_node_)
{
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+ PVRGpuTraceDeInitDevice(device_node_);
+#endif
PVRSRVDeviceDestroy(device_node_);
}
if (g_driver_initialized)
@@ -141,6 +152,24 @@
return DRETF(false, "Failed to initialize stats: %d", srv_err);
}
#endif
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+ srv_err = PVRGpuTraceInitDevice(device_node_);
+ if (srv_err != 0)
+ {
+ return DRETF(false, "Failed to initialize GPU tracing: %d", srv_err);
+ }
+ trace_observer_ = magma::PlatformTraceObserver::Create();
+ if (!trace_observer_)
+ {
+ return DRETF(false, "Failed to make trace observer");
+ }
+ trace_observer_->SetObserver([](bool enabled) {
+ PVRGpuTraceEnabledSet(static_cast<IMG_BOOL>(enabled));
+ // Don't enable UFO or Firmware activity notifications, since they seem
+ // pretty chatty.
+ });
+
+#endif
return true;
}
diff --git a/fuchsia/msd_img_device.h b/fuchsia/msd_img_device.h
index de6612c..a92065c 100644
--- a/fuchsia/msd_img_device.h
+++ b/fuchsia/msd_img_device.h
@@ -13,6 +13,7 @@
#include "msd_img_connection.h"
#include "platform_bus_mapper.h"
#include "platform_device.h"
+#include "platform_trace.h"
typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE;
typedef void* IMG_HANDLE;
@@ -85,6 +86,7 @@
#if !defined(NO_HARDWARE)
IMG_HANDLE stats_user_ = nullptr;
#endif
+ std::unique_ptr<magma::PlatformTraceObserver> trace_observer_;
std::unique_ptr<FuchsiaSysInfo> sys_info_;
};
diff --git a/include/config_kernel_fuchsia_mt8167.h b/include/config_kernel_fuchsia_mt8167.h
index 548acd3..dc6e1e5 100644
--- a/include/config_kernel_fuchsia_mt8167.h
+++ b/include/config_kernel_fuchsia_mt8167.h
@@ -127,6 +127,7 @@
#define PVRSRV_ENABLE_PROCESS_STATS
#define SUPPORT_DEVICEMEMHISTORY_BRIDGE
+#define SUPPORT_GPUTRACE_EVENTS 1
#define SUPPORT_PAGE_FAULT_DEBUG
#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO
#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO_THRESHOLD 90
diff --git a/include/config_kernel_fuchsia_no_hardware.h b/include/config_kernel_fuchsia_no_hardware.h
index 2d5cae0..d6bf156 100644
--- a/include/config_kernel_fuchsia_no_hardware.h
+++ b/include/config_kernel_fuchsia_no_hardware.h
@@ -127,6 +127,7 @@
#define RGX_FW_HEAP_SHIFT 25
#define SUPPORT_DBGDRV_EVENT_OBJECTS
#define SUPPORT_DEVICEMEMHISTORY_BRIDGE
+#define SUPPORT_GPUTRACE_EVENTS 1
#define SUPPORT_MMU_PENDING_FAULT_PROTECTION
#define SUPPORT_PAGE_FAULT_DEBUG
#define SUPPORT_PERCONTEXT_FREELIST
diff --git a/services/server/env/fuchsia/pvr_gputrace.cc b/services/server/env/fuchsia/pvr_gputrace.cc
new file mode 100644
index 0000000..bef7af5
--- /dev/null
+++ b/services/server/env/fuchsia/pvr_gputrace.cc
@@ -0,0 +1,170 @@
+/*************************************************************************/ /*!
+@File pvr_gputrace.c
+@Title PVR GPU Trace module Linux implementation
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+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.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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.
+*/ /**************************************************************************/
+
+extern "C"
+{
+#include "device.h"
+#include "pvr_debug.h"
+#include "pvr_gputrace.h"
+#include "pvrsrv_apphint.h"
+#include "pvrsrv_error.h"
+#include "rgxhwperf.h"
+}
+
+#include "platform_trace.h"
+
+
+/******************************************************************************
+ Module In-bound API
+******************************************************************************/
+
+uint64_t
+GetFlowId(const IMG_UINT32 ui32CtxId, const IMG_UINT32 ui32JobId)
+{
+ return (static_cast<uint64_t>(ui32CtxId) << 32) | ui32JobId;
+}
+
+void
+PVRGpuTraceClientWork(PVRSRV_DEVICE_NODE *psDevNode,
+ const IMG_UINT32 ui32CtxId,
+ const IMG_UINT32 ui32JobId,
+ const IMG_CHAR *pszKickType)
+{
+ PVR_ASSERT(pszKickType);
+
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "PVRGpuTraceClientKick(%s): contextId %u, "
+ "jobId %u",
+ pszKickType, ui32CtxId, ui32JobId));
+
+ TRACE_INSTANT("magma", "Kick", TRACE_SCOPE_THREAD, "type", pszKickType, "ui32CtxId", ui32CtxId, "ui32JobId",
+ ui32JobId);
+ TRACE_FLOW_BEGIN("magma", "work", GetFlowId(ui32CtxId, ui32JobId));
+}
+
+void
+PVRGpuTraceWorkSwitch(IMG_UINT64 ui64HWTimestampInOSTimeNs,
+ const IMG_UINT32 ui32CtxId,
+ const IMG_UINT32 ui32CtxPriority,
+ const IMG_UINT32 ui32JobId,
+ const IMG_CHAR *pszWorkType,
+ PVR_GPUTRACE_SWITCH_TYPE eSwType)
+{
+ PVR_ASSERT(pszWorkType);
+
+ // ui64HWTimestampInOSTime is in ns.
+ uint64_t ticks = ui64HWTimestampInOSTimeNs * zx_ticks_per_second() / 1000000000;
+
+ if (eSwType == PVR_GPUTRACE_SWITCH_TYPE_BEGIN)
+ {
+ TRACE_VTHREAD_DURATION_BEGIN("magma", pszWorkType, "GPU", 0, ticks, "ui32CtxId", ui32CtxId, "ui32CtxPriority",
+ ui32CtxPriority, "ui32JobId", ui32JobId);
+ TRACE_VTHREAD_FLOW_END("magma", "work", "GPU", 0, GetFlowId(ui32CtxId, ui32JobId), ticks);
+ }
+ else if (eSwType == PVR_GPUTRACE_SWITCH_TYPE_END)
+ {
+ TRACE_VTHREAD_DURATION_END("magma", pszWorkType, "GPU", 0, ticks, "ui32CtxId", ui32CtxId, "ui32CtxPriority",
+ ui32CtxPriority, "ui32JobId", ui32JobId);
+ }
+ else
+ {
+ TRACE_VTHREAD_DURATION_BEGIN("magma", pszWorkType, "GPU", 0, ticks, "ui32CtxId", ui32CtxId, "ui32CtxPriority",
+ ui32CtxPriority, "ui32JobId", ui32JobId);
+ TRACE_VTHREAD_DURATION_END("magma", pszWorkType, "GPU", 0, ticks, "ui32CtxId", ui32CtxId, "ui32CtxPriority",
+ ui32CtxPriority, "ui32JobId", ui32JobId);
+ }
+}
+
+void
+PVRGpuTraceUfo(IMG_UINT64 ui64OSTimestampNs,
+ const RGX_HWPERF_UFO_EV eEvType,
+ const IMG_UINT32 ui32ExtJobRef,
+ const IMG_UINT32 ui32CtxId,
+ const IMG_UINT32 ui32JobId,
+ const IMG_UINT32 ui32UFOCount,
+ const RGX_HWPERF_UFO_DATA_ELEMENT *puData)
+{
+ // Never enabled.
+}
+
+void
+PVRGpuTraceFirmware(IMG_UINT64 ui64HWTimestampInOSTimeNs, const IMG_CHAR *pszWorkType, PVR_GPUTRACE_SWITCH_TYPE eSwType)
+{
+ // Never enabled.
+}
+
+void
+PVRGpuTraceEventsLost(const RGX_HWPERF_STREAM_ID eStreamId, const IMG_UINT32 ui32LastOrdinal, const IMG_UINT32 ui32CurrOrdinal)
+{
+ // Ignore
+}
+
+PVRSRV_ERROR
+PVRGpuTraceSupportInit(void)
+{
+ PVRSRV_ERROR eError;
+
+ eError = RGXHWPerfFTraceGPUInitSupport();
+ PVR_LOGR_IF_ERROR(eError, "RGXHWPerfFTraceGPUSupportInit");
+
+ return PVRSRV_OK;
+}
+
+void
+PVRGpuTraceSupportDeInit(void)
+{
+ RGXHWPerfFTraceGPUDeInitSupport();
+}
+
+PVRSRV_ERROR
+PVRGpuTraceInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+
+ eError = RGXHWPerfFTraceGPUInitDevice(psDeviceNode);
+ PVR_LOGG_IF_ERROR(eError, "RGXHWPerfFTraceGPUInitDevice", e0);
+
+ return PVRSRV_OK;
+
+e0:
+ RGXHWPerfFTraceGPUDeInitDevice(psDeviceNode);
+ return eError;
+}
+
+void
+PVRGpuTraceDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ RGXHWPerfFTraceGPUDeInitDevice(psDeviceNode);
+}
+
+
+/******************************************************************************
+ End of file (pvr_gputrace.c)
+******************************************************************************/
diff --git a/services/server/env/fuchsia/pvr_gputrace.h b/services/server/env/fuchsia/pvr_gputrace.h
new file mode 100644
index 0000000..7a54889
--- /dev/null
+++ b/services/server/env/fuchsia/pvr_gputrace.h
@@ -0,0 +1,121 @@
+/*************************************************************************/ /*!
+@File pvr_gputrace.h
+@Title PVR GPU Trace module common environment interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+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.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) 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; AND (B) 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.
+*/ /**************************************************************************/
+
+#ifndef PVR_GPUTRACE_H_
+#define PVR_GPUTRACE_H_
+
+#include "img_types.h"
+#include "rgx_hwperf.h"
+#include "device.h"
+
+
+/******************************************************************************
+ Module out-bound API
+******************************************************************************/
+
+/*
+ The device layer of the KM driver defines these two APIs to allow a
+ platform module to set and retrieve the feature's on/off state.
+*/
+extern PVRSRV_ERROR
+PVRGpuTraceEnabledSet(IMG_BOOL bNewValue);
+extern PVRSRV_ERROR
+PVRGpuTraceEnabledSetNoBridgeLock(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_BOOL bNewValue);
+
+/******************************************************************************
+ Module In-bound API
+******************************************************************************/
+
+typedef enum
+{
+ PVR_GPUTRACE_SWITCH_TYPE_UNDEF = 0,
+
+ PVR_GPUTRACE_SWITCH_TYPE_BEGIN = 1,
+ PVR_GPUTRACE_SWITCH_TYPE_END = 2
+
+} PVR_GPUTRACE_SWITCH_TYPE;
+
+void
+PVRGpuTraceClientWork(PVRSRV_DEVICE_NODE *psDevNode,
+ const IMG_UINT32 ui32ExtJobRef,
+ const IMG_UINT32 ui32IntJobRef,
+ const IMG_CHAR *pszKickType);
+
+
+void
+PVRGpuTraceWorkSwitch(IMG_UINT64 ui64OSTimestamp,
+ const IMG_UINT32 ui32ContextId,
+ const IMG_UINT32 ui32CtxPriority,
+ const IMG_UINT32 ui32JobId,
+ const IMG_CHAR *pszWorkType,
+ PVR_GPUTRACE_SWITCH_TYPE eSwType);
+
+void
+PVRGpuTraceUfo(IMG_UINT64 ui64OSTimestamp,
+ const RGX_HWPERF_UFO_EV eEvType,
+ const IMG_UINT32 ui32ExtJobRef,
+ const IMG_UINT32 ui32CtxId,
+ const IMG_UINT32 ui32JobId,
+ const IMG_UINT32 ui32UFOCount,
+ const RGX_HWPERF_UFO_DATA_ELEMENT *puData);
+
+void
+PVRGpuTraceFirmware(IMG_UINT64 ui64HWTimestampInOSTime, const IMG_CHAR *pszWorkType, PVR_GPUTRACE_SWITCH_TYPE eSwType);
+
+void
+PVRGpuTraceEventsLost(const RGX_HWPERF_STREAM_ID eStreamId,
+ const IMG_UINT32 ui32LastOrdinal,
+ const IMG_UINT32 ui32CurrOrdinal);
+
+/* Early initialisation of GPU Ftrace events logic.
+ * This function initialises some necessary structures. */
+PVRSRV_ERROR
+PVRGpuTraceSupportInit(void);
+void
+PVRGpuTraceSupportDeInit(void);
+
+PVRSRV_ERROR
+PVRGpuTraceInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+void
+PVRGpuTraceDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/* FTrace events callbacks interface */
+
+void
+PVRGpuTraceEnableUfoCallback(void);
+void
+PVRGpuTraceDisableUfoCallback(void);
+
+void
+PVRGpuTraceEnableFirmwareActivityCallback(void);
+void
+PVRGpuTraceDisableFirmwareActivityCallback(void);
+
+#endif /* PVR_GPUTRACE_H_ */