LCOV - code coverage report
Current view: top level - coll_communicator_mgr/dfx/taskException/aicpu - hcclCommTaskExceptionLite.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 62.8 % 401 252
Test Date: 2026-07-28 12:11:00 Functions: 79.3 % 29 23

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : #include "hcclCommTaskExceptionLite.h"
      11              : #include "stream_lite.h"
      12              : #include "hcomm_task_scheduler_error.h"
      13              : #include "task_struct_v2.h"
      14              : #include "dlhal_function_v2.h"
      15              : #include <shared_mutex>
      16              : #include "aicpu_indop_env.h"
      17              : #include "kernel_entrance.h"
      18              : 
      19              : namespace hcomm {
      20              : constexpr u32 RT_SDMA_COMPERR = 0x9; // A3 sdma error类型为0x9时,表示写拷贝发生超时代答,或者数据搬移时地址译码错误
      21              : constexpr u32 RT_SDMA_COMPDATAERR = 0xa; // A3 sdma error类型为0xa时,表示读拷贝发生超时代答,或者读HBM返回ERROR
      22              : constexpr u32 RT_SDMA_DATAERR = 0x8; // A3 sdma error类型为0x8时,表示读HBM返回ERROR
      23              : constexpr u32 RT_UB_LOCAL_OPERATIOINERR = 0x2; // A5 ub error类型为0x2时,表示UB本端返回ERROR
      24              : constexpr u32 RT_UB_REMOTE_OPERATIOINERR = 0x3; // A5 ub error类型为0x3时,表示UB远端返回ERROR
      25              : constexpr u32 RT_UB_LINK_FAILEDERR = 0x5; // A5 ub error类型为0x5时,表示网络异常,taack超时
      26              : constexpr uint8_t ubSqeType = 9; // A5 sqeType为9表示UBDMA任务
      27              : constexpr uint8_t sdmaSqeType = 11; // A5 sqeType为11表示SDMA任务
      28              : 
      29              : constexpr uint32_t TASK_CONTEXT_SIZE = 50; // task 执行失败时打印前序task信息的数量
      30              : constexpr uint32_t TASK_CONTEXT_INFO_SIZE = LOG_TMPBUF_SIZE - TASK_CONTEXT_SIZE; // task 执行失败时打印前序task信息的长度限制
      31              : constexpr u32 MAX_NAME_LEN = 64;
      32              : constexpr u32 TASK_ID_SHIFT_BITS = 16;
      33              : 
      34           69 : HcclCommTaskExceptionLite &HcclCommTaskExceptionLite::GetInstance()
      35              : {
      36           69 :     static HcclCommTaskExceptionLite instance; // aicpu侧一个dev一个进程,不需要按dev区分单例对象
      37           69 :     return instance;
      38              : }
      39              : 
      40           36 : void HcclCommTaskExceptionLite::Init(u32 devId)
      41              : {
      42           36 :     devId_ = devId;
      43           36 :     HCCL_INFO("[%s]success, devId_[%u]", __func__, devId_);
      44           36 : }
      45              : 
      46            1 : void HcclCommTaskExceptionLite::Call()
      47              : {
      48            1 :     if (stopCall_ == true) {
      49            0 :         return;
      50              :     }
      51              : 
      52            1 :     HcclResult ret = HandleExceptionCqe();
      53            1 :     if (ret != HCCL_SUCCESS) {
      54            0 :         stopCall_ = true;
      55            0 :         HCCL_ERROR("[%s]HandleExceptionCqe fail, set stopCall_[%d]", __func__, stopCall_); // 函数调用失败,停止调用避免刷屏
      56              :     }
      57              : }
      58              : 
      59            6 : HcclResult HcclCommTaskExceptionLite::IsHandleDpuStop(uint8_t *taskexceptionVa, bool &isStop)
      60              : {
      61            6 :     uint8_t stopSignal = 0;
      62            6 :     errno_t ret = memcpy_s(&stopSignal, sizeof(stopSignal), taskexceptionVa, sizeof(stopSignal)); // 读标志位,第1字节,存放host侧发送是否停止的信号。
      63            6 :     if (ret != EOK) {
      64            0 :         HCCL_ERROR("[HcclCommTaskExceptionLite::%s] memcpy_s failed on flag, return[%d].", __func__, ret);
      65            0 :         return HCCL_E_MEMORY;
      66              :     }
      67            6 :     if (stopSignal == 1) {
      68            1 :         isStop = true;
      69            1 :         stopSignal = 0;
      70            1 :         ret = memcpy_s(taskexceptionVa, sizeof(stopSignal), &stopSignal, sizeof(stopSignal)); // 读标志位,第1字节,存放host侧发送是否停止的信号。
      71            1 :         if (ret != EOK) {
      72            0 :             HCCL_ERROR("[HcclCommTaskExceptionLite::%s] memcpy_s failed on flag, return[%d].", __func__, ret);
      73            0 :             return HCCL_E_MEMORY;
      74              :         }
      75              :     }
      76            6 :     return HCCL_SUCCESS;
      77              : }
      78              : 
      79            8 : HcclResult HcclCommTaskExceptionLite::HandleDpuTaskexception(CollCommAicpu *aicpuComm)
      80              : {
      81              :     // 轮询taskexception共享内存
      82            8 :     auto commId = aicpuComm->GetIdentifier();
      83            8 :     std::lock_guard<std::mutex> lock(g_taskExpDevMemMapMutex);
      84            8 :     auto it = g_taskExpDevMemMap.find(commId);
      85            8 :     if (it == g_taskExpDevMemMap.end()) {
      86            1 :         return HCCL_SUCCESS; // 非dpu场景,map为空
      87              :     }
      88              : 
      89            7 :     auto taskexceptionVa = reinterpret_cast<uint8_t *>(it->second);
      90            7 :     if (taskexceptionVa == nullptr) {
      91            1 :         return HCCL_SUCCESS;
      92              :     }
      93              :     // 查是否要停止
      94            6 :     bool isStop = false;
      95            6 :     CHK_RET(IsHandleDpuStop(taskexceptionVa, isStop));
      96            6 :     if (isStop) {
      97            1 :         it->second = nullptr;
      98            1 :         return HCCL_SUCCESS;
      99              :     }
     100              :     // 查是否有错误
     101            5 :     uint16_t flag = 0;
     102            5 :     errno_t ret = memcpy_s(&flag, sizeof(flag), taskexceptionVa + sizeof(uint8_t), sizeof(flag)); // 读标志位,第2-3字节,存放HcclResult。
     103            5 :     if (ret != EOK) {
     104            0 :         HCCL_ERROR("[HcclCommTaskExceptionLite::%s] memcpy_s failed on flag, return[%d].", __func__, ret);
     105            0 :         return HCCL_E_MEMORY;
     106              :     }
     107            5 :     if (flag != 0) {
     108              :         // 触发taskexception
     109            4 :         HCCL_ERROR("[HcclCommTaskExceptionLite][DPU] taskexceptionVa[%p], errorCode[%d], devId[%u], commId[%s]", taskexceptionVa, flag, aicpuComm->GetDevId(), commId.c_str());
     110              :         // 1、取notify,并构造rtLogicCqReport_t
     111            7 :         CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite());
     112            4 :         CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite());
     113            2 :         CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite()->GetCurrDfxOpInfo());
     114            1 :         auto curDfxOpInfo = aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite()->GetCurrDfxOpInfo();
     115            1 :         u32 notifyId = curDfxOpInfo->cpuWaitAicpuNotifyId_;
     116            1 :         rtLogicCqReport_t exceptionInfo{};
     117              :         // 2、调用SendTaskExceptionByMBox触发taskexception回调
     118            1 :         CHK_RET(SendTaskExceptionByMBox(notifyId, 0, exceptionInfo));
     119              :         // 3、标志位置0
     120            1 :         ret = memset_s(taskexceptionVa + sizeof(uint8_t), sizeof(uint16_t), 0, sizeof(uint16_t)); // 标志位置0
     121            1 :         if (ret != EOK) {
     122            0 :             HCCL_ERROR("[HcclCommTaskExceptionLite::%s] memset_s failed on flag, return[%d].", __func__, ret);
     123            0 :             return HCCL_E_MEMORY;
     124              :         }
     125            1 :     }
     126            2 :     return HCCL_SUCCESS;
     127            8 : }
     128              : 
     129            1 : HcclResult HcclCommTaskExceptionLite::HandleExceptionCqe()
     130              : {
     131            1 :     std::shared_lock<std::shared_mutex> rwlock(AicpuIndopProcess::AicpuGetCommMutex());
     132              : 
     133            1 :     std::vector<std::pair<std::string, CollCommAicpuMgr *>> aicpuCommInfo;
     134            1 :     CHK_RET(AicpuIndopProcess::AicpuGetCommAll(aicpuCommInfo));
     135              : 
     136            2 :     for (auto &commInfo : aicpuCommInfo) {
     137            1 :         CollCommAicpu *aicpuComm = commInfo.second->GetCollCommAicpu();
     138            1 :         CHK_PTR_NULL(aicpuComm);
     139              : 
     140            2 :         if ((aicpuComm->GetCommmStatus() == HcclCommStatus::HCCL_COMM_STATUS_INVALID) ||
     141            1 :             (aicpuComm->GetCommmStatus() == HcclCommStatus::HCCL_COMM_STATUS_SUSPENDING)) {
     142            1 :             continue;
     143              :         }
     144            0 :         CHK_RET(HandleDpuTaskexception(aicpuComm)); // dpu taskexception
     145              : 
     146            0 :         std::shared_lock<std::shared_mutex> threadRwlock(aicpuComm->GetThreadMutex());
     147            0 :         const std::vector<std::shared_ptr<hccl::Thread>> threads = aicpuComm->GetAllThread();
     148            0 :         for (auto thread : threads) {
     149              :             rtLogicCqReport_t cqeException;
     150            0 :             dfx::CqeStatus cqeStatus = dfx::CqeStatus::kDefault;
     151            0 :             Hccl::StreamLite *streamLite = static_cast<Hccl::StreamLite *>(thread->GetStreamLitePtr());
     152            0 :             CHK_PTR_NULL(streamLite);
     153              : 
     154            0 :             HcclResult ret = GetThreadCqe(thread.get(), cqeException, cqeStatus);
     155            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s]GetThreadCqe fail, aicpuComm[%s], streamId[%u]",
     156              :                 __func__, aicpuComm->GetIdentifier().c_str(), streamLite->GetId()), ret);
     157              : 
     158            0 :             ret = ProcessCqe(aicpuComm, cqeException, cqeStatus, aicpuCommInfo);
     159            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s]ProcessCqe fail, aicpuComm[%s], streamId[%u], "
     160              :                 "cqeStatus[%d]", __func__, aicpuComm->GetIdentifier().c_str(), streamLite->GetId(), cqeStatus), ret);
     161            0 :         }
     162            0 :     }
     163            1 :     return HCCL_SUCCESS;
     164            1 : }
     165              : 
     166            1 : HcclResult HcclCommTaskExceptionLite::PrintAllCommTaskException()
     167              : {
     168            1 :     std::shared_lock<std::shared_mutex> rwlock(AicpuIndopProcess::AicpuGetCommMutex());
     169              : 
     170            1 :     std::vector<std::pair<std::string, CollCommAicpuMgr *>> aicpuCommInfo;
     171            1 :     CHK_RET(AicpuIndopProcess::AicpuGetCommAll(aicpuCommInfo));
     172              : 
     173            1 :     HCCL_RUN_INFO("[TaskException][AICPU]%s start, comm size[%u]", __func__, aicpuCommInfo.size());
     174            1 :     HcclResult ret = HCCL_SUCCESS;
     175            2 :     for (auto &commInfo : aicpuCommInfo) {
     176            1 :         CollCommAicpu *aicpuComm = commInfo.second->GetCollCommAicpu();
     177            1 :         HcclResult pRet = PrintCommTaskException(aicpuComm);
     178            1 :         CHK_PRT_CONT(pRet != HCCL_SUCCESS, HCCL_ERROR("PrintCommTaskException fail, comm[%s]",
     179              :             aicpuComm->GetIdentifier().c_str()));
     180            1 :         ret = (pRet != HCCL_SUCCESS) ? pRet : ret;
     181              :     }
     182            1 :     HCCL_RUN_INFO("[TaskException][AICPU]%s end, ret[%d]", __func__, ret);
     183            1 :     return ret;
     184            1 : }
     185              : 
     186            2 : HcclResult HcclCommTaskExceptionLite::PrintCommTaskException(CollCommAicpu *aicpuComm)
     187              : {
     188            2 :     CHK_PTR_NULL(aicpuComm);
     189            2 :     HcclResult ret = HCCL_SUCCESS;
     190            2 :     HCCL_RUN_INFO("[TaskException][AICPU]%s comm[%s] start", __func__, aicpuComm->GetIdentifier().c_str());
     191            2 :     std::shared_lock<std::shared_mutex> threadRwlock(aicpuComm->GetThreadMutex());
     192            2 :     const std::vector<std::shared_ptr<hccl::Thread>> threads = aicpuComm->GetAllThread();
     193            3 :     for (auto thread : threads) {
     194            1 :         CHK_SMART_PTR_NULL(thread);
     195            1 :         Hccl::StreamLite *streamLite = static_cast<Hccl::StreamLite *>(thread->GetStreamLitePtr());
     196            1 :         CHK_PTR_NULL(streamLite);
     197            1 :         u32 sqHead = 0U;
     198            1 :         u32 sqTail = 0U;
     199            1 :         HcclResult ret = QuerySqStatus(devId_, streamLite->GetSqId(), sqHead, sqTail);
     200            1 :         if (ret != HCCL_SUCCESS || sqHead == sqTail) { // 此流为空时,不打印
     201            0 :             HCCL_RUN_INFO("[TaskException][AICPU]PrintTaskExceptionBySqeId skip, "
     202              :                 "QuerySqStatus ret[%d], aicpuComm[%s], sqId[%u], sqHead[%u], sqTail[%u]",
     203              :                 ret, aicpuComm->GetIdentifier().c_str(), streamLite->GetSqId(), sqHead, sqTail);
     204            0 :             continue;
     205              :         }
     206            1 :         uint16_t streamId = 0;
     207            1 :         uint16_t taskId = 0;
     208            1 :         streamLite->GetRtsq()->GetStreamIdAndTaskIdBySqIdx(sqHead, streamId, taskId);
     209            1 :         const u32 sqeId = GetSqeId(taskId, streamId);
     210            1 :         HcclResult pRet = PrintTaskExceptionBySqeId(aicpuComm, streamLite->GetSqId(), sqeId);
     211            1 :         CHK_PRT_CONT(pRet != HCCL_SUCCESS, HCCL_ERROR("PrintTaskExceptionBySqeId fail, comm[%s], sqId[%u], sqeId[%u]",
     212              :             aicpuComm->GetIdentifier().c_str(), streamLite->GetSqId(), sqeId));
     213            1 :         ret = (pRet != HCCL_SUCCESS) ? pRet : ret;
     214            1 :     }
     215            2 :     HCCL_RUN_INFO("[TaskException][AICPU]%s comm[%s] end, ret[%d]", __func__, aicpuComm->GetIdentifier().c_str(), ret);
     216            2 :     return ret;
     217            2 : }
     218              : 
     219            0 : HcclResult HcclCommTaskExceptionLite::GetThreadCqe(hccl::Thread* thread, rtLogicCqReport_t &cqeException,
     220              :     dfx::CqeStatus &cqeStatus)
     221              : {
     222            0 :     CHK_SMART_PTR_NULL(thread);
     223            0 :     Hccl::StreamLite *streamLite = static_cast<Hccl::StreamLite *>(thread->GetStreamLitePtr());
     224            0 :     CHK_PTR_NULL(streamLite);
     225              : 
     226            0 :     constexpr u32 reportSize = MAX_REPORT_CNT;
     227              :     rtLogicCqReport_t streamReport[reportSize];
     228              :     
     229              :     CqeQueryInput cqeQueryInput;
     230            0 :     cqeQueryInput.devId = devId_;
     231            0 :     cqeQueryInput.streamId = streamLite->GetId();
     232            0 :     cqeQueryInput.sqId = streamLite->GetSqId();
     233            0 :     cqeQueryInput.cqId = streamLite->GetCqId();
     234            0 :     cqeQueryInput.type = static_cast<uint32_t>(DRV_LOGIC_TYPE);
     235            0 :     cqeQueryInput.cqeAddr = reinterpret_cast<uint8_t *>(streamReport);
     236              :     
     237            0 :     cqeStatus = CqReportRecv(cqeQueryInput, cqeException);
     238            0 :     if (cqeStatus == dfx::CqeStatus::kCqeInnerError) {
     239            0 :         HCCL_ERROR("[%s]CqReportRecv fail, CqeQueryInput:%s", __func__, cqeQueryInput.ToString().c_str());
     240            0 :         return HCCL_E_INTERNAL;
     241              :     }
     242            0 :     return HCCL_SUCCESS;
     243              : }
     244              : 
     245            1 : HcclResult HcclCommTaskExceptionLite::ProcessCqe(CollCommAicpu *aicpuComm, const rtLogicCqReport_t &exceptionInfo,
     246              :     const CqeStatus &cqeStatus, const std::vector<std::pair<std::string, CollCommAicpuMgr *>> &aicpuCommInfo)
     247              : {
     248            1 :     if (cqeStatus == dfx::CqeStatus::kDefault) {
     249            1 :         return HCCL_SUCCESS;
     250              :     }
     251              : 
     252            0 :     if (hcomm::GetTaskExceptionEnable() == false) {
     253            0 :         HCCL_ERROR("[TaskException][AICPU]taskException enable is false, skip print taskException");
     254            0 :         return HCCL_SUCCESS;
     255              :     }
     256              : 
     257            0 :     HcclResult ret = HCCL_SUCCESS;
     258            0 :     const u32 sqeId = GetSqeId(exceptionInfo.taskId, exceptionInfo.streamId);
     259            0 :     ret = PrintTaskExceptionBySqeId(aicpuComm, exceptionInfo.sqId, sqeId);
     260            0 :     CHK_PRT_CONT(ret != HCCL_SUCCESS, HCCL_ERROR("[PrintTaskExceptionBySqeId]fail, ret[%d], group[%s], sqId[%u], taskId[%u]",
     261              :         ret, aicpuComm->GetIdentifier().c_str(), exceptionInfo.sqId, exceptionInfo.taskId)); // 如果上报失败,继续打印taskException
     262              : 
     263            0 :     ret = ReportErrMsg(aicpuComm, exceptionInfo);
     264            0 :     CHK_PRT_CONT(ret != HCCL_SUCCESS, HCCL_ERROR("[ReportErrMsg]fail, ret[%d], group[%s], sqId[%u], taskId[%u]",
     265              :         ret, aicpuComm->GetIdentifier().c_str(), exceptionInfo.sqId, exceptionInfo.taskId)); // 如果上报失败,继续打印taskException
     266              : 
     267              :     // notify超时场景:step1 打印当前流信息;step2 打印当前通信域信息;step3 打印其他通信域信息
     268            0 :     if (cqeStatus == dfx::CqeStatus::kCqeException && exceptionInfo.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER) {
     269            0 :         CHK_RET(PrintCommTaskException(aicpuComm));
     270            0 :         for (auto &commInfo : aicpuCommInfo) {
     271            0 :             CollCommAicpu *comm = commInfo.second->GetCollCommAicpu();
     272            0 :             if (comm != nullptr && comm->GetIdentifier() != aicpuComm->GetIdentifier()) {
     273            0 :                 CHK_RET(PrintCommTaskException(comm));
     274              :             }
     275              :         }
     276              :     }
     277            0 :     return ret;
     278              : }
     279              : 
     280            1 : u32 HcclCommTaskExceptionLite::GetSqeId(uint16_t taskId, uint16_t streamId)
     281              : {
     282            1 :     return (static_cast<u32>(taskId) << TASK_ID_SHIFT_BITS) | static_cast<u32>(streamId);
     283              : }
     284              :          
     285            0 : HcclResult HcclCommTaskExceptionLite::ReportErrMsg(CollCommAicpu *aicpuComm, const rtLogicCqReport_t &exceptionInfo)
     286              : {
     287            0 :     CHK_PTR_NULL(aicpuComm);
     288            0 :     CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite());
     289            0 :     CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite());
     290              : 
     291            0 :     const u32 sqeId = GetSqeId(exceptionInfo.taskId, exceptionInfo.streamId);
     292            0 :     HCCL_INFO("[%s]group[%s], sqeId[0x%x], taskId[%u], streamId[%u].",
     293              :         __func__, aicpuComm->GetIdentifier().c_str(), sqeId, exceptionInfo.taskId, exceptionInfo.streamId);
     294              : 
     295            0 :     const auto curTask = aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite()->GetTaskInfo(exceptionInfo.sqId, sqeId);
     296            0 :     CHK_SMART_PTR_NULL(curTask);
     297            0 :     CHK_SMART_PTR_NULL(curTask->dfxOpInfo_);
     298              : 
     299            0 :     if (!aicpuComm->IsErrorReported()) {
     300              :         // 1) errorMessage上报
     301            0 :         Hccl::ErrorMessageReport errMsgInfo{};
     302            0 :         CHK_RET(GenerateErrorMessageReport(aicpuComm, *curTask, exceptionInfo, errMsgInfo));
     303            0 :         CHK_RET(aicpuComm->SendErrorMessageReportToHost(errMsgInfo));
     304              : 
     305              :         // 2) send mbox to tsfw
     306            0 :         u32 notifyId = curTask->dfxOpInfo_->cpuWaitAicpuNotifyId_;
     307            0 :         CHK_RET(SendTaskExceptionByMBox(notifyId, 0, exceptionInfo));
     308            0 :         aicpuComm->SetErrorReported(true);
     309              :     }
     310            0 :     return HCCL_SUCCESS;
     311              : }
     312              : 
     313            1 : HcclResult HcclCommTaskExceptionLite::PrintTaskExceptionBySqeId(CollCommAicpu *aicpuComm, u32 sqId, u32 sqeId)
     314              : {
     315            1 :     CHK_PTR_NULL(aicpuComm);
     316            1 :     CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite());
     317            1 :     CHK_PTR_NULL(aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite());
     318              : 
     319              :     // 已经打印过的不再重复打印
     320            1 :     auto it = threadsPrinted_.find(sqId);
     321            1 :     if (it != threadsPrinted_.end() && it->second == sqeId) {
     322            0 :         HCCL_RUN_INFO("TaskException][AICPU]sqId:%u, sqeId:%u has been printed, skip", sqId, sqeId);
     323            0 :         return HCCL_SUCCESS;
     324              :     }
     325            1 :     threadsPrinted_[sqId] = sqeId;
     326              : 
     327            1 :     const auto curTask = aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite()->GetTaskInfo(sqId, sqeId);
     328            1 :     CHK_SMART_PTR_NULL(curTask);
     329            1 :     CHK_SMART_PTR_NULL(curTask->dfxOpInfo_);
     330              : 
     331            1 :     u32 sqHead = 0U;
     332            1 :     u32 sqTail = 0U;
     333            1 :     (void)QuerySqStatus(devId_, sqId, sqHead, sqTail);
     334              : 
     335              :     // 1. 打印task信息
     336            1 :     HCCL_ERROR("[TaskException][AICPU]base information is %s, %s, sqHead:%u, sqTail:%u",
     337              :         curTask->GetIndopBaseInfo().c_str(), curTask->GetParaInfo().c_str(), sqHead, sqTail);
     338              :     // 2. UB任务打印EID信息
     339            1 :     PrintEid(*curTask);
     340              :     // 3. 打印group信息
     341            1 :     HCCL_ERROR("[TaskException][AICPU]group information is %s.", GetGroupInfo(aicpuComm).c_str());
     342              :     // 4. 打印算子信息和task序列
     343            1 :     if (curTask->taskParam_.taskType != Hccl::TaskParamType::TASK_NOTIFY_WAIT) { // 非notify场景,仅打印算子信息
     344            1 :         HCCL_ERROR("[TaskException][AICPU]opData information is %s.", curTask->GetIndopDataInfo().c_str());
     345              :     } else {
     346            0 :         CHK_RET(PrintTaskContextInfo(aicpuComm, sqId, sqeId)); // notify场景打印算子信息和task序列
     347              :     }
     348            1 :     return HCCL_SUCCESS;
     349              : }
     350              : 
     351            0 : HcclResult HcclCommTaskExceptionLite::GenerateErrorMessageReport(CollCommAicpu *aicpuComm,
     352              :     const Hccl::TaskInfo& taskInfo, const rtLogicCqReport_t &exceptionInfo, Hccl::ErrorMessageReport &errMsgInfo)
     353              : {
     354              :     // 获取需要上报的关键信息
     355            0 :     errMsgInfo.remoteUserRank = taskInfo.GetRemoteRankId();
     356            0 :     errMsgInfo.streamId = taskInfo.streamId_;
     357            0 :     errMsgInfo.taskId = taskInfo.taskId_;
     358            0 :     errMsgInfo.rankId = aicpuComm->GetTopoInfo().userRank;
     359            0 :     errMsgInfo.rankSize = aicpuComm->GetTopoInfo().userRankSize;
     360            0 :     errMsgInfo.opIndex = taskInfo.dfxOpInfo_->opIndex_;
     361            0 :     errMsgInfo.opType = taskInfo.dfxOpInfo_->op_.opType;
     362            0 :     errMsgInfo.count = taskInfo.dfxOpInfo_->op_.dataCount;
     363            0 :     errMsgInfo.dataType = taskInfo.dfxOpInfo_->op_.dataType;
     364            0 :     errMsgInfo.srcAddr = taskInfo.dfxOpInfo_->op_.inputAddr;
     365            0 :     errMsgInfo.dstAddr = taskInfo.dfxOpInfo_->op_.outputAddr;
     366            0 :     errMsgInfo.taskType = taskInfo.taskParam_.taskType;
     367              : 
     368            0 :     errMsgInfo.rtCqErrorType = exceptionInfo.errorType;
     369            0 :     errMsgInfo.rtCqErrorCode = exceptionInfo.errorCode;
     370              : 
     371            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(errMsgInfo.tag, sizeof(errMsgInfo.tag),
     372              :         taskInfo.dfxOpInfo_->algTag_.c_str(), taskInfo.dfxOpInfo_->algTag_.size()));
     373            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(errMsgInfo.group, sizeof(errMsgInfo.group),
     374              :         aicpuComm->GetIdentifier().c_str(), aicpuComm->GetIdentifier().size()));
     375              : 
     376            0 :     GenerateTaskErrMsg(taskInfo, errMsgInfo, exceptionInfo);
     377            0 :     return HCCL_SUCCESS;
     378              : }
     379              : 
     380            9 : void HcclCommTaskExceptionLite::GenerateTaskErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo,
     381              :     const rtLogicCqReport_t &exceptionInfo)
     382              : {
     383            9 :     switch (taskInfo.taskParam_.taskType) {
     384            2 :         case Hccl::TaskParamType::TASK_NOTIFY_WAIT:
     385              :         case Hccl::TaskParamType::TASK_NOTIFY_RECORD:
     386            2 :             FillNotifyErrMsg(taskInfo, errMsgInfo);
     387            2 :             break;
     388            2 :         case Hccl::TaskParamType::TASK_UB_REDUCE_INLINE:
     389              :         case Hccl::TaskParamType::TASK_WRITE_REDUCE_WITH_NOTIFY:
     390            2 :             FillReduceErrMsg(taskInfo, errMsgInfo, exceptionInfo);
     391            2 :             break;
     392            1 :         case Hccl::TaskParamType::TASK_REDUCE_INLINE:
     393            1 :             FillReduceInlineErrMsg(taskInfo, errMsgInfo);
     394            1 :             break;
     395            2 :         case Hccl::TaskParamType::TASK_UB_INLINE_WRITE:
     396              :         case Hccl::TaskParamType::TASK_WRITE_WITH_NOTIFY:
     397            2 :             FillDmaErrMsg(taskInfo, errMsgInfo, exceptionInfo);
     398            2 :             break;
     399            1 :         case Hccl::TaskParamType::TASK_UB:
     400            1 :             FillUbErrMsg(taskInfo, errMsgInfo, exceptionInfo);
     401            1 :             break;
     402            1 :         case Hccl::TaskParamType::TASK_SDMA:
     403            1 :             FillSdmaErrMsg(taskInfo, errMsgInfo);
     404            1 :             break;
     405            0 :         default:
     406            0 :             HCCL_ERROR("[TaskException][AICPU]%s taskType[%d] is not support", __func__, taskInfo.taskParam_.taskType);
     407            0 :             return;
     408              :     }
     409              : }
     410              : 
     411            2 : void HcclCommTaskExceptionLite::FillNotifyErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo)
     412              : {
     413            2 :     errMsgInfo.notifyId = taskInfo.taskParam_.taskPara.Notify.notifyID;
     414            2 :     errMsgInfo.notifyValue = taskInfo.taskParam_.taskPara.Notify.value;
     415            2 : }
     416              : 
     417            2 : void HcclCommTaskExceptionLite::FillReduceErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo,
     418              :     const rtLogicCqReport_t &exceptionInfo)
     419              : {
     420            2 :     errMsgInfo.reduceType = taskInfo.taskParam_.taskPara.Reduce.reduceOp;
     421            2 :     errMsgInfo.notifyId = taskInfo.taskParam_.taskPara.Reduce.notifyID;
     422            2 :     errMsgInfo.notifyValue = taskInfo.taskParam_.taskPara.Reduce.notifyValue;
     423            2 :     errMsgInfo.locEid = taskInfo.taskParam_.taskPara.Reduce.locEid;
     424            2 :     errMsgInfo.rmtEid = taskInfo.taskParam_.taskPara.Reduce.rmtEid;
     425            2 :     errMsgInfo.ubCqeStatus = exceptionInfo.errorCode & 0xFF;
     426            2 :     errMsgInfo.linkType = taskInfo.taskParam_.taskPara.Reduce.linkType;
     427            2 :     errMsgInfo.size = taskInfo.taskParam_.taskPara.Reduce.size;
     428            2 :     errMsgInfo.taskSrcAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.Reduce.src);
     429            2 :     errMsgInfo.taskDstAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.Reduce.dst);
     430            2 :     HCCL_ERROR("[TaskException][AICPU]ubCqeStatus[%u], localEid[%s], remoteEid[%s]. ",
     431              :         errMsgInfo.ubCqeStatus, errMsgInfo.locEid.Describe().c_str(), errMsgInfo.rmtEid.Describe().c_str());
     432            2 : }
     433              : 
     434            2 : void HcclCommTaskExceptionLite::FillDmaErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo,
     435              :     const rtLogicCqReport_t &exceptionInfo)
     436              : {
     437            2 :     errMsgInfo.notifyId = taskInfo.taskParam_.taskPara.DMA.notifyID;
     438            2 :     errMsgInfo.notifyValue = taskInfo.taskParam_.taskPara.DMA.notifyValue;
     439            2 :     FillUbErrMsg(taskInfo, errMsgInfo, exceptionInfo);
     440            2 : }
     441              : 
     442            1 : void HcclCommTaskExceptionLite::FillSdmaErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo)
     443              : {
     444            1 :     errMsgInfo.linkType = taskInfo.taskParam_.taskPara.DMA.linkType;
     445            1 :     errMsgInfo.size = taskInfo.taskParam_.taskPara.DMA.size;
     446            1 :     errMsgInfo.taskSrcAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.DMA.src);
     447            1 :     errMsgInfo.taskDstAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.DMA.dst);
     448            1 : }
     449              : 
     450            3 : void HcclCommTaskExceptionLite::FillUbErrMsg(const Hccl::TaskInfo& taskInfo, Hccl::ErrorMessageReport &errMsgInfo,
     451              :     const rtLogicCqReport_t &exceptionInfo)
     452              : {
     453            3 :     errMsgInfo.locEid = taskInfo.taskParam_.taskPara.DMA.locEid;
     454            3 :     errMsgInfo.rmtEid = taskInfo.taskParam_.taskPara.DMA.rmtEid;
     455            3 :     errMsgInfo.ubCqeStatus = exceptionInfo.errorCode & 0xFF;
     456            3 :     errMsgInfo.linkType = taskInfo.taskParam_.taskPara.DMA.linkType;
     457            3 :     errMsgInfo.size = taskInfo.taskParam_.taskPara.DMA.size;
     458            3 :     errMsgInfo.taskSrcAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.DMA.src);
     459            3 :     errMsgInfo.taskDstAddr = reinterpret_cast<u64>(taskInfo.taskParam_.taskPara.DMA.dst);
     460            3 :     HCCL_ERROR("[TaskException][AICPU]ubCqeStatus[%u], localEid[%s], remoteEid[%s]. ",
     461              :         errMsgInfo.ubCqeStatus, errMsgInfo.locEid.Describe().c_str(), errMsgInfo.rmtEid.Describe().c_str());
     462            3 : }
     463              : 
     464            1 : void HcclCommTaskExceptionLite::FillReduceInlineErrMsg(const Hccl::TaskInfo& taskInfo,
     465              :     Hccl::ErrorMessageReport &errMsgInfo)
     466              : {
     467            1 :     errMsgInfo.reduceType = taskInfo.taskParam_.taskPara.Reduce.reduceOp;
     468            1 : }
     469              : 
     470            4 : HcclResult HcclCommTaskExceptionLite::SendTaskExceptionByMBox(const u32 notifyId, const u32 tsId,
     471              :     const rtLogicCqReport_t &exceptionInfo)
     472              : {
     473            4 :     ts_aicpu_msg_info_t aicpuSqe = {};
     474            4 :     u32 hostpid = 0;
     475            4 :     u32 vfId = 0;
     476            4 :     int pid = getpid();
     477            4 :     HCCL_INFO("[%s]getpid[%d]", __func__, pid);
     478              :     // 调整drvQueryProcessHostPid获取pid和vf_id的值
     479            4 :     CHK_RET(HrtHalDrvQueryProcessHostPid(pid, nullptr, &vfId, &hostpid, nullptr));
     480              : 
     481            4 :     aicpuSqe.pid = hostpid;
     482            4 :     aicpuSqe.cmd_type = TS_AICPU_RECORD;
     483            4 :     aicpuSqe.vf_id = vfId;
     484            4 :     aicpuSqe.tid = 0U;  // notify is no need tid
     485            4 :     aicpuSqe.u.aicpu_record.record_type = AICPU_MSG_NOTIFY_RECORD_V2;
     486            4 :     aicpuSqe.u.aicpu_record.record_id = notifyId;
     487            4 :     aicpuSqe.ts_id = static_cast<uint8_t>(tsId);
     488            4 :     aicpuSqe.u.aicpu_record.fault_task_id = 0xffffffff;
     489              : 
     490            4 :     if (exceptionInfo.sqeType == ubSqeType) {
     491            1 :         aicpuSqe.u.aicpu_record.ret_code = SwitchUBCqeErrCodeToTsErrCode(exceptionInfo.errorCode & 0xFF);
     492            3 :     } else if (exceptionInfo.sqeType == sdmaSqeType) {
     493            1 :         aicpuSqe.u.aicpu_record.ret_code = SwitchSdmaCqeErrCodeToTsErrCode(exceptionInfo.errorCode);
     494              :     } else {
     495            2 :         aicpuSqe.u.aicpu_record.ret_code = TS_ERROR_HCCL_OTHER_ERROR;
     496              :     }
     497              : 
     498              :     struct event_summary event;
     499            4 :     event.dst_engine = TS_CPU;
     500            4 :     event.policy = ONLY;
     501            4 :     event.pid = 0;
     502            4 :     event.grp_id = 0;
     503            4 :     event.event_id = EVENT_TS_CTRL_MSG;
     504            4 :     event.subevent_id = 0U;
     505            4 :     event.msg_len = static_cast<uint32_t>(sizeof(ts_aicpu_msg_info_t));
     506            4 :     event.msg = reinterpret_cast<char_t *>(&aicpuSqe);
     507            4 :     drvError_t ret = Hccl::DlHalFunctionV2::GetInstance().dlHalEschedSubmitEvent(devId_, &event);
     508            4 :     if (ret != DRV_ERROR_NONE) {
     509            0 :         HCCL_ERROR("[%s]dlHalEschedSubmitEvent failed, ret=%d, notifyId=%u, hostpid=%u, vfId=%u, tsId=%u",
     510              :             __func__, ret, notifyId, hostpid, vfId, tsId);
     511            0 :         return HCCL_E_DRV;
     512              :     }
     513            4 :     HCCL_RUN_INFO("[%s]finished, notifyId=%u, hostpid=%u, vfId=%u, tsId=%u, errorType=%u, errorCode=%u, ret_code=%u",
     514              :         __func__, notifyId, hostpid, vfId, tsId, exceptionInfo.errorType, exceptionInfo.errorCode,
     515              :         aicpuSqe.u.aicpu_record.ret_code);
     516            4 :     return HCCL_SUCCESS;
     517              : }
     518              : 
     519              : // 把UB类错误码转换成Ts对应的错误码
     520            5 : uint16_t HcclCommTaskExceptionLite::SwitchUBCqeErrCodeToTsErrCode(u32 cqeErrCode) {
     521            5 :     switch (cqeErrCode) {
     522            2 :         case RT_UB_LOCAL_OPERATIOINERR:
     523            2 :             return TS_ERROR_HCCL_OP_UB_DDRC_FAILED;
     524            1 :         case RT_UB_REMOTE_OPERATIOINERR:
     525            1 :             return TS_ERROR_HCCL_OP_UB_POISON_FAILED;
     526            1 :         case RT_UB_LINK_FAILEDERR:
     527            1 :             return TS_ERROR_HCCL_OP_UB_LINK_FAILED;
     528            1 :         default:
     529            1 :             return TS_ERROR_HCCL_OTHER_ERROR;
     530              :     }
     531              : }
     532              : 
     533              : // 把SDMA类错误码转换成Ts对应的错误码
     534            5 : uint16_t HcclCommTaskExceptionLite::SwitchSdmaCqeErrCodeToTsErrCode(u32 cqeErrCode) {
     535            5 :     switch (cqeErrCode) {
     536            2 :         case RT_SDMA_COMPERR:
     537            2 :             return TS_ERROR_SDMA_LINK_ERROR;
     538            1 :         case RT_SDMA_COMPDATAERR:
     539            1 :             return TS_ERROR_SDMA_POISON_ERROR;
     540            1 :         case RT_SDMA_DATAERR:
     541            1 :             return TS_ERROR_SDMA_DDRC_ERROR;
     542            1 :         default:
     543            1 :             return TS_ERROR_HCCL_OTHER_ERROR;
     544              :     }
     545              : }
     546              : 
     547            0 : HcclResult HcclCommTaskExceptionLite::CollectTaskContext(CollCommAicpu *aicpuComm, u32 sqId, u32 taskId,
     548              :     std::vector<Hccl::TaskInfo*> &taskContext)
     549              : {
     550            0 :     auto queue = aicpuComm->GetHcclCommDfxLite()->GetMirrorTaskManagerLite()->GetQueue(sqId);
     551            0 :     CHK_PRT_RET(queue == nullptr,
     552              :         HCCL_ERROR("[%s]GetQueue nullptr, devId[%u], sqId[%u].", __func__, devId_, sqId), HCCL_E_PARA);
     553              : 
     554            0 :     auto func = [taskId] (const std::unique_ptr<Hccl::TaskInfo>& task) { return task->taskId_ == taskId; };
     555            0 :     auto taskIterPtr = queue->Find(func);
     556            0 :     CHK_PRT_RET(taskIterPtr == nullptr || *taskIterPtr == *queue->End(),
     557              :         HCCL_ERROR("[%s]exception task not found, devId[%u], sqId[%u], taskId[%u]", __func__, devId_, sqId, taskId),
     558              :         HCCL_E_PARA);
     559              : 
     560              :     // 找到当前异常task的前50个task(至多)
     561            0 :     for (uint32_t i = 0; i < TASK_CONTEXT_SIZE && !queue->IsEmpty(); ++i, --(*taskIterPtr)) {
     562            0 :         if ((**taskIterPtr)->taskId_ > taskId) { // 回绕中止
     563            0 :             HCCL_ERROR("[%s]prev taskId[%u] is bigger than err taskId[%u], taskNum[%u], stop traversal",
     564              :                 __func__, (**taskIterPtr)->taskId_, taskId, taskContext.size());
     565            0 :             break;
     566              :         }
     567            0 :         taskContext.emplace_back((**taskIterPtr).get());
     568              : 
     569            0 :         if (*taskIterPtr == *queue->Begin()) { // 遍历到起始位置中止
     570            0 :             HCCL_ERROR("[%s]taskId[%u] is queue Begin, taskNum[%u], stop traversal",
     571              :                 __func__, (**taskIterPtr)->taskId_, taskContext.size());
     572            0 :             break;
     573              :         }
     574              :     }
     575            0 :     return HCCL_SUCCESS;
     576            0 : }
     577              : 
     578            0 : HcclResult HcclCommTaskExceptionLite::PrintTaskContextInfo(CollCommAicpu *aicpuComm, u32 sqId, u32 taskId)
     579              : {
     580            0 :     std::vector<Hccl::TaskInfo*> taskContext {};
     581            0 :     CHK_PRT_RET(CollectTaskContext(aicpuComm, sqId, taskId, taskContext) != HCCL_SUCCESS,
     582              :         HCCL_ERROR("[%s]CollectTaskContext failed, devId[%u], sqId[%u], taskId[%u]", __func__, devId_, sqId, taskId),
     583              :         HCCL_E_PARA);
     584              : 
     585            0 :     std::string taskContextInfo = "";
     586            0 :     Hccl::TaskInfo* lastTask = nullptr;
     587            0 :     for (u32 i = 0; i < taskContext.size(); ++i) {
     588            0 :         if (taskContext[i] == nullptr) {
     589            0 :             HCCL_ERROR("[%s]taskContext[%u] is nullptr, skip!", __func__, i);
     590            0 :             continue;
     591              :         }
     592            0 :         if (lastTask == nullptr) {
     593            0 :             lastTask = taskContext[i];
     594              :         }
     595            0 :         std::string conciseInfo = taskContext[i]->GetConciseBaseInfo() + ",";
     596              : 
     597            0 :         u32 lastOpIndex = ((lastTask->dfxOpInfo_ == nullptr) ? UINT32_MAX : lastTask->dfxOpInfo_->opIndex_);
     598            0 :         u32 curOpIndex = ((taskContext[i]->dfxOpInfo_ == nullptr) ? UINT32_MAX : taskContext[i]->dfxOpInfo_->opIndex_);
     599            0 :         bool overSize = (taskContextInfo.size() + conciseInfo.size()) >= TASK_CONTEXT_INFO_SIZE; // 1. 字符串超过一定长度时,打印一次
     600              :         // 2. 不同算子,新起一行打印
     601            0 :         if (overSize || (lastOpIndex != curOpIndex)) {
     602            0 :             HCCL_ERROR("[TaskException][AICPU]opData information is %s.", lastTask->GetIndopDataInfo().c_str());
     603            0 :             HCCL_ERROR("[TaskException][AICPU]task sequence is OP(%u): %s", lastOpIndex, taskContextInfo.c_str());
     604            0 :             taskContextInfo = "";
     605            0 :             lastTask = taskContext[i];
     606              :         }
     607            0 :         taskContextInfo += conciseInfo;
     608            0 :     }
     609              : 
     610              :     // 3. 最后一个task,打印一次
     611            0 :     if (!taskContextInfo.empty() && lastTask != nullptr) {
     612            0 :         u32 lastOpIndex = (lastTask->dfxOpInfo_ == nullptr) ? UINT32_MAX : lastTask->dfxOpInfo_->opIndex_;
     613            0 :         HCCL_ERROR("[TaskException][AICPU]opData information is %s.", lastTask->GetIndopDataInfo().c_str());
     614            0 :         HCCL_ERROR("[TaskException][AICPU]task sequence is OP(%u): %s", lastOpIndex, taskContextInfo.c_str());
     615              :     }
     616            0 :     HCCL_ERROR("[TaskException][AICPU]task sequence end.");
     617            0 :     return HCCL_SUCCESS;
     618            0 : }
     619              : 
     620            2 : std::string HcclCommTaskExceptionLite::GetGroupInfo(CollCommAicpu *aicpuComm)
     621              : {
     622            2 :     if (aicpuComm == nullptr) {
     623            1 :         HCCL_ERROR("[%s]aicpuComm is nullptr, return empty string.", __func__);
     624            2 :         return "";
     625              :     }
     626              :     return Hccl::StringFormat("group:[%s], rankSize:[%u], localRank:[%d]",
     627            1 :             aicpuComm->GetIdentifier().c_str(), aicpuComm->GetTopoInfo().userRankSize, aicpuComm->GetTopoInfo().userRank);
     628              : }
     629              : 
     630            1 : void HcclCommTaskExceptionLite::PrintEid(const Hccl::TaskInfo& taskInfo)
     631              : {
     632            2 :     if (taskInfo.taskParam_.taskType == Hccl::TaskParamType::TASK_UB_REDUCE_INLINE ||
     633            1 :         taskInfo.taskParam_.taskType == Hccl::TaskParamType::TASK_WRITE_REDUCE_WITH_NOTIFY) {
     634            0 :         HCCL_ERROR("[TaskException][AICPU][%s]Error UB link info: localEid[%s], remoteEid[%s].", __func__,
     635              :             taskInfo.taskParam_.taskPara.Reduce.locEid.Describe().c_str(),
     636              :             taskInfo.taskParam_.taskPara.Reduce.rmtEid.Describe().c_str());
     637            2 :     } else if (taskInfo.taskParam_.taskType == Hccl::TaskParamType::TASK_UB_INLINE_WRITE ||
     638            2 :         taskInfo.taskParam_.taskType == Hccl::TaskParamType::TASK_WRITE_WITH_NOTIFY ||
     639            1 :         taskInfo.taskParam_.taskType == Hccl::TaskParamType::TASK_UB) {
     640            0 :         HCCL_ERROR("[TaskException][AICPU][%s]Error UB link info: localEid[%s], remoteEid[%s].", __func__,
     641              :             taskInfo.taskParam_.taskPara.DMA.locEid.Describe().c_str(),
     642              :             taskInfo.taskParam_.taskPara.DMA.rmtEid.Describe().c_str());
     643              :     }
     644            1 : }
     645              : }
        

Generated by: LCOV version 2.0-1