Skip to content

Commit c7ce397

Browse files
Metrics IP Sampling Add Support for Streamer APIs
This Patch adds support for collecting IP Metrics using StreamerOpen, StreamerClose and StreamerReadData Related-To: LOCI-2755 Related-To: LOCI-2756 Signed-off-by: Joshua Santosh Ranjan <[email protected]>
1 parent 16b0ebe commit c7ce397

17 files changed

+767
-89
lines changed

level_zero/tools/source/metrics/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ list(APPEND L0_SRCS_TOOLS_METRICS
2020
${CMAKE_CURRENT_SOURCE_DIR}/os_metric_ip_sampling.h
2121
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_source.h
2222
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_source.cpp
23+
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_streamer.h
24+
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_streamer.cpp
2325
)
2426

2527
if(UNIX)

level_zero/tools/source/metrics/linux/os_metric_ip_sampling_imp_linux.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,17 @@ ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNRep
8181
auto ioctlHelper = drm->getIoctlHelper();
8282
uint32_t euStallFdParameter = ioctlHelper->getEuStallFdParameter();
8383
std::array<uint64_t, 10u> properties;
84-
if (!ioctlHelper->getEuStallProperties(properties, maxDssBufferSize, samplingUnit, defaultPollPeriodNs, deviceImp.getPhysicalSubDeviceId())) {
84+
auto engineInfo = drm->getEngineInfo();
85+
if (engineInfo == nullptr) {
86+
return ZE_RESULT_ERROR_UNKNOWN;
87+
}
88+
auto classInstance = engineInfo->getEngineInstance(deviceImp.getPhysicalSubDeviceId(), aub_stream::ENGINE_CCS);
89+
if (classInstance == nullptr) {
90+
return ZE_RESULT_ERROR_UNKNOWN;
91+
}
92+
93+
if (!ioctlHelper->getEuStallProperties(properties, maxDssBufferSize, samplingUnit, defaultPollPeriodNs,
94+
classInstance->engineInstance)) {
8595
return ZE_RESULT_ERROR_UNKNOWN;
8696
}
8797

@@ -107,18 +117,22 @@ ze_result_t MetricIpSamplingLinuxImp::startMeasurement(uint32_t &notifyEveryNRep
107117

108118
ze_result_t MetricIpSamplingLinuxImp::stopMeasurement() {
109119

110-
int32_t ret = NEO::SysCalls::close(stream);
111-
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, "close() failed errno = %d | ret = %d \n",
112-
errno, ret);
120+
int32_t disableStatus = NEO::SysCalls::ioctl(stream, I915_PERF_IOCTL_DISABLE, 0);
121+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (disableStatus < 0), stderr,
122+
"I915_PERF_IOCTL_DISABLE failed errno = %d | ret = %d \n", errno, disableStatus);
123+
124+
int32_t closeStatus = NEO::SysCalls::close(stream);
125+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (closeStatus < 0), stderr,
126+
"close() failed errno = %d | ret = %d \n", errno, closeStatus);
113127
stream = -1;
114128

115-
return (ret == 0) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
129+
return ((closeStatus == 0) && (disableStatus == 0)) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
116130
}
117131

