已合并
fix: 修复event sync不准确问题,sqhead-1位置读到新下发任务id #4530
fix: 修复event sync不准确问题,sqhead-1位置读到新下发任务id #4530
已合并
王璐瑶创建于 6 天前
3 个文件变更+31-8
@@ -1808,11 +1808,12 @@ rtError_t Stream::GetFinishedTaskIdBySqHead(uint16_t &sqHead, uint32_t &finished
1808 (((flags_ & RT_STREAM_HUGE) != 0U) && (device_->GetDevProperties().maxTaskNumPerHugeStream != 0)) ?1808 (((flags_ & RT_STREAM_HUGE) != 0U) && (device_->GetDevProperties().maxTaskNumPerHugeStream != 0)) ?
1809 device_->GetDevProperties().maxTaskNumPerHugeStream :1809 device_->GetDevProperties().maxTaskNumPerHugeStream :
1810 device_->GetDevProperties().rtsqDepth;1810 device_->GetDevProperties().rtsqDepth;
1811+ const uint16_t lastId = lastTaskId_;
1811 const uint32_t posTail = GetTaskPosTail();1812 const uint32_t posTail = GetTaskPosTail();
1812 const uint32_t posHead = GetTaskPosHead();1813 const uint32_t posHead = GetTaskPosHead();
1813- rtError_t error = device_->Driver_()->GetSqHead(Device_()->Id_(), Device_()->DevGetTsId(), sqId_, sqHead);1814+ rtError_t error = device_->Driver_()->GetSqHead(device_->Id_(), device_->DevGetTsId(), sqId_, sqHead);
1814- COND_RETURN_ERROR(error != RT_ERROR_NONE, error, "Query sq head failed, retCode=%#x.",1815+ COND_RETURN_ERROR(
1815- static_cast<uint32_t>(error));1816+ error != RT_ERROR_NONE, error, "Query sq head failed, retCode=%#x.", static_cast<uint32_t>(error));
1816 if (((posTail + rtsqDepth - sqHead) % rtsqDepth) >= (posTail + rtsqDepth - posHead) % rtsqDepth) {1817 if (((posTail + rtsqDepth - sqHead) % rtsqDepth) >= (posTail + rtsqDepth - posHead) % rtsqDepth) {
1817 return RT_ERROR_NONE;1818 return RT_ERROR_NONE;
1818 }1819 }
@@ -1822,12 +1823,26 @@ rtError_t Stream::GetFinishedTaskIdBySqHead(uint16_t &sqHead, uint32_t &finished
1822 1823 
1823 const uint16_t finishedPos = static_cast<uint16_t>((sqHead + rtsqDepth - 1) % rtsqDepth);1824 const uint16_t finishedPos = static_cast<uint16_t>((sqHead + rtsqDepth - 1) % rtsqDepth);
1824 (void)GetTaskIdByPos(finishedPos, endTaskId); // sqhead-1 is finished pos.1825 (void)GetTaskIdByPos(finishedPos, endTaskId); // sqhead-1 is finished pos.
1826+ const uint32_t reReadPosTail = GetTaskPosTail();
1827+ // tail未变化但最新任务已变化,说明本次读取的taskId可能属于新下发任务。
1828+ if (reReadPosTail == posTail && lastTaskId_ != lastId) {
1829+ return RT_ERROR_NONE;
1830+ }
1831+ // tail已发生变化且新tail到达sqHead,sqHead - 1位置可能读到新下发任务。
1832+ if ((reReadPosTail + rtsqDepth - sqHead) % rtsqDepth < ((reReadPosTail + rtsqDepth - posTail) % rtsqDepth)) {
1833+ return RT_ERROR_NONE;
1834+ }
1835+ // sqHead - 1位置读到的任务不能比入口时的最新任务更新。
1836+ if ((endTaskId != MAX_UINT16_NUM) && TASK_ID_GT(endTaskId, lastId)) {
1837+ return RT_ERROR_NONE;
1838+ }
1825 RT_LOG(RT_LOG_INFO, "stream_id=%d, sq_id=%u, sqHead=%u, nextTaskId=%u, finishedPos=%u, endTaskId=%u",1839 RT_LOG(RT_LOG_INFO, "stream_id=%d, sq_id=%u, sqHead=%u, nextTaskId=%u, finishedPos=%u, endTaskId=%u",
1826 streamId_, sqId_, sqHead, nextTaskId, finishedPos, endTaskId);1840 streamId_, sqId_, sqHead, nextTaskId, finishedPos, endTaskId);
1827 1841 
1828 // In scenarios with multiple SQEs, ffts+, mem wait, determine whether a task has been completed.1842 // In scenarios with multiple SQEs, ffts+, mem wait, determine whether a task has been completed.
1829 // If the task IDs before and after are the same, it is considered that the task has not been completed.1843 // If the task IDs before and after are the same, it is considered that the task has not been completed.
1830- if (sqHead == posTail || nextTaskId != endTaskId) { // In the multi-task scenario, the task is reclaimed after all the tasks are executed.1844+ // In the multi-task scenario, the task is reclaimed after all the tasks are executed.
1845+ if ((sqHead == posTail) || (nextTaskId != endTaskId)) {
1831 finishedId = endTaskId;1846 finishedId = endTaskId;
1832 }1847 }
1833 1848 
@@ -1851,7 +1866,7 @@ bool Stream::SynchronizeDelayTime(const uint16_t finishedId, const uint16_t task
1851 uint32_t tryCount = 0U;1866 uint32_t tryCount = 0U;
1852 const uint64_t beginTime = GetWallUs();1867 const uint64_t beginTime = GetWallUs();
1853 while (GetWallUs() - beginTime < SLEEP_UNIT) {1868 while (GetWallUs() - beginTime < SLEEP_UNIT) {
1854- if (TASK_ID_GEQ(executeEndTaskid_.Value(), taskId)) {1869+ if ((executeEndTaskid_.Value() != MAX_UINT16_NUM) && (TASK_ID_GEQ(executeEndTaskid_.Value(), taskId))) {
1855 return true;1870 return true;
1856 }1871 }
1857 tryCount++;1872 tryCount++;
@@ -1884,12 +1899,15 @@ rtError_t Stream::SynchronizeExecutedTask(const uint32_t taskId, const mmTimespe
1884 Runtime::Instance()->excptCallBack_(RT_EXCEPTION_TASK_TIMEOUT);1899 Runtime::Instance()->excptCallBack_(RT_EXCEPTION_TASK_TIMEOUT);
1885 }1900 }
1886 }1901 }
1887- COND_RETURN_ERROR_MSG_INNER((abortStatus_ == RT_ERROR_STREAM_ABORT), RT_ERROR_STREAM_ABORT, "The stream %u is in abort state.", streamId_);1902+ COND_RETURN_ERROR_MSG_INNER(
1903+ (abortStatus_ == RT_ERROR_STREAM_ABORT), RT_ERROR_STREAM_ABORT,
1904+ "The stream is in abort state, stream_id=%u.", streamId_);
1888 error = CheckContextStatus(false);1905 error = CheckContextStatus(false);
1889- COND_RETURN_ERROR(error != RT_ERROR_NONE, error, "context is abort, status=%#x.", static_cast<uint32_t>(error));1906+ COND_RETURN_ERROR(error != RT_ERROR_NONE, error, "Context is abort, status=%#x.", static_cast<uint32_t>(error));
1890 COND_RETURN_ERROR_MSG_INNER((GetStreamStatus() != StreamStatus::NORMAL), RT_ERROR_STREAM_SYNC,1907 COND_RETURN_ERROR_MSG_INNER((GetStreamStatus() != StreamStatus::NORMAL), RT_ERROR_STREAM_SYNC,
1891 "The stream status is %u (NORMAL=0, ABNORMAL=1), device_id=%u, stream_id=%d.", static_cast<uint32_t>(GetStreamStatus()), device_->Id_(), Id_());1908 "The stream status is %u (NORMAL=0, ABNORMAL=1), device_id=%u, stream_id=%d.", static_cast<uint32_t>(GetStreamStatus()), device_->Id_(), Id_());
1892- if ((IsTaskExcuted(GetExecuteEndTaskId(), taskId)) || (sqHead == posTail)) {1909+ const uint16_t exeEndTaskId = GetExecuteEndTaskId();
1910+ if (((exeEndTaskId != MAX_UINT16_NUM) && IsTaskExcuted(exeEndTaskId, taskId)) || (sqHead == posTail)) {
1893 return RT_ERROR_NONE;1911 return RT_ERROR_NONE;
1894 }1912 }
1895 if (!device_->GetIsDoingRecycling()) {1913 if (!device_->GetIsDoingRecycling()) {
@@ -961,6 +961,7 @@ TEST_F(DavidStreamTest, TestSeparateSendAndRecycle3) {
961 rtError_t ret;961 rtError_t ret;
962 MOCKER_CPP(&Stream::IsSeparateSendAndRecycle).stubs().will(returnValue(true));962 MOCKER_CPP(&Stream::IsSeparateSendAndRecycle).stubs().will(returnValue(true));
963 stream->SetBindFlag(false);963 stream->SetBindFlag(false);
964+ stream->SetExecuteEndTaskId(0);
964 ret = SubmitTaskPostProc(stream, 0, true, 100);965 ret = SubmitTaskPostProc(stream, 0, true, 100);
965 966 
966 EXPECT_EQ(ret, RT_ERROR_NONE); 967 EXPECT_EQ(ret, RT_ERROR_NONE);
@@ -997,6 +998,7 @@ TEST_F(DavidStreamTest, TestSeparateSendAndRecycle4)
997 rtError_t ret;998 rtError_t ret;
998 MOCKER_CPP(&Stream::IsSeparateSendAndRecycle).stubs().will(returnValue(true));999 MOCKER_CPP(&Stream::IsSeparateSendAndRecycle).stubs().will(returnValue(true));
999 stream->SetBindFlag(false);1000 stream->SetBindFlag(false);
1001+ stream->SetExecuteEndTaskId(0);
1000 ret = SubmitTaskPostProc(stream, 0, true, 100);1002 ret = SubmitTaskPostProc(stream, 0, true, 100);
1001 EXPECT_EQ(ret, RT_ERROR_NONE); 1003 EXPECT_EQ(ret, RT_ERROR_NONE);
1002}1004}
@@ -292,6 +292,7 @@ TEST_F(DavidTaskRecycleTest, SyncTaskRecycleBySqHead)
292 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);292 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);
293 task->sqeNum = 1U;293 task->sqeNum = 1U;
294 task->type = TS_TASK_TYPE_KERNEL_AICORE;294 task->type = TS_TASK_TYPE_KERNEL_AICORE;
295+ rt_ut::UnwrapOrNull<Stream>(stream)->SetLastTaskId(task->id);
295 EXPECT_EQ(error, RT_ERROR_NONE);296 EXPECT_EQ(error, RT_ERROR_NONE);
296 EXPECT_EQ(pos, i);297 EXPECT_EQ(pos, i);
297 }298 }
@@ -343,6 +344,7 @@ TEST_F(DavidTaskRecycleTest, SyncTaskRecycleBySqHeadV2)
343 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);344 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);
344 task->sqeNum = 1U;345 task->sqeNum = 1U;
345 task->type = TS_TASK_TYPE_KERNEL_AICORE;346 task->type = TS_TASK_TYPE_KERNEL_AICORE;
347+ rt_ut::UnwrapOrNull<Stream>(stream)->SetLastTaskId(task->id);
346 EXPECT_EQ(error, RT_ERROR_NONE);348 EXPECT_EQ(error, RT_ERROR_NONE);
347 EXPECT_EQ(pos, i);349 EXPECT_EQ(pos, i);
348 }350 }
@@ -429,6 +431,7 @@ TEST_F(DavidTaskRecycleTest, DvppWaitGroupCommonTaskReportLogicCq)
429 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);431 task->stream = rt_ut::UnwrapOrNull<Stream>(stream);
430 task->sqeNum = 1U;432 task->sqeNum = 1U;
431 task->type = TS_TASK_TYPE_KERNEL_AICORE;433 task->type = TS_TASK_TYPE_KERNEL_AICORE;
434+ rt_ut::UnwrapOrNull<Stream>(stream)->SetLastTaskId(task->id);
432 EXPECT_EQ(ret, RT_ERROR_NONE);435 EXPECT_EQ(ret, RT_ERROR_NONE);
433 EXPECT_EQ(pos, i);436 EXPECT_EQ(pos, i);
434 }437 }