|
33 | 33 | #include "shared/test/common/mocks/linux/mock_os_context_linux.h" |
34 | 34 | #include "shared/test/common/mocks/mock_execution_environment.h" |
35 | 35 | #include "shared/test/common/mocks/mock_product_helper.h" |
| 36 | +#include "shared/test/common/mocks/mock_release_helper.h" |
36 | 37 | #include "shared/test/common/os_interface/linux/drm_mock_memory_info.h" |
37 | 38 | #include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h" |
38 | 39 | #include "shared/test/common/test_macros/hw_test.h" |
@@ -2949,3 +2950,113 @@ TEST(DrmTest, givenSetupHardwareInfoWhenTopologyDataHasRegionCountThenFeatureTab |
2949 | 2950 |
|
2950 | 2951 | EXPECT_EQ(2u, hwInfo->featureTable.regionCount); |
2951 | 2952 | } |
| 2953 | + |
| 2954 | +TEST(DrmTest, givenContextCreateFailsWhenSlmLimitExtensionIsPresentThenRetryWithoutIt) { |
| 2955 | + auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(); |
| 2956 | + |
| 2957 | + class DrmMockRetryContext : public DrmMock { |
| 2958 | + public: |
| 2959 | + using DrmMock::DrmMock; |
| 2960 | + int contextCreateCallCount = 0; |
| 2961 | + int failUntilCallCount = 0; |
| 2962 | + |
| 2963 | + int ioctl(DrmIoctl request, void *arg) override { |
| 2964 | + if (request == DrmIoctl::gemContextCreateExt) { |
| 2965 | + contextCreateCallCount++; |
| 2966 | + if (contextCreateCallCount <= failUntilCallCount) { |
| 2967 | + return -1; |
| 2968 | + } |
| 2969 | + } |
| 2970 | + return DrmMock::ioctl(request, arg); |
| 2971 | + } |
| 2972 | + }; |
| 2973 | + |
| 2974 | + auto mockReleaseHelper = std::make_unique<MockReleaseHelper>(); |
| 2975 | + mockReleaseHelper->isSlmLimitationTo96KNeededResult = true; |
| 2976 | + |
| 2977 | + DrmMockRetryContext drm(*executionEnvironment->rootDeviceEnvironments[0]); |
| 2978 | + executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper); |
| 2979 | + |
| 2980 | + // First call fails with SlmLimit, retry without SlmLimit succeeds |
| 2981 | + drm.failUntilCallCount = 1; |
| 2982 | + auto result = drm.createDrmContext(1, false, false); |
| 2983 | + EXPECT_GE(result, 0); |
| 2984 | + EXPECT_EQ(2, drm.contextCreateCallCount); |
| 2985 | +} |
| 2986 | + |
| 2987 | +TEST(DrmTest, givenContextCreateFailsWithAndWithoutSlmLimitThenReturnsError) { |
| 2988 | + auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(); |
| 2989 | + |
| 2990 | + class DrmMockAlwaysFail : public DrmMock { |
| 2991 | + public: |
| 2992 | + using DrmMock::DrmMock; |
| 2993 | + int contextCreateCallCount = 0; |
| 2994 | + |
| 2995 | + int ioctl(DrmIoctl request, void *arg) override { |
| 2996 | + if (request == DrmIoctl::gemContextCreateExt) { |
| 2997 | + contextCreateCallCount++; |
| 2998 | + return -1; |
| 2999 | + } |
| 3000 | + return DrmMock::ioctl(request, arg); |
| 3001 | + } |
| 3002 | + }; |
| 3003 | + |
| 3004 | + auto mockReleaseHelper = std::make_unique<MockReleaseHelper>(); |
| 3005 | + mockReleaseHelper->isSlmLimitationTo96KNeededResult = true; |
| 3006 | + |
| 3007 | + DrmMockAlwaysFail drm(*executionEnvironment->rootDeviceEnvironments[0]); |
| 3008 | + executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper); |
| 3009 | + |
| 3010 | + auto result = drm.createDrmContext(1, false, false); |
| 3011 | + EXPECT_EQ(-1, result); |
| 3012 | + EXPECT_EQ(2, drm.contextCreateCallCount); // initial + 1 retry without SlmLimit |
| 3013 | +} |
| 3014 | + |
| 3015 | +TEST(DrmTest, givenContextCreateSucceedsOnFirstTryThenNoRetry) { |
| 3016 | + auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(); |
| 3017 | + DrmMock drm(*executionEnvironment->rootDeviceEnvironments[0]); |
| 3018 | + |
| 3019 | + auto mockReleaseHelper = std::make_unique<MockReleaseHelper>(); |
| 3020 | + mockReleaseHelper->isSlmLimitationTo96KNeededResult = true; |
| 3021 | + executionEnvironment->rootDeviceEnvironments[0]->releaseHelper = std::move(mockReleaseHelper); |
| 3022 | + |
| 3023 | + drm.storedRetVal = 0; |
| 3024 | + auto result = drm.createDrmContext(1, false, false); |
| 3025 | + EXPECT_GE(result, 0); |
| 3026 | + EXPECT_EQ(1, drm.ioctlCount.contextCreate.load()); |
| 3027 | +} |
| 3028 | + |
| 3029 | +TEST(DrmTest, givenNoSlmLimitExtensionWhenContextCreateFailsThenNoRetryAndReturnError) { |
| 3030 | + auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(); |
| 3031 | + |
| 3032 | + class DrmMockAlwaysFail : public DrmMock { |
| 3033 | + public: |
| 3034 | + using DrmMock::DrmMock; |
| 3035 | + |
| 3036 | + int ioctl(DrmIoctl request, void *arg) override { |
| 3037 | + if (request == DrmIoctl::gemContextCreateExt) { |
| 3038 | + ioctlCount.contextCreate++; |
| 3039 | + return -1; |
| 3040 | + } |
| 3041 | + return DrmMock::ioctl(request, arg); |
| 3042 | + } |
| 3043 | + }; |
| 3044 | + |
| 3045 | + DrmMockAlwaysFail drm(*executionEnvironment->rootDeviceEnvironments[0]); |
| 3046 | + // no release helper -> no SLM limit extension -> no retry possible |
| 3047 | + auto result = drm.createDrmContext(1, false, false); |
| 3048 | + EXPECT_EQ(-1, result); |
| 3049 | + EXPECT_EQ(1, drm.ioctlCount.contextCreate.load()); |
| 3050 | +} |
| 3051 | + |
| 3052 | +TEST(DrmTest, givenSetSlmLimitTo96KContextParamThenCorrectValuesAreSet) { |
| 3053 | + auto executionEnvironment = std::make_unique<MockExecutionEnvironment>(); |
| 3054 | + DrmMock drm(*executionEnvironment->rootDeviceEnvironments[0]); |
| 3055 | + |
| 3056 | + GemContextCreateExtSetParam extSetparam = {}; |
| 3057 | + drm.ioctlHelper->setSlmLimitTo96KContextParam(extSetparam); |
| 3058 | + |
| 3059 | + EXPECT_EQ(static_cast<uint32_t>(I915_CONTEXT_CREATE_EXT_SETPARAM), extSetparam.base.name); |
| 3060 | + EXPECT_EQ(static_cast<uint64_t>(I915_CONTEXT_PARAM_WA_22013059131), extSetparam.param.param); |
| 3061 | + EXPECT_EQ(1u, extSetparam.param.value); |
| 3062 | +} |
0 commit comments