LCOV - code coverage report
Current view: top level - base_comm/resources/endpoints/dfx - endpoint_monitor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.6 % 107 98
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 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              : 
      11              : #include "dfx/endpoint_monitor.h"
      12              : #include "hcom_common.h"
      13              : 
      14              : namespace hcomm {
      15              : 
      16              : constexpr u32 EndpointMonitor::MONITOR_INTERVAL;
      17              : 
      18          264 : EndpointMonitor::~EndpointMonitor() { DeInit(deviceLogicId_); }
      19              : 
      20           76 : EndpointMonitor& EndpointMonitor::GetInstance(s32 deviceLogicId)
      21              : {
      22           76 :     static std::array<EndpointMonitor, MAX_MODULE_DEVICE_NUM + 1> instances;
      23              :     uint32_t deviceId;
      24           76 :     if ((deviceLogicId < 0) || (static_cast<u32>(deviceLogicId) > MAX_MODULE_DEVICE_NUM)) {
      25            0 :         HCCL_ERROR(
      26              :             "[EndpointMonitor][%s] deviceLogicId[%d] not in range [0,%u]", __func__, deviceLogicId,
      27              :             MAX_MODULE_DEVICE_NUM);
      28            0 :         deviceId = MAX_MODULE_DEVICE_NUM;
      29              :     } else {
      30           76 :         deviceId = static_cast<u32>(deviceLogicId);
      31              :     }
      32           76 :     return instances[deviceId];
      33              : }
      34              : 
      35            8 : HcclResult EndpointMonitor::RegisterToEndpointMonitor(s32 deviceLogicId, EndpointHandle epHandle)
      36              : {
      37            8 :     if ((deviceLogicId < 0) || (static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM)) {
      38            2 :         HCCL_ERROR(
      39              :             "[EndpointMonitor][%s] deviceLogicId[%d] not in range [0,%u)", __func__, deviceLogicId,
      40              :             MAX_MODULE_DEVICE_NUM);
      41            2 :         return HCCL_E_PARA;
      42              :     }
      43            6 :     CHK_PRT_RET(epHandle == nullptr, HCCL_ERROR("[EndpointMonitor][%s] epHandle is null", __func__), HCCL_E_PTR);
      44              : 
      45            5 :     HCCL_INFO(
      46              :         "[EndpointMonitor] deviceLogicId[%d] epHandle[%p] RegisterToEndpointMonitor begin.", deviceLogicId, epHandle);
      47            5 :     u32 devPhyId{0};
      48            5 :     CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<u32>(deviceLogicId), devPhyId));
      49              : 
      50              :     {
      51            5 :         std::lock_guard<std::mutex> lock(threadLock_);
      52            5 :         epHandleSet_.emplace(reinterpret_cast<u64>(epHandle));
      53            5 :         if (!initialized_) {
      54            1 :             deviceLogicId_ = deviceLogicId;
      55            1 :             devPhyId_ = devPhyId;
      56            1 :             CHK_RET(RunMonitorThread());
      57              :         }
      58            5 :     }
      59              : 
      60            5 :     HCCL_INFO(
      61              :         "[EndpointMonitor] deviceLogicId[%d] epHandle[%p] RegisterToEndpointMonitor Completed.", deviceLogicId,
      62              :         epHandle);
      63            5 :     return HCCL_SUCCESS;
      64              : }
      65              : 
      66            1 : HcclResult EndpointMonitor::RunMonitorThread()
      67              : {
      68            1 :     HCCL_INFO("[EndpointMonitor][%s] deviceLogicId[%d] Start Thread.", __func__, deviceLogicId_);
      69            1 :     endpointMonitorThreadFlag_ = true;
      70            1 :     EXCEPTION_CATCH(
      71              :         endpointMonitorThread_ = std::make_unique<std::thread>(&EndpointMonitor::MonitorThread, this),
      72              :         return HCCL_E_INTERNAL);
      73            1 :     CHK_SMART_PTR_NULL(endpointMonitorThread_);
      74            1 :     initialized_ = true;
      75            1 :     return HCCL_SUCCESS;
      76              : }
      77              : 
      78            1 : void EndpointMonitor::MonitorThread()
      79              : {
      80            1 :     SetThreadName("Hccl_Ub_Event_Monitor");
      81              : 
      82            1 :     HcclResult ret = hrtSetDevice(deviceLogicId_);
      83            1 :     if (ret != HCCL_SUCCESS) {
      84            0 :         HCCL_ERROR(
      85              :             "[EndpointMonitor][%s] hrtSetDevice failed, deviceLogicId[%d], ret[%d]", __func__, deviceLogicId_, ret);
      86            0 :         return;
      87              :     }
      88              : 
      89            5 :     while (endpointMonitorThreadFlag_) {
      90            4 :         ProcessUbAsyncEvents();
      91            4 :         std::this_thread::sleep_for(std::chrono::milliseconds(MONITOR_INTERVAL));
      92              :     }
      93              : 
      94            1 :     ret = hrtResetDevice(deviceLogicId_);
      95            1 :     if (ret != HCCL_SUCCESS) {
      96            0 :         HCCL_ERROR(
      97              :             "[EndpointMonitor][%s] hrtResetDevice failed, deviceLogicId[%d], ret[%d]", __func__, deviceLogicId_, ret);
      98              :     }
      99              : }
     100              : 
     101            1 : HcclResult EndpointMonitor::UnRegisterToEndpointMonitor()
     102              : {
     103            1 :     s32 deviceLogicId = deviceLogicId_;
     104            1 :     HCCL_INFO("[EndpointMonitor] deviceId[%d] UnRegisterToEndpointMonitor begin.", deviceLogicId);
     105              :     {
     106            1 :         std::lock_guard<std::mutex> lock(threadLock_);
     107            1 :         CHK_PRT_RET(
     108              :             !initialized_,
     109              :             HCCL_WARNING(
     110              :                 "[EndpointMonitor] deviceId[%d] hcclUbEventMonitor has been destroyed, or not initialized",
     111              :                 deviceLogicId),
     112              :             HCCL_SUCCESS);
     113            1 :         epHandleSet_.clear();
     114            1 :     }
     115              : 
     116            1 :     CHK_RET(DeInit(deviceLogicId_));
     117            1 :     deviceLogicId_ = 0;
     118            1 :     devPhyId_ = 0;
     119            1 :     initialized_ = false;
     120              : 
     121            1 :     HCCL_INFO("[EndpointMonitor] deviceId[%d] UnRegisterToEndpointMonitor completed.", deviceLogicId);
     122            1 :     return HCCL_SUCCESS;
     123              : }
     124              : 
     125           53 : void EndpointMonitor::RemoveEpHandleFromEndpointMonitor(EndpointHandle epHandle)
     126              : {
     127           53 :     if (epHandle == nullptr) {
     128            2 :         HCCL_ERROR("[EndpointMonitor][%s] epHandle is null", __func__);
     129            2 :         return;
     130              :     }
     131              : 
     132              :     {
     133           51 :         std::lock_guard<std::mutex> lock(threadLock_);
     134           51 :         auto it = epHandleSet_.find(reinterpret_cast<u64>(epHandle));
     135           51 :         if (it != epHandleSet_.end()) {
     136            4 :             epHandleSet_.erase(it);
     137            4 :             HCCL_INFO(
     138              :                 "[EndpointMonitor][%s] epHandle[%p] is remove from deviceId[%d]", __func__, epHandle, deviceLogicId_);
     139              :         }
     140           51 :     }
     141              : }
     142              : 
     143          265 : HcclResult EndpointMonitor::DeInit(s32 deviceLogicId)
     144              : {
     145          265 :     endpointMonitorThreadFlag_ = false;
     146          265 :     if (endpointMonitorThread_) {
     147            1 :         if (endpointMonitorThread_->joinable()) {
     148              :             try {
     149            1 :                 HCCL_INFO("[EndpointMonitor][%s] deviceId[%d] thread join", __func__, deviceLogicId);
     150            1 :                 endpointMonitorThread_->join();
     151            1 :                 endpointMonitorThread_.reset();
     152            0 :             } catch (const std::exception& e) {
     153            0 :                 HCCL_ERROR("[EndpointMonitor][%s] deviceId[%d] join failed: %s", __func__, deviceLogicId, e.what());
     154            0 :                 return HCCL_E_INTERNAL;
     155            0 :             }
     156              :         }
     157              :     }
     158          265 :     return HCCL_SUCCESS;
     159              : }
     160              : 
     161            8 : void EndpointMonitor::ProcessUbAsyncEvents()
     162              : {
     163            8 :     std::lock_guard<std::mutex> lock(threadLock_);
     164           11 :     for (auto it = epHandleSet_.begin(); it != epHandleSet_.end();) {
     165            3 :         u32 num = ASYNC_EVENT_MAX_NUM;
     166            3 :         Endpoint* localEpPtr = reinterpret_cast<Endpoint*>(*it);
     167            3 :         HcclResult ret = localEpPtr->GetAsyncEvents(devPhyId_, events_, num);
     168            3 :         if (ret != HCCL_SUCCESS) {
     169            2 :             it = epHandleSet_.erase(it);
     170            2 :             HCCL_ERROR(
     171              :                 "[EndpointMonitor][%s] deviceId[%d] HcommGetAsyncEvents failed ret[%d], "
     172              :                 "epHandle[%p] removed from monitor",
     173              :                 __func__, deviceLogicId_, ret, localEpPtr);
     174            2 :             continue;
     175              :         }
     176              : 
     177            5 :         for (u32 i = 0; i < num; ++i) {
     178            4 :             PrintUbAsyncEventsContext(static_cast<void*>(localEpPtr), i, events_[i]);
     179              :         }
     180              : 
     181            1 :         ++it;
     182              :     }
     183            8 : }
     184              : 
     185              : constexpr u32 SECOND_LAST_OFFSET = 2; // 倒数第二个字节偏移
     186              : constexpr u32 LAST_OFFSET = 3;        // 倒数第一个字节偏移
     187            2 : void EndpointMonitor::PrintUbAsyncEventsContext(void* epHandle, u32 seq, const struct AsyncEvent& event)
     188              : {
     189            2 :     u32 contextLen = event.len;
     190            2 :     if (contextLen > CONTEXT_MAX_LEN) {
     191            1 :         HCCL_ERROR(
     192              :             "[EndpointMonitor][%s] deviceId[%d] epHandle[%p] seq[%u] context len[%u] exceed max[%u]", __func__,
     193              :             deviceLogicId_, epHandle, seq, contextLen, CONTEXT_MAX_LEN);
     194            1 :         return;
     195              :     }
     196              : 
     197            1 :     HCCL_ERROR("************************************** ub async event **************************************");
     198            1 :     HCCL_ERROR(
     199              :         "deviceId[%d] epHandle[%p] seq[%u] resId[%u] eventType[%u] contextLen[%u]", deviceLogicId_, epHandle, seq,
     200              :         event.resId, event.eventType, event.len);
     201            1 :     if (contextLen != 0) {
     202            1 :         HCCL_ERROR("bytes order: high -> low");
     203              :     }
     204            1 :     constexpr u32 bytesPerLine = 4;
     205            4 :     for (u32 i = 0; i < contextLen; i += bytesPerLine) {
     206            3 :         u32 endIndex = std::min(i + bytesPerLine, contextLen);
     207            3 :         HCCL_ERROR(
     208              :             "context[byte %3u]: %02x%02x%02x%02x", endIndex,
     209              :             (i + LAST_OFFSET < contextLen) ? event.context[i + LAST_OFFSET] : 0,
     210              :             (i + SECOND_LAST_OFFSET < contextLen) ? event.context[i + SECOND_LAST_OFFSET] : 0,
     211              :             (i + 1 < contextLen) ? event.context[i + 1] : 0, event.context[i]);
     212              :     }
     213            1 :     HCCL_ERROR("********************************************************************************************");
     214              : }
     215              : 
     216              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1