fix: return error when not closed command list is executed

Related-To: NEO-10356

Signed-off-by: Zbigniew Zdanowicz <zbigniew.zdanowicz@intel.com>
This commit is contained in:
Zbigniew Zdanowicz 2025-04-02 11:50:40 +00:00 committed by Compute-Runtime-Automation
parent bb3927531e
commit f578dc0316
8 changed files with 87 additions and 17 deletions

View File

@ -410,6 +410,10 @@ struct CommandList : _ze_command_list_handle_t {
return localDispatchSupport;
}
bool isClosed() const {
return closedCmdList;
}
protected:
NEO::GraphicsAllocation *getAllocationFromHostPtrMap(const void *buffer, uint64_t bufferSize, bool copyOffload);
NEO::GraphicsAllocation *getHostPtrAlloc(const void *buffer, uint64_t bufferSize, bool hostCopyAllowed, bool copyOffload);
@ -504,6 +508,7 @@ struct CommandList : _ze_command_list_handle_t {
bool localDispatchSupport = false;
bool copyOperationOffloadEnabled = false;
bool l3FlushAfterPostSyncRequired = false;
bool closedCmdList = false;
};
using CommandListAllocatorFn = CommandList *(*)(uint32_t);

View File

@ -153,6 +153,7 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::reset() {
latestOperationRequiredNonWalkerInOrderCmdsChaining = false;
taskCountUpdateFenceRequired = false;
closedCmdList = false;
this->inOrderPatchCmds.clear();
@ -375,6 +376,7 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::close() {
} else {
NEO::EncodeBatchBufferStartOrEnd<GfxFamily>::programBatchBufferEnd(commandContainer);
}
closedCmdList = true;
return ZE_RESULT_SUCCESS;
}

View File

