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

Generated by: LCOV version 2.0-1