LCOV - code coverage report
Current view: top level - aicpu_schedule/statistic - aicpusd_proc_mem_statistic.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.4 % 157 145
Test Date: 2026-08-12 11:05:02 Functions: 93.3 % 15 14

            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              : 
      11              : #include "aicpusd_proc_mem_statistic.h"
      12              : 
      13              : #include <string>
      14              : #include <fstream>
      15              : #include "aicpusd_util.h"
      16              : 
      17              : namespace AicpuSchedule {
      18              : namespace {
      19              : constexpr const char* VM_RSS_NAME = "VmRSS:";
      20              : constexpr const char* VM_HWM_NAME = "VmHWM:";
      21              : constexpr const char* XSMEME_NAME = "summary:";
      22              : const std::string SVM_STAT_NAME = "peak_page_cnt=";
      23              : constexpr const uint64_t DEFAULT_PAGE_SIZE = 4 * 1024UL;
      24              : constexpr const uint64_t H_PAGE_SIZE = 2 * 1024 * 1024UL;
      25              : constexpr const uint64_t BYTE_TO_KBYTE = 1024UL;
      26              : constexpr const int32_t SVM_VALUE_CNT = 2;
      27              : constexpr const int32_t XSMEM_VALUE_CNT = 2;
      28              : } // namespace
      29           12 : AicpuSdProcMemStatistic::AicpuSdProcMemStatistic() : deployCtx_(DeployContext::HOST), curPid_(0) {}
      30              : 
      31           12 : AicpuSdProcMemStatistic::~AicpuSdProcMemStatistic() {}
      32              : 
      33            5 : void AicpuSdProcMemStatistic::StatisticProcSvmMemInfo()
      34              : {
      35            5 :     if (deployCtx_ != DeployContext::DEVICE) {
      36            4 :         return;
      37              :     }
      38            4 :     uint64_t svmValue = 0UL;
      39            4 :     if (!GetSvmInfoFromFile(svmValue)) {
      40            3 :         return;
      41              :     }
      42            1 :     if (svmValue > svmMem_.memHwm) {
      43            1 :         svmMem_.memHwm = svmValue;
      44              :     }
      45            1 :     svmMem_.memTotal += svmValue;
      46            1 :     svmMem_.statCnt++;
      47              : }
      48              : 
      49            4 : bool AicpuSdProcMemStatistic::GetSvmInfoFromFile(uint64_t& svmValue)
      50              : {
      51            4 :     std::ifstream inFile(svmMemCfgFile_);
      52            4 :     if (!inFile) {
      53            1 :         aicpusd_info(
      54              :             "Opening svmMem file was not successful, pid=%d, errno=%d, reason:%s", static_cast<int32_t>(curPid_), errno,
      55              :             strerror(errno));
      56            1 :         return false;
      57              :     }
      58            6 :     const ScopeGuard fileGuard([&inFile]() { inFile.close(); });
      59            3 :     std::string summaryStr;
      60            3 :     std::string inputLine;
      61            4 :     while (getline(inFile, inputLine)) {
      62            3 :         const size_t pos = inputLine.find(SVM_STAT_NAME);
      63            3 :         if (pos != std::string::npos) {
      64            2 :             summaryStr = inputLine.substr(pos);
      65            2 :             break;
      66              :         }
      67              :     }
      68              : 
      69            3 :     if (summaryStr.empty()) {
      70            1 :         aicpusd_warn("summaryStr is empty");
      71            1 :         return false;
      72              :     }
      73              : 
      74            2 :     uint64_t peakPgCnt = 0;
      75            2 :     uint64_t peakHPgCnt = 0;
      76              :     const int32_t ret =
      77            2 :         sscanf_s(summaryStr.c_str(), "peak_page_cnt=%llu; peak_hpage_cnt=%llu", &peakPgCnt, &peakHPgCnt);
      78            2 :     if (ret < SVM_VALUE_CNT) {
      79            1 :         aicpusd_warn(
      80              :             "read summaryStr:%s failed, ret:%d, peakHPgCnt:%llu, peakHPgCnt:%llu", summaryStr.c_str(), ret, peakPgCnt,
      81              :             peakHPgCnt);
      82            1 :         return false;
      83              :     }
      84              : 
      85            1 :     aicpusd_info("peakPgCnt:%lu, peakHPgCnt:%lu summary:%s.", peakPgCnt, peakHPgCnt, summaryStr.c_str());
      86            1 :     if ((peakPgCnt == 0) && (peakHPgCnt == 0UL)) {
      87            0 :         return false;
      88              :     }
      89            1 :     svmValue = peakPgCnt * DEFAULT_PAGE_SIZE + peakHPgCnt + H_PAGE_SIZE;
      90            1 :     return true;
      91            4 : }
      92              : 
      93            4 : bool AicpuSdProcMemStatistic::GetXsMemInfoFromFile(uint64_t& xsMemValue)
      94              : {
      95            4 :     std::ifstream inFile(xsMemCfgFile_);
      96            4 :     if (!inFile) {
      97            1 :         aicpusd_info(
      98              :             "Opening xsMem file was not successful, pid=%d, errno=%d, reason:%s", static_cast<int32_t>(curPid_), errno,
      99              :             strerror(errno));
     100            1 :         return false;
     101              :     }
     102            6 :     const ScopeGuard fileGuard([&inFile]() { inFile.close(); });
     103            3 :     std::string summaryStr;
     104            3 :     std::string inputLine;
     105            4 :     while (getline(inFile, inputLine)) {
     106            3 :         if (inputLine.compare(0, strlen(XSMEME_NAME), XSMEME_NAME) == 0) {
     107            2 :             summaryStr = std::move(inputLine);
     108            2 :             break;
     109              :         }
     110              :     }
     111              : 
     112            3 :     if (summaryStr.empty()) {
     113            1 :         aicpusd_warn("summaryStr is empty");
     114            1 :         return false;
     115              :     }
     116              : 
     117            2 :     uint64_t allocSize = 0;
     118            2 :     uint64_t realSize = 0;
     119            2 :     const int32_t ret = sscanf_s(summaryStr.c_str(), "summary: %llu %llu", &allocSize, &realSize);
     120            2 :     if (ret < XSMEM_VALUE_CNT) {
     121            1 :         aicpusd_warn(
     122              :             "read summaryStr:%s failed, ret:%d, allocsize:%llu, real size:%llu", summaryStr.c_str(), ret, allocSize,
     123              :             realSize);
     124            1 :         return false;
     125              :     }
     126              : 
     127            1 :     aicpusd_info("allocsize:%lu B, real size:%lu B, %s.", allocSize, realSize, summaryStr.c_str());
     128            1 :     if (realSize == 0) {
     129            0 :         return false;
     130              :     }
     131            1 :     xsMemValue = realSize;
     132            1 :     return true;
     133            4 : }
     134              : 
     135            4 : void AicpuSdProcMemStatistic::StatisticProcXsMemInfo()
     136              : {
     137            4 :     uint64_t xsMemValue = 0UL;
     138            4 :     if (!GetXsMemInfoFromFile(xsMemValue)) {
     139            3 :         return;
     140              :     }
     141            1 :     if (xsMemValue > xsMem_.memHwm) {
     142            1 :         xsMem_.memHwm = xsMemValue;
     143              :     }
     144            1 :     xsMem_.memTotal += xsMemValue;
     145            1 :     xsMem_.statCnt++;
     146              : }
     147              : 
     148            4 : bool AicpuSdProcMemStatistic::GetOsMemInfoFromFile(uint64_t& rssValue, uint64_t& hwmValue)
     149              : {
     150            4 :     std::ifstream ifFile(rssMemCfgFile_);
     151            4 :     if (!ifFile) {
     152            1 :         aicpusd_info(
     153              :             "Opening rss file was not successful, pid=%d, errno=%d, reason:%s", static_cast<int32_t>(curPid_), errno,
     154              :             strerror(errno));
     155            1 :         return false;
     156              :     }
     157            6 :     const ScopeGuard fileGuard([&ifFile]() { ifFile.close(); });
     158            3 :     std::string vmRssStr;
     159            3 :     std::string vmHwmStr;
     160            3 :     std::string inputLine;
     161           26 :     while (getline(ifFile, inputLine)) {
     162           25 :         if (inputLine.compare(0, strlen(VM_RSS_NAME), VM_RSS_NAME) == 0) {
     163            2 :             vmRssStr = std::move(inputLine);
     164           23 :         } else if (inputLine.compare(0, strlen(VM_HWM_NAME), VM_HWM_NAME) == 0) {
     165            2 :             vmHwmStr = std::move(inputLine);
     166              :         } else {
     167           21 :             continue;
     168              :         }
     169            4 :         if ((!vmRssStr.empty()) && (!vmHwmStr.empty())) {
     170            2 :             break;
     171              :         }
     172              :     }
     173              : 
     174            3 :     if ((vmRssStr.empty()) || (vmHwmStr.empty())) {
     175            1 :         aicpusd_run_info("cannot get vmrss or vmhwm");
     176            1 :         return false;
     177              :     }
     178              : 
     179            2 :     if (!AicpuUtil::TransStrToull(vmRssStr.substr(strlen(VM_RSS_NAME)), rssValue)) {
     180            1 :         aicpusd_warn("get vmRssError:%s failed", vmRssStr.c_str());
     181            1 :         return false;
     182              :     }
     183              : 
     184            1 :     if (!AicpuUtil::TransStrToull(vmHwmStr.substr(strlen(VM_HWM_NAME)), hwmValue)) {
     185            0 :         aicpusd_warn("get vmHwmError:%s failed", vmHwmStr.c_str());
     186            0 :         return false;
     187              :     }
     188            1 :     aicpusd_info("vmRss:%llu KB, vmHwm:%llu KB.", rssValue, hwmValue);
     189            1 :     return true;
     190            4 : }
     191              : 
     192            3 : void AicpuSdProcMemStatistic::StatisticProcOsMemInfo()
     193              : {
     194            3 :     uint64_t rssValue = 0UL;
     195            3 :     uint64_t hwmValue = 0UL;
     196            3 :     if (!GetOsMemInfoFromFile(rssValue, hwmValue)) {
     197            2 :         aicpusd_warn("get os meminfo failed");
     198            2 :         return;
     199              :     }
     200            1 :     rssMem_.memHwm = hwmValue;
     201            1 :     rssMem_.memTotal += rssValue;
     202            1 :     rssMem_.statCnt++;
     203              : }
     204              : 
     205            1 : void AicpuSdProcMemStatistic::StatisticProcMemInfo()
     206              : {
     207            1 :     StatisticProcOsMemInfo();
     208            1 :     StatisticProcXsMemInfo();
     209            1 :     StatisticProcSvmMemInfo();
     210            1 : }
     211              : 
     212            1 : bool AicpuSdProcMemStatistic::InitProcMemStatistic()
     213              : {
     214            1 :     auto ret = memset_s(&rssMem_, sizeof(rssMem_), 0x00, sizeof(rssMem_));
     215            1 :     if (ret != EOK) {
     216            0 :         aicpusd_err("memset rssMem failed ret:%d", ret);
     217            0 :         return false;
     218              :     }
     219              : 
     220            1 :     ret = memset_s(&svmMem_, sizeof(svmMem_), 0x00, sizeof(svmMem_));
     221            1 :     if (ret != EOK) {
     222            0 :         aicpusd_err("memset svmMem_ failed ret:%d", ret);
     223            0 :         return false;
     224              :     }
     225              : 
     226            1 :     ret = memset_s(&xsMem_, sizeof(xsMem_), 0x00, sizeof(xsMem_));
     227            1 :     if (ret != EOK) {
     228            0 :         aicpusd_err("memset xsMem_ failed ret:%d", ret);
     229            0 :         return false;
     230              :     }
     231            1 :     (void)GetAicpuDeployContext(deployCtx_);
     232            1 :     curPid_ = getpid();
     233            1 :     if (curPid_ < 0) {
     234            0 :         aicpusd_err("get pid error:%d", curPid_);
     235            0 :         return false;
     236              :     }
     237            1 :     rssMemCfgFile_ = "/proc/" + std::to_string(curPid_) + "/status";
     238            1 :     xsMemCfgFile_ = "/proc/xsmem/task/" + std::to_string(curPid_) + "/summary";
     239            1 :     svmMemCfgFile_ = "/proc/svm/task/" + std::to_string(curPid_) + "/summary";
     240            1 :     return true;
     241              : }
     242              : 
     243            5 : void AicpuSdProcMemStatistic::PrintOutProcMemInfo(const uint32_t hostPid)
     244              : {
     245            5 :     uint64_t rssavg = 0UL;
     246            5 :     if (rssMem_.statCnt > 0) {
     247            2 :         rssavg = rssMem_.memTotal / rssMem_.statCnt;
     248              :     }
     249            5 :     aicpusd_info("rssavg:%llu KB, rsstotal:%llu KB, rsscnt:%llu", rssavg, rssMem_.memTotal, rssMem_.statCnt);
     250            5 :     uint64_t xsmAvg = 0UL;
     251            5 :     if (xsMem_.statCnt > 0) {
     252            1 :         xsmAvg = xsMem_.memTotal / xsMem_.statCnt;
     253              :     }
     254            5 :     aicpusd_info("xsmAvg:%llu B, xsmtotal:%llu B, xsmcnt:%llu", xsmAvg, xsMem_.memTotal, xsMem_.statCnt);
     255            5 :     if (deployCtx_ == DeployContext::DEVICE) {
     256            3 :         uint64_t svmAvg = 0UL;
     257            3 :         if (svmMem_.statCnt > 0) {
     258            1 :             svmAvg = svmMem_.memTotal / svmMem_.statCnt;
     259              :         }
     260            3 :         aicpusd_info("svmAvg:%llu B, svmtotal:%llu B, svmcnt:%llu", svmAvg, svmMem_.memTotal, svmMem_.statCnt);
     261            3 :         aicpusd_run_info(
     262              :             "proc_metrics:pid=%u, rssavg=%lu B, rsshwm=%llu B, xsmemavg=%llu B, xsmemhwm=%lu B, "
     263              :             "svmmemavg=%llu B, svmmemhwm=%lu B",
     264              :             hostPid, rssavg * BYTE_TO_KBYTE, rssMem_.memHwm * BYTE_TO_KBYTE, xsmAvg, xsMem_.memHwm, svmAvg,
     265              :             svmMem_.memHwm);
     266              :     } else {
     267            2 :         aicpusd_run_info(
     268              :             "proc_metrics:pid=%u, rssavg=%lu B, rsshwm=%llu B, xsmemavg=%llu B, xsmemhwm=%lu B", hostPid,
     269              :             rssavg * BYTE_TO_KBYTE, rssMem_.memHwm * BYTE_TO_KBYTE, xsmAvg, xsMem_.memHwm);
     270              :     }
     271            5 : }
     272              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1