1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "executor/memory/dma_info.h"
16 #include "util/file_utils.h"
17 #include "securec.h"
18
19 using namespace std;
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 static constexpr int BYTE_PER_KB = 1024;
DmaInfo()24 DmaInfo::DmaInfo()
25 {
26 }
27
~DmaInfo()28 DmaInfo::~DmaInfo()
29 {
30 }
31
32 /**
33 * @description: create dma info
34 * @param {string} &str-string to be inserted into result
35 * @return void
36 */
CreateDmaInfo(const string & str)37 void DmaInfo::CreateDmaInfo(const string &str)
38 {
39 /*
40 Dma-buf objects usage of processes:
41 Process pid fd size_bytes ino exp_pid exp_task_comm buf_name exp_name
42 composer_host 552 11 3686400 7135 552 composer_host NULL rockchipdrm
43 composer_host 552 18 3686400 30235 543 allocator_host NULL rockchipdrm
44 Total dmabuf size of composer_host: 29491200 bytes
45 render_service 575 28 3686400 28052 543 allocator_host NULL rockchipdrm
46 render_service 575 31 3686400 31024 543 allocator_host NULL rockchipdrm
47 Total dmabuf size of render_service: 35520512 bytes
48 */
49 MemInfoData::DmaInfo dmaInfo;
50 char name[256] = {0}; // 256: max size of name
51 if (sscanf_s(str.c_str(), "%255s %llu %*llu %llu %llu %*n %*s %*s %*s",
52 name, sizeof(name), &dmaInfo.pid, &dmaInfo.size, &dmaInfo.ino) == 0) {
53 return;
54 }
55 dmaInfo.name = name;
56 dmaInfo.size /= BYTE_PER_KB;
57 auto it = dmaInfos_.find(dmaInfo.ino);
58 if (it == dmaInfos_.end()) {
59 dmaInfos_.insert(pair<uint64_t, MemInfoData::DmaInfo>(dmaInfo.ino, dmaInfo));
60 } else if ((dmaInfo.name != "composer_host" && dmaInfo.name != "render_service") ||
61 (dmaInfo.name == "render_service" && it->second.name == "composer_host")) {
62 it->second.pid = dmaInfo.pid;
63 }
64 }
65
66 /**
67 * @description: parse dma info
68 * @param void
69 * @return {bool}-the result of
70 */
ParseDmaInfo()71 bool DmaInfo::ParseDmaInfo()
72 {
73 if (initialized_) {
74 return true;
75 }
76 initialized_ = true;
77 string path = "/proc/process_dmabuf_info";
78 bool ret = FileUtils::GetInstance().LoadStringFromProcCb(path, false, true, [&](const string &line) -> void {
79 CreateDmaInfo(line);
80 });
81 for (const auto &it : dmaInfos_) {
82 auto dma = dmaMap_.find(it.second.pid);
83 if (dma != dmaMap_.end()) {
84 dma->second += it.second.size;
85 } else {
86 dmaMap_.insert(pair<uint32_t, uint64_t>(it.second.pid, it.second.size));
87 }
88 }
89 return ret;
90 }
91
92 /**
93 * @description: get dma total
94 * @param void
95 * @return {uint64_t} dma total
96 */
GetTotalDma()97 uint64_t DmaInfo::GetTotalDma()
98 {
99 uint64_t totalDma = 0;
100 for (const auto &it : dmaMap_) {
101 totalDma += it.second;
102 }
103 return totalDma;
104 }
105
106 /**
107 * @description: get dma by pid
108 * @param {int32_t} &pid-process id
109 * @return dma value of process
110 */
GetDmaByPid(const int32_t & pid) const111 uint64_t DmaInfo::GetDmaByPid(const int32_t &pid) const
112 {
113 auto it = dmaMap_.find(pid);
114 if (it != dmaMap_.end()) {
115 return it->second;
116 }
117 return 0;
118 }
119 } // namespace HiviewDFX
120 } // namespace OHOS
121