Improve Pmu Ult's such that syscalls are not called directly

Signed-off-by: Mayank Raghuwanshi <mayank.raghuwanshi@intel.com>
This commit is contained in:
Mayank Raghuwanshi 2021-04-22 19:24:31 +05:30 committed by Compute-Runtime-Automation
parent 1823054e08
commit a92798ec4f
4 changed files with 48 additions and 61 deletions

View File

@ -42,17 +42,13 @@ uint32_t PmuInterfaceImp::getEventType() {
return eventTypeVal; return eventTypeVal;
} }
ssize_t PmuInterfaceImp::readCounters(int fd, uint64_t *data, ssize_t sizeOfdata) {
return read(fd, data, sizeOfdata);
}
int PmuInterfaceImp::getErrorNo() { int PmuInterfaceImp::getErrorNo() {
return errno; return errno;
} }
inline int64_t PmuInterfaceImp::perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) { inline int64_t PmuInterfaceImp::perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) {
attr->size = sizeof(*attr); attr->size = sizeof(*attr);
return syscall(perfEventOpenSyscallNumber, attr, pid, cpu, groupFd, flags); return this->syscallFunction(perfEventOpenSyscallNumber, attr, pid, cpu, groupFd, flags);
} }
int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint32_t format) { int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint32_t format) {
@ -82,7 +78,7 @@ int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint32_t f
int PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) { int PmuInterfaceImp::pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) {
ssize_t len; ssize_t len;
len = readCounters(fd, data, sizeOfdata); len = this->readFunction(fd, data, sizeOfdata);
if (len != sizeOfdata) { if (len != sizeOfdata) {
return -1; return -1;
} }

View File

@ -24,9 +24,10 @@ class PmuInterfaceImp : public PmuInterface, NEO::NonCopyableOrMovableClass {
MOCKABLE_VIRTUAL int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override; MOCKABLE_VIRTUAL int pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override;
protected: protected:
MOCKABLE_VIRTUAL int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags);
MOCKABLE_VIRTUAL ssize_t readCounters(int fd, uint64_t *data, ssize_t sizeOfdata);
MOCKABLE_VIRTUAL int getErrorNo(); MOCKABLE_VIRTUAL int getErrorNo();
MOCKABLE_VIRTUAL int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags);
decltype(&read) readFunction = read;
decltype(&syscall) syscallFunction = syscall;
private: private:
uint32_t getEventType(); uint32_t getEventType();

View File

@ -23,7 +23,8 @@ class MockPmuInterfaceImpForSysman : public PmuInterfaceImp {
public: public:
using PmuInterfaceImp::getErrorNo; using PmuInterfaceImp::getErrorNo;
using PmuInterfaceImp::perfEventOpen; using PmuInterfaceImp::perfEventOpen;
using PmuInterfaceImp::readCounters; using PmuInterfaceImp::readFunction;
using PmuInterfaceImp::syscallFunction;
MockPmuInterfaceImpForSysman(LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {} MockPmuInterfaceImpForSysman(LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {}
}; };
template <> template <>
@ -37,41 +38,22 @@ struct Mock<MockPmuInterfaceImpForSysman> : public MockPmuInterfaceImpForSysman
return -1; return -1;
} }
int mockedPmuReadAfterClearAndSuccessReturn(int fd, uint64_t *data, ssize_t sizeOfdata) { int mockedReadCountersForGroupSuccess(int fd, uint64_t *data, ssize_t sizeOfdata) {
memset(data, 0, sizeOfdata);
return 0;
}
int mockedPmuReadAndFailureReturn(int fd, uint64_t *data, ssize_t sizeOfdata) {
return -1;
}
ssize_t mockReadCounterSuccess(int fd, uint64_t *data, ssize_t sizeOfdata) {
data[0] = mockEventVal;
data[1] = mockTimeStamp;
return sizeOfdata;
}
ssize_t mockedReadCountersForGroupSuccess(int fd, uint64_t *data, ssize_t sizeOfdata) {
data[0] = mockEventCount; data[0] = mockEventCount;
data[1] = mockTimeStamp; data[1] = mockTimeStamp;
data[2] = mockEvent1Val; data[2] = mockEvent1Val;
data[3] = mockEvent2Val; data[3] = mockEvent2Val;
return sizeOfdata; return 0;
} }
ssize_t mockReadCounterFailure(int fd, uint64_t *data, ssize_t sizeOfdata) {
return -1;
}
int mockGetErrorNoSuccess() { int mockGetErrorNoSuccess() {
return EINVAL; return EINVAL;
} }
int mockGetErrorNoFailure() { int mockGetErrorNoFailure() {
return EBADF; return EBADF;
} }
MOCK_METHOD(int, pmuRead, (int fd, uint64_t *data, ssize_t sizeOfdata), (override));
MOCK_METHOD(int64_t, perfEventOpen, (perf_event_attr * attr, pid_t pid, int cpu, int groupFd, uint64_t flags), (override)); MOCK_METHOD(int64_t, perfEventOpen, (perf_event_attr * attr, pid_t pid, int cpu, int groupFd, uint64_t flags), (override));
MOCK_METHOD(ssize_t, readCounters, (int fd, uint64_t *data, ssize_t sizeOfdata), (override));
MOCK_METHOD(int, getErrorNo, (), (override)); MOCK_METHOD(int, getErrorNo, (), (override));
}; };
@ -85,5 +67,6 @@ struct Mock<PmuFsAccess> : public PmuFsAccess {
return ZE_RESULT_SUCCESS; return ZE_RESULT_SUCCESS;
} }
}; };
} // namespace ult } // namespace ult
} // namespace L0 } // namespace L0

