Skip to content

Commit a47c02e

Browse files
authored
Add lifetime handle validation to zeInitDrivers (#470)
* Previous mako generation had missed epilogue hooking for zeInitDrivers, added it into the Mako * Added Unit tests to verify Signed-off-by: Russell McGuire <russell.w.mcguire@intel.com>
1 parent 978ebe4 commit a47c02e

4 files changed

Lines changed: 107 additions & 1 deletion

File tree

scripts/templates/validation/valddi.cpp.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ return ${failure_return};
197197

198198
<%
199199
func_name = th.make_func_name(n, tags, obj)
200-
generate_post_call = re.match(r"\w+Create\w*$|\w+Get$|\w+Get\w*Exp$|\w+GetIpcHandle$|\w+GetSubDevices$", func_name)
200+
generate_post_call = re.match(r"\w+Create\w*$|\w+Get$|\w+Get\w*Exp$|\w+GetIpcHandle$|\w+GetSubDevices$|\w+InitDrivers$", func_name)
201201
%>
202202
if(context.enableHandleLifetime ){
203203
auto result = context.handleLifetime->${n}HandleLifetime.${th.make_func_name(n, tags, obj)}Prologue( \

source/layers/validation/ze_valddi.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7748,6 +7748,15 @@ namespace validation_layer
77487748
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult_zeInitDrivers(result, pCount, phDrivers, desc);
77497749
}
77507750

7751+
7752+
if( driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime ){
7753+
for (size_t i = 0; ( nullptr != phDrivers) && (i < *pCount); ++i){
7754+
if (phDrivers[i]){
7755+
context.handleLifetime->addHandle( phDrivers[i] );
7756+
context.handleLifetime->addDependent( pCount, phDrivers[i] );
7757+
}
7758+
}
7759+
}
77517760
return logAndPropagateResult_zeInitDrivers(driver_result, pCount, phDrivers, desc);
77527761
}
77537762

test/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,17 @@ set_property(TEST test_zer_validation_layer_positive_case PROPERTY ENVIRONMENT "
11301130
add_test(NAME test_zer_parameter_validation_layer_negative_case COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWhenCallingZerApiWithParameterValidationEnabledThenExpectValidationsAreTriggered)
11311131
set_property(TEST test_zer_parameter_validation_layer_negative_case PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_PARAMETER_VALIDATION=1;ZE_ENABLE_HANDLE_LIFETIME=1;ZEL_ENABLE_EVENTS_CHECKER=1;ZEL_ENABLE_BASIC_LEAK_CHECKER=1;ZEL_ENABLE_CERTIFICATION_CHECKER=1")
11321132

1133+
# Handle Lifetime Validation Tests
1134+
# Regression: zeInitDrivers must register driver handles so downstream calls succeed.
1135+
add_test(NAME test_handle_lifetime_zeInitDrivers_path COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeInitDriversThenSucceeds*)
1136+
set_property(TEST test_handle_lifetime_zeInitDrivers_path PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")
1137+
1138+
add_test(NAME test_handle_lifetime_zeDriverGet_path COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeDriverGetThenSucceeds*)
1139+
set_property(TEST test_handle_lifetime_zeDriverGet_path PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")
1140+
1141+
add_test(NAME test_handle_lifetime_null_handle_rejected COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithNullDriverHandleThenReturnsInvalidHandle*)
1142+
set_property(TEST test_handle_lifetime_null_handle_rejected PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")
1143+
11331144
# API Call Tracing Tests - Validation Layer with Trace Logging
11341145
add_test(NAME test_validation_layer_api_tracing_basic COMMAND tests --gtest_filter=ValidationLayerApiTracing.GivenValidationLayerEnabledWithTraceLevelLoggingWhenCallingBasicApisThenTracingDoesNotCrash)
11351146
set_property(TEST test_validation_layer_api_tracing_basic PROPERTY ENVIRONMENT "ZE_ENABLE_VALIDATION_LAYER=1;ZEL_ENABLE_LOADER_LOGGING=1;ZEL_LOADER_LOGGING_LEVEL=trace;ZE_ENABLE_NULL_DRIVER=1")

test/loader_validation_layer.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,3 +970,89 @@ TEST(
970970
EXPECT_EQ(ZE_RESULT_SUCCESS, zeCommandQueueDestroy(commandQueue));
971971
EXPECT_EQ(ZE_RESULT_SUCCESS, zeContextDestroy(context));
972972
}
973+
974+
///////////////////////////////////////////////////////////////////////////////
975+
// Handle Lifetime Tests
976+
//
977+
// These tests validate the ZE_ENABLE_HANDLE_LIFETIME feature of the validation
978+
// layer. Handle lifetime tracking registers handles when they are created and
979+
// validates them on every subsequent API call, returning
980+
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE for any unregistered handle.
981+
//
982+
// The tests are run as separate CTest invocations with the environment:
983+
// ZE_ENABLE_VALIDATION_LAYER=1
984+
// ZE_ENABLE_HANDLE_LIFETIME=1
985+
// ZE_ENABLE_NULL_DRIVER=1
986+
987+
// Regression test: driver handles obtained via zeInitDrivers must be registered
988+
// in the handle lifetime tracker so that subsequent API calls succeed.
989+
// Before the fix, zeInitDrivers had no handle-registration epilogue (unlike
990+
// zeDriverGet), causing zeDeviceGet to return ZE_RESULT_ERROR_INVALID_NULL_HANDLE.
991+
TEST(
992+
HandleLifetimeValidation,
993+
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeInitDriversThenSucceeds) {
994+
995+
ze_init_driver_type_desc_t driverTypeDesc = {};
996+
driverTypeDesc.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;
997+
driverTypeDesc.pNext = nullptr;
998+
driverTypeDesc.flags = UINT32_MAX;
999+
1000+
uint32_t count = 0;
1001+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, nullptr, &driverTypeDesc));
1002+
EXPECT_GT(count, 0);
1003+
1004+
std::vector<ze_driver_handle_t> drivers(count);
1005+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, drivers.data(), &driverTypeDesc));
1006+
1007+
// Regression: driver handles from zeInitDrivers must be registered with the
1008+
// handle lifetime tracker so that zeDeviceGet does not fail with
1009+
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE.
1010+
uint32_t deviceCount = 0;
1011+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, nullptr));
1012+
EXPECT_GT(deviceCount, 0);
1013+
1014+
std::vector<ze_device_handle_t> devices(deviceCount);
1015+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, devices.data()));
1016+
}
1017+
1018+
// Verify that driver handles obtained via zeDriverGet are registered correctly
1019+
// and can be used with zeDeviceGet when handle lifetime tracking is enabled.
1020+
TEST(
1021+
HandleLifetimeValidation,
1022+
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeDriverGetThenSucceeds) {
1023+
1024+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInit(ZE_INIT_FLAG_GPU_ONLY));
1025+
1026+
uint32_t driverCount = 0;
1027+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDriverGet(&driverCount, nullptr));
1028+
EXPECT_GT(driverCount, 0);
1029+
1030+
std::vector<ze_driver_handle_t> drivers(driverCount);
1031+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDriverGet(&driverCount, drivers.data()));
1032+
1033+
uint32_t deviceCount = 0;
1034+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, nullptr));
1035+
EXPECT_GT(deviceCount, 0);
1036+
1037+
std::vector<ze_device_handle_t> devices(deviceCount);
1038+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, devices.data()));
1039+
}
1040+
1041+
// Verify that calling an API with a null (unregistered) handle returns
1042+
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE when handle lifetime tracking is enabled.
1043+
TEST(
1044+
HandleLifetimeValidation,
1045+
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithNullDriverHandleThenReturnsInvalidHandle) {
1046+
1047+
ze_init_driver_type_desc_t driverTypeDesc = {};
1048+
driverTypeDesc.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;
1049+
driverTypeDesc.pNext = nullptr;
1050+
driverTypeDesc.flags = UINT32_MAX;
1051+
1052+
uint32_t count = 0;
1053+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, nullptr, &driverTypeDesc));
1054+
1055+
// A null handle is never registered; the handle lifetime checker must reject it.
1056+
uint32_t deviceCount = 0;
1057+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_HANDLE, zeDeviceGet(nullptr, &deviceCount, nullptr));
1058+
}

0 commit comments

Comments
 (0)