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

Generated by: LCOV version 2.0-1