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

Generated by: LCOV version 2.0-1