118132
ze_result_t MetricIpSamplingLinuxImp::readData(uint8_t *pRawData, size_t *pRawDataSize) {
119133

120-
ssize_t ret = NEO::SysCalls::pread(stream, pRawData, *pRawDataSize, 0u);
121-
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, "pread() failed errno = %d | ret = %d \n",
134+
ssize_t ret = NEO::SysCalls::read(stream, pRawData, *pRawDataSize);
135+
PRINT_DEBUG_STRING(NEO::DebugManager.flags.PrintDebugMessages.get() && (ret < 0), stderr, "read() failed errno = %d | ret = %d \n",
122136
errno, ret);
123137

124138
if (ret >= 0) {
@@ -127,6 +141,12 @@ ze_result_t MetricIpSamplingLinuxImp::readData(uint8_t *pRawData, size_t *pRawDa
127141
}
128142

129143
*pRawDataSize = 0;
144+
145+
// If read needs to try again, do not return error
146+
if (errno == EINTR || errno == EAGAIN || errno == EBUSY) {
147+
return ZE_RESULT_SUCCESS;
148+
}
149+
130150
return ZE_RESULT_ERROR_UNKNOWN;
131151
}
132152

level_zero/tools/source/metrics/metric_ip_sampling_source.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,25 +160,17 @@ ze_result_t IpSamplingMetricGroupImp::calculateMetricValuesExp(const zet_metric_
160160
}
161161

162162
bool IpSamplingMetricGroupImp::activate() {
163-
return false;
163+
// There is no hardware specific activation, since metric collection starts in streamer open
164+
return true;
164165
}
165166

166167
bool IpSamplingMetricGroupImp::deactivate() {
167-
return false;
168+
return true;
168169
}
169170
zet_metric_group_handle_t IpSamplingMetricGroupImp::getMetricGroupForSubDevice(const uint32_t subDeviceIndex) {
170171
return toHandle();
171172
}
172173

173-
ze_result_t IpSamplingMetricGroupImp::streamerOpen(
174-
zet_context_handle_t hContext,
175-
zet_device_handle_t hDevice,
176-
zet_metric_streamer_desc_t *desc,
177-
ze_event_handle_t hNotificationEvent,
178-
zet_metric_streamer_handle_t *phMetricStreamer) {
179-
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
180-
}
181-
182174
ze_result_t IpSamplingMetricGroupImp::metricQueryPoolCreate(
183175
zet_context_handle_t hContext,
184176
zet_device_handle_t hDevice,

level_zero/tools/source/metrics/metric_ip_sampling_source.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace L0 {
1414

1515
struct IpSamplingMetricImp;
1616
struct IpSamplingMetricGroupImp;
17+
struct IpSamplingMetricStreamerImp;
1718

1819
class IpSamplingMetricSourceImp : public MetricSource {
1920

@@ -26,10 +27,13 @@ class IpSamplingMetricSourceImp : public MetricSource {
2627
ze_result_t appendMetricMemoryBarrier(CommandList &commandList) override;
2728
void setMetricOsInterface(std::unique_ptr<MetricIpSamplingOsInterface> &metricOsInterface);
2829
static std::unique_ptr<IpSamplingMetricSourceImp> create(const MetricDeviceContext &metricDeviceContext);
30+
MetricIpSamplingOsInterface *getMetricOsInterface() { return metricOsInterface.get(); }
31+
IpSamplingMetricStreamerImp *pActiveStreamer = nullptr;
2932

3033
protected:
3134
void cacheMetricGroup();
3235
bool isEnabled = false;
36+
3337
const MetricDeviceContext &metricDeviceContext;
3438
std::unique_ptr<MetricIpSamplingOsInterface> metricOsInterface = nullptr;
3539
std::unique_ptr<IpSamplingMetricGroupImp> cachedMetricGroup = nullptr;
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "level_zero/tools/source/metrics/metric_ip_sampling_streamer.h"
9+
10+
#include "level_zero/tools/source/metrics/metric.h"
11+
#include "level_zero/tools/source/metrics/metric_ip_sampling_source.h"
12+
#include "level_zero/tools/source/metrics/os_metric_ip_sampling.h"
13+
#include <level_zero/zet_api.h>
14+
15+
namespace L0 {
16+
17+
ze_result_t IpSamplingMetricGroupImp::streamerOpen(
18+
zet_context_handle_t hContext,
19+
zet_device_handle_t hDevice,
20+
zet_metric_streamer_desc_t *desc,
21+
ze_event_handle_t hNotificationEvent,
22+
zet_metric_streamer_handle_t *phMetricStreamer) {
23+
24+
auto device = Device::fromHandle(hDevice);
25+
26+
// Check whether metric group is activated.
27+
if (!device->getMetricDeviceContext().isMetricGroupActivated(this->toHandle())) {
28+
return ZE_RESULT_NOT_READY;
29+
}
30+
31+
auto &metricSource = device->getMetricDeviceContext().getMetricSource<IpSamplingMetricSourceImp>();
32+
// Check whether metric streamer is already open.
33+
if (metricSource.pActiveStreamer != nullptr) {
34+
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
35+
}
36+
37+
auto pStreamerImp = new IpSamplingMetricStreamerImp(metricSource);
38+
UNRECOVERABLE_IF(pStreamerImp == nullptr);
39+
40+
const ze_result_t result = metricSource.getMetricOsInterface()->startMeasurement(desc->notifyEveryNReports, desc->samplingPeriod);
41+
if (result == ZE_RESULT_SUCCESS) {
42+
metricSource.pActiveStreamer = pStreamerImp;
43+
pStreamerImp->attachEvent(hNotificationEvent);
44+
} else {
45+
delete pStreamerImp;
46+
pStreamerImp = nullptr;
47+
return result;
48+
}
49+
50+
*phMetricStreamer = pStreamerImp->toHandle();
51+
return ZE_RESULT_SUCCESS;
52+
}
53+
54+
ze_result_t IpSamplingMetricStreamerImp::readData(uint32_t maxReportCount, size_t *pRawDataSize, uint8_t *pRawData) {
55+
56+
// Return required size if requested.
57+
if (*pRawDataSize == 0) {
58+
*pRawDataSize = ipSamplingSource.getMetricOsInterface()->getRequiredBufferSize(maxReportCount);
59+
return ZE_RESULT_SUCCESS;
60+
}
61+
62+
// If there is a difference in pRawDataSize and maxReportCount, use the minimum value for reading.
63+
if (maxReportCount != UINT32_MAX) {
64+
size_t maxSizeRequired = ipSamplingSource.getMetricOsInterface()->getRequiredBufferSize(maxReportCount);
65+
*pRawDataSize = std::min(maxSizeRequired, *pRawDataSize);
66+
}
67+
68+
return ipSamplingSource.getMetricOsInterface()->readData(pRawData, pRawDataSize);
69+
}
70+
71+
ze_result_t IpSamplingMetricStreamerImp::close() {
72+
73+
const ze_result_t result = ipSamplingSource.getMetricOsInterface()->stopMeasurement();
74+
detachEvent();
75+
ipSamplingSource.pActiveStreamer = nullptr;
76+
delete this;
77+
78+
return result;
79+
}
80+
81+
Event::State IpSamplingMetricStreamerImp::getNotificationState() {
82+
83+
return ipSamplingSource.getMetricOsInterface()->isNReportsAvailable()
84+
? Event::State::STATE_SIGNALED
85+
: Event::State::STATE_INITIAL;
86+
}
87+
88+
ze_result_t IpSamplingMetricStreamerImp::appendStreamerMarker(CommandList &commandList, uint32_t value) {
89+
90+
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
91+
}
92+
93+
void IpSamplingMetricStreamerImp::attachEvent(ze_event_handle_t hNotificationEvent) {
94+
// Associate notification event with metric streamer.
95+
pNotificationEvent = Event::fromHandle(hNotificationEvent);
96+
if (pNotificationEvent != nullptr) {
97+
pNotificationEvent->metricStreamer = this;
98+
}
99+
}
100+
101+
void IpSamplingMetricStreamerImp::detachEvent() {
102+
// Release notification event.
103+
if (pNotificationEvent != nullptr) {
104+
pNotificationEvent->metricStreamer = nullptr;
105+
}
106+
}
107+
108+
} // namespace L0
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
10+
#include "level_zero/tools/source/metrics/metric.h"
11+
#include "level_zero/tools/source/metrics/os_metric_ip_sampling.h"
12+
13+
namespace L0 {
14+
15+
class IpSamplingMetricSourceImp;
16+
17+
struct IpSamplingMetricStreamerImp : MetricStreamer {
18+
19+
IpSamplingMetricStreamerImp(IpSamplingMetricSourceImp &ipSamplingSource) : ipSamplingSource(ipSamplingSource) {}
20+
~IpSamplingMetricStreamerImp() override{};
21+
ze_result_t readData(uint32_t maxReportCount, size_t *pRawDataSize, uint8_t *pRawData) override;
22+
ze_result_t close() override;
23+
Event::State getNotificationState() override;
24+
ze_result_t appendStreamerMarker(CommandList &commandList, uint32_t value) override;
25+
void attachEvent(ze_event_handle_t hNotificationEvent);
26+
void detachEvent();
27+
28+
protected:
29+
Event *pNotificationEvent = nullptr;
30+
IpSamplingMetricSourceImp &ipSamplingSource;
31+
};
32+
33+
} // namespace L0

level_zero/tools/test/unit_tests/sources/metrics/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ target_sources(${TARGET_NAME} PRIVATE
2020
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_oa_streamer_3.cpp
2121
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_oa_initialization.cpp
2222
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_ip_sampling_enumeration.cpp
23+
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_fixture.cpp
24+
${CMAKE_CURRENT_SOURCE_DIR}/metric_ip_sampling_fixture.h
25+
${CMAKE_CURRENT_SOURCE_DIR}/test_metric_ip_sampling_streamer.cpp
2326

2427
)
2528

0 commit comments

Comments
 (0)