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

Generated by: LCOV version 2.0-1