feature: add main lock for both execute and flush

- both execute and flush have their own locks
- spliting these locks makes race condition
- obtain lock at higher level
- do not lock in queue when calling execute from immediate
- pass main lock to flush so can be unlocked before synchronize

Related-To: NEO-10356

Signed-off-by: Zbigniew Zdanowicz <zbigniew.zdanowicz@intel.com>
This commit is contained in:
Zbigniew Zdanowicz 2025-03-05 02:00:57 +00:00 committed by Compute-Runtime-Automation
parent 4c795027e3
commit 566e52f72b
4 changed files with 18 additions and 5 deletions

View File

@ -424,7 +424,7 @@ inline ze_result_t CommandListCoreFamilyImmediate<gfxCoreFamily>::executeCommand
size_t commandStreamStart = this->cmdListCurrentStartOffset;
auto csr = static_cast<CommandQueueImp *>(cmdQ)->getCsr();
auto lockCSR = csr->obtainUniqueOwnership();
auto lockCSR = outerLock != nullptr ? std::move(*outerLock) : csr->obtainUniqueOwnership();
if (NEO::ApiSpecificConfig::isSharedAllocPrefetchEnabled()) {
auto svmAllocMgr = this->device->getDriverHandle()->getSvmAllocsManager();
@ -1685,8 +1685,8 @@ ze_result_t CommandListCoreFamilyImmediate<gfxCoreFamily>::appendCommandLists(ui
return ret;
}
auto cmdQueue = this->cmdQImmediate;
ret = cmdQueue->executeCommandLists(numCommandLists, phCommandLists, nullptr, true, this->commandContainer.getCommandStream());
auto mainAppendLock = static_cast<CommandQueueImp *>(this->cmdQImmediate)->getCsr()->obtainUniqueOwnership();
ret = this->cmdQImmediate->executeCommandLists(numCommandLists, phCommandLists, nullptr, true, this->commandContainer.getCommandStream());
if (ret != ZE_RESULT_SUCCESS) {
return ret;
}
@ -1701,7 +1701,7 @@ ze_result_t CommandListCoreFamilyImmediate<gfxCoreFamily>::appendCommandLists(ui
}
bool hasStallingCmds = true;
return flushImmediate(ret, true, hasStallingCmds, relaxedOrderingDispatch, NEO::AppendOperations::kernel, false, hSignalEvent, true, nullptr);
return flushImmediate(ret, true, hasStallingCmds, relaxedOrderingDispatch, NEO::AppendOperations::kernel, false, hSignalEvent, true, &mainAppendLock);
}
} // namespace L0

View File

@ -73,11 +73,12 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandLists(
this->csr->ensurePrimaryCsrInitialized(*this->device->getNEODevice());
}
auto lockCSR = this->csr->obtainUniqueOwnership();
std::unique_lock<NEO::CommandStreamReceiver::MutexType> lockCSR;
if (parentImmediateCommandlistLinearStream != nullptr) {
this->startingCmdBuffer = parentImmediateCommandlistLinearStream;
} else {
lockCSR = this->csr->obtainUniqueOwnership();
this->startingCmdBuffer = &this->commandStream;
}

View File

@ -1567,12 +1567,19 @@ HWTEST2_F(ImmediateCommandListTest, givenImmediateCmdListWhenAppendingRegularThe
commandList->close();
auto cmdListHandle = commandList->toHandle();
auto &ultCsr = neoDevice->getUltCommandStreamReceiver<FamilyType>();
ultCsr.recursiveLockCounter = 0;
// first append can carry preamble
commandListImmediate->appendCommandLists(1, &cmdListHandle, nullptr, 0, nullptr);
EXPECT_EQ(1u, ultCsr.recursiveLockCounter);
// regular append can dispatch bb_start to secondary regular or primary directly regular
commandListImmediate->appendCommandLists(1, &cmdListHandle, nullptr, 0, nullptr);
EXPECT_EQ(2u, ultCsr.recursiveLockCounter);
auto startStream = static_cast<L0::CommandQueueImp *>(commandListImmediate->cmdQImmediate)->getStartingCmdBuffer();
if (commandListImmediate->getCmdListBatchBufferFlag()) {

View File

@ -1379,9 +1379,14 @@ HWTEST2_F(ExecuteCommandListTests, givenSuccessfulSubmitBatchBufferThenExecuteCo
auto commandListHandle = commandList->toHandle();
commandList->close();
auto &ultCsr = neoDevice->getUltCommandStreamReceiver<FamilyType>();
ultCsr.recursiveLockCounter = 0;
auto res = commandQueue->executeCommandLists(1, &commandListHandle, nullptr, false, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
EXPECT_EQ(1u, ultCsr.recursiveLockCounter);
commandQueue->destroy();
commandList->destroy();
}