View File

@ -31,10 +31,10 @@ struct SysmanPmuFixture : public SysmanDeviceFixture {
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PmuFsAccess>::readValSuccess)); .WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PmuFsAccess>::readValSuccess));
ON_CALL(*pPmuInterface.get(), perfEventOpen(_, _, _, _, _)) ON_CALL(*pPmuInterface.get(), perfEventOpen(_, _, _, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockedPerfEventOpenAndSuccessReturn)); .WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockedPerfEventOpenAndSuccessReturn));
ON_CALL(*pPmuInterface.get(), pmuRead(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockedReadCountersForGroupSuccess));
ON_CALL(*pPmuInterface.get(), getErrorNo()) ON_CALL(*pPmuInterface.get(), getErrorNo())
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockGetErrorNoSuccess)); .WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockGetErrorNoSuccess));
ON_CALL(*pPmuInterface.get(), readCounters(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockReadCounterSuccess));
} }
void TearDown() override { void TearDown() override {
SysmanDeviceFixture::TearDown(); SysmanDeviceFixture::TearDown();
@ -43,38 +43,48 @@ struct SysmanPmuFixture : public SysmanDeviceFixture {
} }
}; };
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuReadAndReadCountersFunctionReturnsSuccessThenSuccessIsReturned) { inline static ssize_t openReadReturnSuccess(int fd, void *data, size_t sizeOfdata) {
uint64_t dataVal[2] = {mockEventVal, mockTimeStamp};
memcpy_s(data, sizeOfdata, dataVal, sizeOfdata);
return sizeOfdata;
}
inline static ssize_t openReadReturnFailure(int fd, void *data, size_t sizeOfdata) {
return -1;
}
inline static long int syscallReturnSuccess(long int sysNo, ...) noexcept {
return mockPmuFd;
}
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuReadThenSuccessIsReturned) {
MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp);
pmuInterface->readFunction = openReadReturnSuccess;
uint64_t data[2]; uint64_t data[2];
int validFd = 10; int validFd = 10;
EXPECT_EQ(0, pLinuxSysmanImp->pPmuInterface->pmuRead(validFd, data, sizeof(data))); EXPECT_EQ(0, pmuInterface->pmuRead(validFd, data, sizeof(data)));
EXPECT_EQ(mockEventVal, data[0]); EXPECT_EQ(mockEventVal, data[0]);
EXPECT_EQ(mockTimeStamp, data[1]); EXPECT_EQ(mockTimeStamp, data[1]);
}
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuReadAndReadCountersFunctionReturnsFailureThenFailureIsReturned) {
ON_CALL(*pPmuInterface.get(), readCounters(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockReadCounterFailure));
int validFd = 10;
uint64_t data[2];
EXPECT_EQ(-1, pLinuxSysmanImp->pPmuInterface->pmuRead(validFd, data, sizeof(data)));
}
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingReadCountersAndInvalidFdIsPassedToReadSyscallThenFailureIsReturned) {
MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp);
uint64_t data[2];
int invalidFd = -1;
EXPECT_EQ(-1, pmuInterface->readCounters(invalidFd, data, sizeof(data)));
delete pmuInterface; delete pmuInterface;
} }
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPerfEventOpenAndInvalidConfigIsPassedThenFailureIsReturned) { TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPerEventOpenThenSuccessIsReturned) {
MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp);
pmuInterface->syscallFunction = syscallReturnSuccess;
struct perf_event_attr attr = {}; struct perf_event_attr attr = {};
int cpu = 0; int cpu = 0;
attr.type = 0;
attr.read_format = static_cast<uint64_t>(PERF_FORMAT_TOTAL_TIME_ENABLED); attr.read_format = static_cast<uint64_t>(PERF_FORMAT_TOTAL_TIME_ENABLED);
attr.config = 0; attr.config = 11;
EXPECT_LT(pmuInterface->perfEventOpen(&attr, -1, cpu, -1, 0), 0); EXPECT_EQ(mockPmuFd, pmuInterface->perfEventOpen(&attr, -1, cpu, -1, 0));
delete pmuInterface;
}
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingThenFailureIsReturned) {
MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp);
pmuInterface->readFunction = openReadReturnFailure;
int validFd = 10;
uint64_t data[2];
EXPECT_EQ(-1, pmuInterface->pmuRead(validFd, data, sizeof(data)));
delete pmuInterface; delete pmuInterface;
} }
@ -84,8 +94,6 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEv
} }
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenReadingGroupOfEventsUsingGroupFdThenSuccessIsReturned) { TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenReadingGroupOfEventsUsingGroupFdThenSuccessIsReturned) {
ON_CALL(*pPmuInterface.get(), readCounters(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImpForSysman>::mockedReadCountersForGroupSuccess));
uint64_t configForEvent1 = 10; uint64_t configForEvent1 = 10;
int64_t groupFd = pLinuxSysmanImp->pPmuInterface->pmuInterfaceOpen(configForEvent1, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); // To get group leader int64_t groupFd = pLinuxSysmanImp->pPmuInterface->pmuInterfaceOpen(configForEvent1, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); // To get group leader
uint64_t configForEvent2 = 15; uint64_t configForEvent2 = 15;
@ -114,13 +122,12 @@ TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingPmuInterfaceOpenAndPerfEv
EXPECT_EQ(-1, pLinuxSysmanImp->pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED)); EXPECT_EQ(-1, pLinuxSysmanImp->pPmuInterface->pmuInterfaceOpen(config, -1, PERF_FORMAT_TOTAL_TIME_ENABLED));
} }
TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenCallingReadCountersAndInvalidFdIsPassedToReadSyscallThenErrorNoInavlidFileDescriptorIsSet) { TEST_F(SysmanPmuFixture, GivenValidPmuHandleWhenAndDomainErrorOccursThenDomainErrorIsReturnedBygetErrorNoFunction) {
MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp); MockPmuInterfaceImpForSysman *pmuInterface = new MockPmuInterfaceImpForSysman(pLinuxSysmanImp);
uint64_t data[2]; log(-1.0); //Domain error injected
int invalidFd = -1; EXPECT_EQ(EDOM, pmuInterface->getErrorNo());
EXPECT_EQ(-1, pmuInterface->readCounters(invalidFd, data, sizeof(data)));
EXPECT_EQ(EBADF, pmuInterface->getErrorNo());
delete pmuInterface; delete pmuInterface;
} }
} // namespace ult } // namespace ult
} // namespace L0 } // namespace L0