From 7799611c016ba7bdb7551ee63eb24fc54c6a6eb8 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Fri, 14 Jan 2022 16:30:41 -0500 Subject: [PATCH] kfdtest: add KFDSVMRangeTest.HMMProfilingEvent Open SMI event file handle, prefetch to migrate svm range to GPU, read HMM profiling events, then check event_id, address, size, pid, event triggers are the expected value. Start separate thread to read SMI event, the same way applications use. Use thread barrier to ensure no event is dropped. Change-Id: I0683969d18d1579847e125d86aa4257602adb13f Signed-off-by: Philip Yang --- tests/kfdtest/src/KFDSVMRangeTest.cpp | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tests/kfdtest/src/KFDSVMRangeTest.cpp b/tests/kfdtest/src/KFDSVMRangeTest.cpp index 5bdcf5b80f..34484801ac 100644 --- a/tests/kfdtest/src/KFDSVMRangeTest.cpp +++ b/tests/kfdtest/src/KFDSVMRangeTest.cpp @@ -21,6 +21,7 @@ * */ #include "KFDSVMRangeTest.hpp" +#include #include #include #include "PM4Queue.hpp" @@ -1401,3 +1402,85 @@ queue_fail: TEST_END } + +/* + * Test SMI HMM SVM profiling event + * Use separate thread to read event the same way as ROCr and ROCProfiler + */ +struct ReadEventThreadParams { + int nodeid; + HSAuint64 *pBuf; + int BufSize; + pthread_barrier_t *barrier; +}; + +unsigned int ReadSMIEventThread(void* p) { + struct ReadEventThreadParams *pArgs = (struct ReadEventThreadParams *)p; + char msg[HSA_SMI_EVENT_MSG_SIZE]; + struct pollfd fds = {0}; + HSAuint64 events; + int fd; + + EXPECT_SUCCESS(hsaKmtOpenSMI(pArgs->nodeid, &fd)); + events = HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_INDEX_MAX) - 1; + EXPECT_EQ(write(fd, &events, sizeof(events)), sizeof(events)); + + pthread_barrier_wait(pArgs->barrier); + + fds.fd = fd; + fds.events = POLLIN; + EXPECT_GE(poll(&fds, 1, 1000), 0); + + memset(msg, 0, sizeof(msg)); + EXPECT_GE(read(fd, msg, HSA_SMI_EVENT_MSG_SIZE), 0); + + int event_id, pid, size, trigger, unused; + HSAuint64 timestamp; + HSAuint64 addr; + EXPECT_EQ(sscanf(msg, "%x %ld -%d @%lx(%d) %d->%x %x:%d %d\n", &event_id, ×tamp, &pid, + &addr, &size, &unused, &unused, &unused, &unused, &trigger), 10); + EXPECT_EQ(event_id, HSA_SMI_EVENT_MIGRATE_START); + EXPECT_EQ((HSAuint64 *)(addr << PAGE_SHIFT), pArgs->pBuf); + EXPECT_EQ(size << PAGE_SHIFT, pArgs->BufSize); + EXPECT_EQ(pid, getpid()); + EXPECT_EQ(trigger, HSA_MIGRATE_TRIGGER_PREFETCH); + close(fd); +} + +TEST_F(KFDSVMRangeTest, HMMProfilingEvent) { + TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX); + TEST_START(TESTPROFILE_RUNALL); + + if (!SVMAPISupported()) + return; + + if (m_VersionInfo.KernelInterfaceMinorVersion < 10) + return; + + int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); + ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; + + if (!GetVramSize(defaultGPUNode)) { + LOG() << "Skipping test: No VRAM found." << std::endl; + return; + } + + pthread_barrier_t barrier; + ASSERT_SUCCESS(pthread_barrier_init(&barrier, NULL, 2)); + + int BufSize = 16 << 10; + HsaSVMRange SysBuffer(BufSize, defaultGPUNode); + HSAuint64 *pBuf = SysBuffer.As(); + + struct ReadEventThreadParams pArgs = {defaultGPUNode, pBuf, BufSize, &barrier}; + uint64_t threadId; + ASSERT_EQ(true, StartThread(&ReadSMIEventThread, &pArgs, threadId)); + + pthread_barrier_wait(&barrier); + + EXPECT_SUCCESS(SVMRangePrefetchToNode(pBuf, BufSize, defaultGPUNode)); + + WaitForThread(threadId); + + TEST_END +}