From 6704b051d265980e087bdc75606822ac66cd0cf7 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Tue, 11 Jun 2019 20:12:34 -0400 Subject: [PATCH] kfdtest: Factor out multi-process test into a base class Create KFDMultiProcessTest base class for tests forking multiple child processes. Derive KFDEvictTest from that class. Change-Id: Ie5f3362c45be2b807bf7a83839ab3820352a67f9 Signed-off-by: Felix Kuehling --- tests/kfdtest/src/KFDEvictTest.cpp | 73 +++++++-------------- tests/kfdtest/src/KFDEvictTest.hpp | 30 +++------ tests/kfdtest/src/KFDMultiProcessTest.cpp | 77 +++++++++++++++++++++++ tests/kfdtest/src/KFDMultiProcessTest.hpp | 62 ++++++++++++++++++ 4 files changed, 169 insertions(+), 73 deletions(-) create mode 100644 tests/kfdtest/src/KFDMultiProcessTest.cpp create mode 100644 tests/kfdtest/src/KFDMultiProcessTest.hpp diff --git a/tests/kfdtest/src/KFDEvictTest.cpp b/tests/kfdtest/src/KFDEvictTest.cpp index cdc6c792b0..f4a4f8cde6 100644 --- a/tests/kfdtest/src/KFDEvictTest.cpp +++ b/tests/kfdtest/src/KFDEvictTest.cpp @@ -34,6 +34,28 @@ #define ALLOCATE_BUF_SIZE_MB (64) #define ALLOCATE_RETRY_TIMES (3) +void KFDEvictTest::SetUp() { + ROUTINE_START + + KFDBaseComponentTest::SetUp(); + + m_pIsaGen = IsaGenerator::Create(m_FamilyId); + + ROUTINE_END +} + +void KFDEvictTest::TearDown() { + ROUTINE_START + + if (m_pIsaGen) + delete m_pIsaGen; + m_pIsaGen = NULL; + + KFDBaseComponentTest::TearDown(); + + ROUTINE_END +} + void KFDEvictTest::AllocBuffers(HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize, std::vector &pBuffers) { HSAuint64 totalMB; @@ -253,57 +275,6 @@ void KFDEvictTest::AmdgpuCommandSubmissionComputeNop(int rn, amdgpu_bo_handle ha EXPECT_EQ(0, amdgpu_cs_ctx_free(contextHandle)); } -void KFDEvictTest::ForkChildProcesses(int nprocesses) { - int i; - - for (i = 0; i < nprocesses - 1; ++i) { - pid_t pid = fork(); - ASSERT_GE(pid, 0); - - if (pid == 0) { - /* Child process */ - /* Cleanup file descriptors copied from parent process - * then call SetUp->hsaKmtOpenKFD to create new process - */ - m_psName = "Test process " + std::to_string(i) + " "; - TearDown(); - SetUp(); - m_ChildPids.clear(); - m_IsParent = false; - return; - } - - /* Parent process */ - m_ChildPids.push_back(pid); - } - - m_psName = "Test process " + std::to_string(i) + " "; -} - -void KFDEvictTest::WaitChildProcesses() { - if (m_IsParent) { - /* Only run by parent process */ - int childStatus; - int childExitOkNum = 0; - int size = m_ChildPids.size(); - - for (HSAuint32 i = 0; i < size; i++) { - pid_t pid = m_ChildPids.front(); - - waitpid(pid, &childStatus, 0); - if (WIFEXITED(childStatus) == 1 && WEXITSTATUS(childStatus) == 0) - childExitOkNum++; - - m_ChildPids.erase(m_ChildPids.begin()); - } - - EXPECT_EQ(childExitOkNum, size); - } - - /* Child process or parent process finished successfully */ - m_ChildStatus = HSAKMT_STATUS_SUCCESS; -} - /* Evict and restore procedure basic test * * Use N_PROCESSES processes to allocate vram buf size larger than total vram size diff --git a/tests/kfdtest/src/KFDEvictTest.hpp b/tests/kfdtest/src/KFDEvictTest.hpp index a602980fbe..b5e7e1c3bf 100644 --- a/tests/kfdtest/src/KFDEvictTest.hpp +++ b/tests/kfdtest/src/KFDEvictTest.hpp @@ -26,31 +26,22 @@ #include #include -#include "KFDLocalMemoryTest.hpp" -#include "KFDBaseComponentTest.hpp" +#include "KFDMultiProcessTest.hpp" #include "IsaGenerator.hpp" #include "PM4Queue.hpp" // @class KFDEvictTest // Test eviction and restore procedure using two processes -class KFDEvictTest : public KFDLocalMemoryTest { +class KFDEvictTest : public KFDMultiProcessTest { public: - KFDEvictTest(void): m_ChildStatus(HSAKMT_STATUS_ERROR), m_IsParent(true) {} + KFDEvictTest(void): m_pIsaGen(NULL) {} - ~KFDEvictTest(void) { - if (!m_IsParent) { - /* Child process has to exit - * otherwise gtest will continue other tests - */ - exit(m_ChildStatus); - } - - try { - WaitChildProcesses(); - } catch (...) {} - } + ~KFDEvictTest(void) {} protected: + virtual void SetUp(); + virtual void TearDown(); + std::string CreateShader(); void AllocBuffers(HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize, std::vector &pBuffers); @@ -59,16 +50,11 @@ class KFDEvictTest : public KFDLocalMemoryTest { void FreeAmdgpuBo(amdgpu_bo_handle handle); void AmdgpuCommandSubmissionComputeNop(int rn, amdgpu_bo_handle handle, PM4Queue *computeQueue); - void ForkChildProcesses(int nprocesses); - void WaitChildProcesses(); protected: // Members - std::string m_psName; - std::vector m_ChildPids; + IsaGenerator* m_pIsaGen; HsaMemFlags m_Flags; void* m_pBuf; - HSAKMT_STATUS m_ChildStatus; - bool m_IsParent; }; #endif // __KFD_EVICT_TEST__H__ diff --git a/tests/kfdtest/src/KFDMultiProcessTest.cpp b/tests/kfdtest/src/KFDMultiProcessTest.cpp new file mode 100644 index 0000000000..2934438f28 --- /dev/null +++ b/tests/kfdtest/src/KFDMultiProcessTest.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved. + * + * 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 "KFDMultiProcessTest.hpp" + +void KFDMultiProcessTest::ForkChildProcesses(int nprocesses) { + int i; + + for (i = 0; i < nprocesses - 1; ++i) { + pid_t pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) { + /* Child process */ + /* Cleanup file descriptors copied from parent process + * then call SetUp->hsaKmtOpenKFD to create new process + */ + m_psName = "Test process " + std::to_string(i) + " "; + TearDown(); + SetUp(); + m_ChildPids.clear(); + m_IsParent = false; + m_ProcessIndex = i; + return; + } + + /* Parent process */ + m_ChildPids.push_back(pid); + } + + m_psName = "Test process " + std::to_string(i) + " "; + m_ProcessIndex = i; +} + +void KFDMultiProcessTest::WaitChildProcesses() { + if (m_IsParent) { + /* Only run by parent process */ + int childStatus; + int childExitOkNum = 0; + int size = m_ChildPids.size(); + + for (HSAuint32 i = 0; i < size; i++) { + pid_t pid = m_ChildPids.front(); + + waitpid(pid, &childStatus, 0); + if (WIFEXITED(childStatus) == 1 && WEXITSTATUS(childStatus) == 0) + childExitOkNum++; + + m_ChildPids.erase(m_ChildPids.begin()); + } + + EXPECT_EQ(childExitOkNum, size); + } + + /* Child process or parent process finished successfully */ + m_ChildStatus = HSAKMT_STATUS_SUCCESS; +} diff --git a/tests/kfdtest/src/KFDMultiProcessTest.hpp b/tests/kfdtest/src/KFDMultiProcessTest.hpp new file mode 100644 index 0000000000..3907571545 --- /dev/null +++ b/tests/kfdtest/src/KFDMultiProcessTest.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved. + * + * 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. + * + */ + +#ifndef __KFD_MULTI_PROCESS_TEST__H__ +#define __KFD_MULTI_PROCESS_TEST__H__ + +#include +#include +#include "KFDBaseComponentTest.hpp" + +// @class KFDMultiProcessTest +// Base class for tests forking multiple child processes +class KFDMultiProcessTest : public KFDBaseComponentTest { + public: + KFDMultiProcessTest(void): m_ChildStatus(HSAKMT_STATUS_ERROR), m_IsParent(true) {} + + ~KFDMultiProcessTest(void) { + if (!m_IsParent) { + /* Child process has to exit + * otherwise gtest will continue other tests + */ + exit(m_ChildStatus); + } + + try { + WaitChildProcesses(); + } catch (...) {} + } + + protected: + void ForkChildProcesses(int nprocesses); + void WaitChildProcesses(); + + protected: // Members + std::string m_psName; + int m_ProcessIndex; + std::vector m_ChildPids; + HSAKMT_STATUS m_ChildStatus; + bool m_IsParent; +}; + +#endif // __KFD_MULTI_PROCESS_TEST__H__