kfdtest: Add KFDQMTest UserQueueBufValidation
Create CP queue and SDMA queue should fail with invalid queue ring buffer or ring buffer size. Test unmap or free queue buffers should fail before queue is destroyed. Use child process to test unmap CWSR buffer will evict queue. Signed-off-by: Philip Yang <Philip.Yang@amd.com> Change-Id: I5dcd51d6b43445d19a986f8b0b82063e20348a5f
This commit is contained in:
committed by
Yang, Philip
parent
3e6f51b715
commit
bd86fb1e63
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <mutex>
|
||||
@@ -2648,3 +2649,166 @@ TEST_F(KFDQMTest, GPUDoorbellWrite) {
|
||||
|
||||
TEST_END
|
||||
}
|
||||
|
||||
TEST_F(KFDQMTest, UserQueueBufValidation) {
|
||||
TEST_START(TESTPROFILE_RUNALL)
|
||||
|
||||
int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();
|
||||
ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node";
|
||||
|
||||
HsaQueueResource QueueResources;
|
||||
HsaMemoryBuffer *QueueBuf;
|
||||
HSAKMT_STATUS status;
|
||||
|
||||
memset(&QueueResources, 0, sizeof(QueueResources));
|
||||
|
||||
// System memory mapping on GPU
|
||||
QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);
|
||||
|
||||
EXPECT_SUCCESS(hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_COMPUTE,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
QueueBuf->As<unsigned int*>(),
|
||||
PAGE_SIZE,
|
||||
NULL,
|
||||
&QueueResources));
|
||||
EXPECT_SUCCESS(hsaKmtDestroyQueue(QueueResources.QueueId));
|
||||
|
||||
// CP Queue creation should fail using wrong ring buffer size
|
||||
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_COMPUTE,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
QueueBuf->As<unsigned int*>(),
|
||||
PAGE_SIZE * 2,
|
||||
NULL,
|
||||
&QueueResources));
|
||||
|
||||
// SDMA queue create should fail using wrong ring buffer size
|
||||
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_SDMA,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
QueueBuf->As<unsigned int*>(),
|
||||
PAGE_SIZE * 2,
|
||||
NULL,
|
||||
&QueueResources));
|
||||
|
||||
// CP queue create should fail using NULL ring buffer
|
||||
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_COMPUTE,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
NULL,
|
||||
PAGE_SIZE,
|
||||
NULL,
|
||||
&QueueResources));
|
||||
|
||||
// SDMA queue create should fail using NULL ring buffer
|
||||
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_SDMA,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
NULL,
|
||||
PAGE_SIZE,
|
||||
NULL,
|
||||
&QueueResources));
|
||||
|
||||
EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>()));
|
||||
EXPECT_SUCCESS(hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE));
|
||||
|
||||
//
|
||||
// This following negative test will evict user queues, must execute in child process,
|
||||
// because parent process is allowed to create queue to run the remaining tests.
|
||||
//
|
||||
pid_t childPid = fork();
|
||||
|
||||
if (childPid == 0) { /* Child process */
|
||||
void *cwsr_addr;
|
||||
int exit_code = 1;
|
||||
|
||||
TearDown();
|
||||
SetUp();
|
||||
|
||||
// System memory mapping on GPU
|
||||
QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);
|
||||
memset(&QueueResources, 0, sizeof(QueueResources));
|
||||
|
||||
status = hsaKmtCreateQueue(defaultGPUNode,
|
||||
HSA_QUEUE_COMPUTE,
|
||||
100,
|
||||
HSA_QUEUE_PRIORITY_NORMAL,
|
||||
QueueBuf->As<unsigned int*>(),
|
||||
PAGE_SIZE,
|
||||
NULL,
|
||||
&QueueResources);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "create queue failed." << std::endl;
|
||||
goto free_exit;
|
||||
}
|
||||
|
||||
// Update queue percentage 0 to set queue inactive in order to get queue info CWSR area
|
||||
status = hsaKmtUpdateQueue(QueueResources.QueueId, 0, HSA_QUEUE_PRIORITY_NORMAL,
|
||||
QueueBuf->As<unsigned int*>(), PAGE_SIZE, NULL);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "update queue failed." << std::endl;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
HsaQueueInfo QueueInfo;
|
||||
status = hsaKmtGetQueueInfo(QueueResources.QueueId, &QueueInfo);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "get queue info failed." << std::endl;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
// unmap CWSR buffer will evict queue before queue is destroyed
|
||||
cwsr_addr = QueueInfo.UserContextSaveArea;
|
||||
munmap(cwsr_addr, PAGE_SIZE);
|
||||
|
||||
// unmap and free queue ring buffer should fail before the queue is destroyed
|
||||
status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);
|
||||
if (status == HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "free queue buf should fail." << std::endl;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());
|
||||
if (status == HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "unmap queue buf should fail." << std::endl;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
exit_code = 0;
|
||||
|
||||
err_exit:
|
||||
status = hsaKmtDestroyQueue(QueueResources.QueueId);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "destroy queue failed." << std::endl;
|
||||
exit_code = 1;
|
||||
}
|
||||
free_exit:
|
||||
status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "unmap queue buf failed." << std::endl;
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) {
|
||||
LOG() << "free queue buf failed." << std::endl;
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
exit(exit_code);
|
||||
} else {
|
||||
int childStatus;
|
||||
|
||||
waitpid(childPid, &childStatus, 0);
|
||||
EXPECT_EQ(true, WIFEXITED(childStatus));
|
||||
EXPECT_EQ(0, WEXITSTATUS(childStatus));
|
||||
}
|
||||
|
||||
TEST_END
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user