@ -132,11 +132,11 @@ struct CommandQueueHw : public CommandQueueImp {
inline size_t computePreemptionSizeForCommandList(CommandListExecutionContext &ctx,
CommandList *commandList,
bool &dirtyState);
inline void setupCmdListsAndContextParams(CommandListExecutionContext &ctx,
ze_command_list_handle_t *phCommandLists,
uint32_t numCommandLists,
ze_fence_handle_t hFence,
NEO::LinearStream *parentImmediateCommandlistLinearStream);
inline ze_result_t setupCmdListsAndContextParams(CommandListExecutionContext &ctx,
ze_command_list_handle_t *phCommandLists,
uint32_t numCommandLists,
ze_fence_handle_t hFence,
NEO::LinearStream *parentImmediateCommandlistLinearStream);
MOCKABLE_VIRTUAL bool isDispatchTaskCountPostSyncRequired(ze_fence_handle_t hFence, bool containsAnyRegularCmdList, bool containsParentImmediateStream) const;
inline size_t estimateLinearStreamSizeInitial(CommandListExecutionContext &ctx);
size_t estimateStreamSizeForExecuteCommandListsRegularHeapless(CommandListExecutionContext &ctx,

View File

@ -143,7 +143,10 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsRegularHeapless(
auto neoDevice = this->device->getNEODevice();
this->csr->initializeDeviceWithFirstSubmission(*neoDevice);
this->setupCmdListsAndContextParams(ctx, commandListHandles, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
ze_result_t retVal = this->setupCmdListsAndContextParams(ctx, commandListHandles, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
if (retVal != ZE_RESULT_SUCCESS) {
return retVal;
}
ctx.isDirectSubmissionEnabled = this->csr->isDirectSubmissionEnabled();
bool instructionCacheFlushRequired = this->csr->isInstructionCacheFlushRequired();
bool stateCacheFlushRequired = neoDevice->getBindlessHeapsHelper() ? neoDevice->getBindlessHeapsHelper()->getStateDirtyForContext(this->csr->getOsContext().getContextId()) : false;
@ -228,7 +231,7 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsRegularHeapless(
if (!parentImmediateCommandlistLinearStream) {
completionResult = this->waitForCommandQueueCompletionAndCleanHeapContainer();
}
ze_result_t retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
if (!parentImmediateCommandlistLinearStream) {
this->csr->getResidencyAllocations().clear();
@ -288,7 +291,10 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsRegular(
ze_fence_handle_t hFence,
NEO::LinearStream *parentImmediateCommandlistLinearStream) {
this->setupCmdListsAndContextParams(ctx, commandListHandles, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
ze_result_t retVal = this->setupCmdListsAndContextParams(ctx, commandListHandles, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
if (retVal != ZE_RESULT_SUCCESS) {
return retVal;
}
ctx.isDirectSubmissionEnabled = this->csr->isDirectSubmissionEnabled();
std::unique_lock<std::mutex> lockForIndirect;
@ -453,7 +459,7 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsRegular(
if (!parentImmediateCommandlistLinearStream) {
completionResult = this->waitForCommandQueueCompletionAndCleanHeapContainer();
}
ze_result_t retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
if (!parentImmediateCommandlistLinearStream) {
this->csr->getResidencyAllocations().clear();
@ -472,7 +478,10 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsCopyOnly(
ze_fence_handle_t hFence,
NEO::LinearStream *parentImmediateCommandlistLinearStream) {
this->setupCmdListsAndContextParams(ctx, phCommandLists, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
ze_result_t retVal = this->setupCmdListsAndContextParams(ctx, phCommandLists, numCommandLists, hFence, parentImmediateCommandlistLinearStream);
if (retVal != ZE_RESULT_SUCCESS) {
return retVal;
}
ctx.isDirectSubmissionEnabled = this->csr->isBlitterDirectSubmissionEnabled();
size_t linearStreamSizeEstimate = this->estimateLinearStreamSizeInitial(ctx);
@ -541,7 +550,7 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandListsCopyOnly(
if (!parentImmediateCommandlistLinearStream) {
completionResult = this->waitForCommandQueueCompletionAndCleanHeapContainer();
}
ze_result_t retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
retVal = this->handleSubmissionAndCompletionResults(submitResult, completionResult);
if (!parentImmediateCommandlistLinearStream) {
this->csr->getResidencyAllocations().clear();
@ -777,7 +786,7 @@ size_t CommandQueueHw<gfxCoreFamily>::computePreemptionSizeForCommandList(
}
template <GFXCORE_FAMILY gfxCoreFamily>
void CommandQueueHw<gfxCoreFamily>::setupCmdListsAndContextParams(
ze_result_t CommandQueueHw<gfxCoreFamily>::setupCmdListsAndContextParams(
CommandListExecutionContext &ctx,
ze_command_list_handle_t *phCommandLists,
uint32_t numCommandLists,
@ -788,6 +797,9 @@ void CommandQueueHw<gfxCoreFamily>::setupCmdListsAndContextParams(
for (auto i = 0u; i < numCommandLists; i++) {
auto commandList = static_cast<CommandListImp *>(CommandList::fromHandle(phCommandLists[i]));
if (!commandList->isClosed()) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
commandList->storeReferenceTsToMappedEvents(false);
commandList->addRegularCmdListSubmissionCounter();
commandList->patchInOrderCmds();
@ -845,6 +857,8 @@ void CommandQueueHw<gfxCoreFamily>::setupCmdListsAndContextParams(
}
ctx.isDispatchTaskCountPostSyncRequired = isDispatchTaskCountPostSyncRequired(hFence, ctx.containsAnyRegularCmdList,
ctx.containsParentImmediateStream);
return ZE_RESULT_SUCCESS;
}
template <GFXCORE_FAMILY gfxCoreFamily>

View File

@ -48,6 +48,7 @@ struct WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>
using BaseClass::appendWriteKernelTimestamp;
using BaseClass::applyMemoryRangesBarrier;
using BaseClass::clearCommandsToPatch;
using BaseClass::closedCmdList;
using BaseClass::cmdListHeapAddressModel;
using BaseClass::cmdListType;
using BaseClass::cmdQImmediate;
@ -189,6 +190,7 @@ struct WhiteBox<L0::CommandListCoreFamilyImmediate<gfxCoreFamily>>
using BaseClass::appendLaunchKernelWithParams;
using BaseClass::appendMemoryCopyBlitRegion;
using BaseClass::clearCommandsToPatch;
using BaseClass::closedCmdList;
using BaseClass::cmdListHeapAddressModel;
using BaseClass::cmdListType;
using BaseClass::cmdQImmediate;
@ -281,6 +283,7 @@ template <>
struct WhiteBox<::L0::CommandListImp> : public ::L0::CommandListImp {
using BaseClass = ::L0::CommandListImp;
using BaseClass::BaseClass;
using BaseClass::closedCmdList;
using BaseClass::cmdListHeapAddressModel;
using BaseClass::cmdListType;
using BaseClass::cmdQImmediate;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -47,6 +47,9 @@ struct CommandQueueExecuteCommandListsFixture : DeviceFixture {
auto commandList = CommandList::fromHandle(commandLists[0]);
this->heaplessStateInit = commandList->isHeaplessStateInitEnabled();
commandList->close();
CommandList::fromHandle(commandLists[1])->close();
}
void tearDown() {
@ -92,11 +95,13 @@ struct MultiDeviceCommandQueueExecuteCommandListsFixture : public MultiDeviceFix
ASSERT_NE(nullptr, commandLists[0]);
EXPECT_EQ(ZE_RESULT_SUCCESS, returnValue);
EXPECT_EQ(2u, CommandList::fromHandle(commandLists[0])->getPartitionCount());
CommandList::fromHandle(commandLists[0])->close();
commandLists[1] = CommandList::create(productFamily, device, NEO::EngineGroupType::renderCompute, 0u, returnValue, false)->toHandle();
ASSERT_NE(nullptr, commandLists[1]);
EXPECT_EQ(ZE_RESULT_SUCCESS, returnValue);
EXPECT_EQ(2u, CommandList::fromHandle(commandLists[1])->getPartitionCount());
CommandList::fromHandle(commandLists[1])->close();
}
void tearDown() {
@ -355,6 +360,9 @@ HWTEST2_F(CommandQueueExecuteCommandLists, givenCommandQueueHaving2CommandListsT
ASSERT_NE(nullptr, commandQueue);
usedSpaceBefore = commandQueue->commandStream.getUsed();
CommandList::fromHandle(commandLists[0])->close();
CommandList::fromHandle(commandLists[1])->close();
result = commandQueue->executeCommandLists(numCommandLists, commandLists, nullptr, true, nullptr);
ASSERT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(2048u, neoDevice->getDefaultEngine().commandStreamReceiver->getScratchSpaceController()->getPerThreadScratchSpaceSizeSlot0());
@ -556,6 +564,7 @@ HWTEST2_F(CommandQueueExecuteCommandListsImplicitScalingDisabled, givenCommandLi
CmdListKernelLaunchParams launchParams = {};
launchParams.isCooperative = true;
pCommandListWithCooperativeKernels->appendLaunchKernelWithParams(&kernel, threadGroupDimensions, nullptr, launchParams);
pCommandListWithCooperativeKernels->close();
ze_command_list_handle_t commandListCooperative[] = {pCommandListWithCooperativeKernels->toHandle()};
auto result = pCommandQueue->executeCommandLists(1, commandListCooperative, nullptr, false, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -566,6 +575,7 @@ HWTEST2_F(CommandQueueExecuteCommandListsImplicitScalingDisabled, givenCommandLi
launchParams.isCooperative = false;
pCommandListWithNonCooperativeKernels->appendLaunchKernelWithParams(&kernel, threadGroupDimensions, nullptr, launchParams);
pCommandListWithNonCooperativeKernels->close();
ze_command_list_handle_t commandListNonCooperative[] = {pCommandListWithNonCooperativeKernels->toHandle()};
result = pCommandQueue->executeCommandLists(1, commandListNonCooperative, nullptr, false, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@ -593,9 +603,11 @@ void CommandQueueExecuteCommandListsFixture::twoCommandListCommandPreemptionTest
auto commandListDisabled = CommandList::whiteboxCast(CommandList::create(productFamily, device, NEO::EngineGroupType::renderCompute, 0u, returnValue, false));
commandListDisabled->commandListPreemptionMode = NEO::PreemptionMode::Disabled;
commandListDisabled->close();
auto commandListThreadGroup = CommandList::whiteboxCast(CommandList::create(productFamily, device, NEO::EngineGroupType::renderCompute, 0u, returnValue, false));
commandListThreadGroup->commandListPreemptionMode = NEO::PreemptionMode::ThreadGroup;
commandListThreadGroup->close();
ze_command_list_handle_t commandLists[] = {commandListDisabled->toHandle(),
commandListThreadGroup->toHandle(),
@ -900,6 +912,7 @@ HWTEST_F(CommandQueueExecuteCommandLists, GivenCopyCommandQueueWhenExecutingCopy
ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue);
EXPECT_TRUE(commandQueue->peekIsCopyOnlyCommandQueue());
commandList->close();
zet_command_list_handle_t cmdListHandle = commandList->toHandle();
returnValue = commandQueue->executeCommandLists(1, &cmdListHandle, nullptr, false, nullptr);
ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue);
@ -934,9 +947,11 @@ struct CommandQueueExecuteCommandListSWTagsTestsFixture : public DeviceFixture {
DeviceFixture::setUp();
ze_result_t returnValue;
commandLists[0] = CommandList::create(productFamily, device, NEO::EngineGroupType::renderCompute, 0u, returnValue, false)->toHandle();
auto cmdList = CommandList::create(productFamily, device, NEO::EngineGroupType::renderCompute, 0u, returnValue, false);
commandLists[0] = cmdList->toHandle();
ASSERT_NE(nullptr, commandLists[0]);
EXPECT_EQ(ZE_RESULT_SUCCESS, returnValue);
cmdList->close();
ze_command_queue_desc_t desc = {};
commandQueue = whiteboxCast(CommandQueue::create(productFamily,
@ -1194,6 +1209,7 @@ HWTEST_F(CommandQueueExecuteCommandLists, GivenUpdateTaskCountFromWaitWhenExecut
ASSERT_NE(nullptr, fence);
ze_fence_handle_t fenceHandle = fence->toHandle();
commandList->close();
zet_command_list_handle_t cmdListHandle = commandList->toHandle();
returnValue = commandQueue->executeCommandLists(1, &cmdListHandle, fenceHandle, false, nullptr);
ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue);
@ -1248,6 +1264,7 @@ HWTEST_F(CommandQueueExecuteCommandLists, GivenCopyCommandQueueWhenExecutingCopy
ze_fence_handle_t fenceHandle = fence->toHandle();
zet_command_list_handle_t cmdListHandle = commandList->toHandle();
commandList->close();
returnValue = commandQueue->executeCommandLists(1, &cmdListHandle, fenceHandle, false, nullptr);
ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue);
size_t usedSpaceAfter = commandQueue->commandStream.getUsed();

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -919,5 +919,33 @@ HWTEST_F(CommandQueueExecuteCommandListsMultiDeviceTest, GivenDirtyFlagForContex
commandQueue->destroy();
}
HWTEST_F(CommandQueueExecuteCommandListsSimpleTest, givenRegularCommandListNotClosedWhenExecutingCommandListThenReturnError) {
ze_command_queue_desc_t queueDesc = {};
ze_result_t returnValue = ZE_RESULT_SUCCESS;
auto commandQueue = whiteboxCast(CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false, false, false, returnValue));
ASSERT_NE(nullptr, commandQueue);
auto engineGroupType = neoDevice->getGfxCoreHelper().getEngineGroupType(neoDevice->getDefaultEngine().getEngineType(),
neoDevice->getDefaultEngine().getEngineUsage(), neoDevice->getHardwareInfo());
auto commandList = CommandList::create(productFamily, device, engineGroupType, 0u, returnValue, false);
ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue);
EXPECT_FALSE(commandList->isClosed());
auto commandListHandle = commandList->toHandle();
returnValue = commandQueue->executeCommandLists(1, &commandListHandle, nullptr, true, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, returnValue);
commandList->close();
EXPECT_TRUE(commandList->isClosed());
commandList->reset();
EXPECT_FALSE(commandList->isClosed());
commandList->destroy();
commandQueue->destroy();
}
} // namespace ult
} // namespace L0

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -561,7 +561,8 @@ HWTEST2_P(L0DebuggerWithBlitterTest, givenDebuggingEnabledWhenInternalCmdQIsUsed
ze_command_list_handle_t commandLists[] = {
CommandList::createImmediate(productFamily, device, &queueDesc, true, NEO::EngineGroupType::renderCompute, returnValue)->toHandle()};
uint32_t numCommandLists = sizeof(commandLists) / sizeof(commandLists[0]);
auto commandList = CommandList::fromHandle(commandLists[0]);
auto commandList = whiteboxCast(static_cast<L0::CommandListImp *>(CommandList::fromHandle(commandLists[0])));
commandList->closedCmdList = true;
auto result = commandQueue->executeCommandLists(numCommandLists, commandLists, nullptr, true, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);