Skip to content

Commit 4ac71d1

Browse files
committed
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 [ROCm/ROCR-Runtime commit: bd86fb1]
1 parent 5088631 commit 4ac71d1

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDQMTest.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
#include <sys/time.h>
25+
#include <sys/mman.h>
2526
#include <vector>
2627
#include <utility>
2728
#include <mutex>
@@ -2648,3 +2649,166 @@ TEST_F(KFDQMTest, GPUDoorbellWrite) {
26482649

26492650
TEST_END
26502651
}
2652+
2653+
TEST_F(KFDQMTest, UserQueueBufValidation) {
2654+
TEST_START(TESTPROFILE_RUNALL)
2655+
2656+
int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();
2657+
ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node";
2658+
2659+
HsaQueueResource QueueResources;
2660+
HsaMemoryBuffer *QueueBuf;
2661+
HSAKMT_STATUS status;
2662+
2663+
memset(&QueueResources, 0, sizeof(QueueResources));
2664+
2665+
// System memory mapping on GPU
2666+
QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);
2667+
2668+
EXPECT_SUCCESS(hsaKmtCreateQueue(defaultGPUNode,
2669+
HSA_QUEUE_COMPUTE,
2670+
100,
2671+
HSA_QUEUE_PRIORITY_NORMAL,
2672+
QueueBuf->As<unsigned int*>(),
2673+
PAGE_SIZE,
2674+
NULL,
2675+
&QueueResources));
2676+
EXPECT_SUCCESS(hsaKmtDestroyQueue(QueueResources.QueueId));
2677+
2678+
// CP Queue creation should fail using wrong ring buffer size
2679+
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
2680+
HSA_QUEUE_COMPUTE,
2681+
100,
2682+
HSA_QUEUE_PRIORITY_NORMAL,
2683+
QueueBuf->As<unsigned int*>(),
2684+
PAGE_SIZE * 2,
2685+
NULL,
2686+
&QueueResources));
2687+
2688+
// SDMA queue create should fail using wrong ring buffer size
2689+
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
2690+
HSA_QUEUE_SDMA,
2691+
100,
2692+
HSA_QUEUE_PRIORITY_NORMAL,
2693+
QueueBuf->As<unsigned int*>(),
2694+
PAGE_SIZE * 2,
2695+
NULL,
2696+
&QueueResources));
2697+
2698+
// CP queue create should fail using NULL ring buffer
2699+
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
2700+
HSA_QUEUE_COMPUTE,
2701+
100,
2702+
HSA_QUEUE_PRIORITY_NORMAL,
2703+
NULL,
2704+
PAGE_SIZE,
2705+
NULL,
2706+
&QueueResources));
2707+
2708+
// SDMA queue create should fail using NULL ring buffer
2709+
EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,
2710+
HSA_QUEUE_SDMA,
2711+
100,
2712+
HSA_QUEUE_PRIORITY_NORMAL,
2713+
NULL,
2714+
PAGE_SIZE,
2715+
NULL,
2716+
&QueueResources));
2717+
2718+
EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>()));
2719+
EXPECT_SUCCESS(hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE));
2720+
2721+
//
2722+
// This following negative test will evict user queues, must execute in child process,
2723+
// because parent process is allowed to create queue to run the remaining tests.
2724+
//
2725+
pid_t childPid = fork();
2726+
2727+
if (childPid == 0) { /* Child process */
2728+
void *cwsr_addr;
2729+
int exit_code = 1;
2730+
2731+
TearDown();
2732+
SetUp();
2733+
2734+
// System memory mapping on GPU
2735+
QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);
2736+
memset(&QueueResources, 0, sizeof(QueueResources));
2737+
2738+
status = hsaKmtCreateQueue(defaultGPUNode,
2739+
HSA_QUEUE_COMPUTE,
2740+
100,
2741+
HSA_QUEUE_PRIORITY_NORMAL,
2742+
QueueBuf->As<unsigned int*>(),
2743+
PAGE_SIZE,
2744+
NULL,
2745+
&QueueResources);
2746+
if (status != HSAKMT_STATUS_SUCCESS) {
2747+
LOG() << "create queue failed." << std::endl;
2748+
goto free_exit;
2749+
}
2750+
2751+
// Update queue percentage 0 to set queue inactive in order to get queue info CWSR area
2752+
status = hsaKmtUpdateQueue(QueueResources.QueueId, 0, HSA_QUEUE_PRIORITY_NORMAL,
2753+
QueueBuf->As<unsigned int*>(), PAGE_SIZE, NULL);
2754+
if (status != HSAKMT_STATUS_SUCCESS) {
2755+
LOG() << "update queue failed." << std::endl;
2756+
goto err_exit;
2757+
}
2758+
2759+
HsaQueueInfo QueueInfo;
2760+
status = hsaKmtGetQueueInfo(QueueResources.QueueId, &QueueInfo);
2761+
if (status != HSAKMT_STATUS_SUCCESS) {
2762+
LOG() << "get queue info failed." << std::endl;
2763+
goto err_exit;
2764+
}
2765+
2766+
// unmap CWSR buffer will evict queue before queue is destroyed
2767+
cwsr_addr = QueueInfo.UserContextSaveArea;
2768+
munmap(cwsr_addr, PAGE_SIZE);
2769+
2770+
// unmap and free queue ring buffer should fail before the queue is destroyed
2771+
status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);
2772+
if (status == HSAKMT_STATUS_SUCCESS) {
2773+
LOG() << "free queue buf should fail." << std::endl;
2774+
goto err_exit;
2775+
}
2776+
2777+
status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());
2778+
if (status == HSAKMT_STATUS_SUCCESS) {
2779+
LOG() << "unmap queue buf should fail." << std::endl;
2780+
goto err_exit;
2781+
}
2782+
2783+
exit_code = 0;
2784+
2785+
err_exit:
2786+
status = hsaKmtDestroyQueue(QueueResources.QueueId);
2787+
if (status != HSAKMT_STATUS_SUCCESS) {
2788+
LOG() << "destroy queue failed." << std::endl;
2789+
exit_code = 1;
2790+
}
2791+
free_exit:
2792+
status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());
2793+
if (status != HSAKMT_STATUS_SUCCESS) {
2794+
LOG() << "unmap queue buf failed." << std::endl;
2795+
exit_code = 1;
2796+
}
2797+
2798+
status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);
2799+
if (status != HSAKMT_STATUS_SUCCESS) {
2800+
LOG() << "free queue buf failed." << std::endl;
2801+
exit_code = 1;
2802+
}
2803+
2804+
exit(exit_code);
2805+
} else {
2806+
int childStatus;
2807+
2808+
waitpid(childPid, &childStatus, 0);
2809+
EXPECT_EQ(true, WIFEXITED(childStatus));
2810+
EXPECT_EQ(0, WEXITSTATUS(childStatus));
2811+
}
2812+
2813+
TEST_END
2814+
}

0 commit comments

Comments
 (0)