summaryrefslogtreecommitdiff
path: root/memtrack_aml.c (plain)
blob: 3689cf5ce99cc238587965d0fc31bb1ef07be869
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "memtrack_aml"
18#include <errno.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <ctype.h>
22
23#include <hardware/memtrack.h>
24#include <log/log.h>
25
26#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27
28static struct hw_module_methods_t memtrack_module_methods = {
29 .open = NULL,
30};
31
32struct memtrack_record record_templates[] = {
33 {
34 .flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED |
35 MEMTRACK_FLAG_PRIVATE |
36 MEMTRACK_FLAG_NONSECURE,
37 },
38
39/*
40 {
41 .flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED |
42 MEMTRACK_FLAG_PRIVATE |
43 MEMTRACK_FLAG_NONSECURE,
44 },
45*/
46};
47
48// just return 0
49int aml_memtrack_init(const struct memtrack_module *module)
50{
51 return 0;
52}
53
54/*
55 * find the userid of process @pid
56 * return the userid if success, or return -1 if not
57 */
58static int memtrack_find_userid(int pid)
59{
60 FILE *fp;
61 char line[1024];
62 char tmp[128];
63 int userid;
64
65 sprintf(tmp, "/proc/%d/status", pid);
66 if ((fp=fopen(tmp, "r")) == NULL) {
67 ALOGD("open file %s error %s", tmp, strerror(errno));
68 return -1;
69 }
70
71 while (fgets(line, sizeof(line), fp) != NULL) {
72 if (sscanf(line, "Uid: %d", &userid) == 1) {
73 fclose(fp);
74 return userid;
75 }
76 }
77
78 // should never reach here
79 fclose(fp);
80 return -1;
81}
82
83static unsigned int memtrack_read_smaps(FILE *fp)
84{
85 char line[1024];
86 unsigned int size, sum = 0;
87 int skip, done = 0;
88
89 unsigned long int start, end;
90 int len;
91 char *name;
92 int nameLen, name_pos;
93
94 if(fgets(line, sizeof(line), fp) == 0) {
95 return 0;
96 }
97
98 while (!done) {
99 skip = 0;
100
101 len = strlen(line);
102 if (len < 1)
103 return 0;
104
105 line[--len] = 0;
106
107 if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) {
108 skip = 1;
109 } else {
110 while (isspace(line[name_pos])) {
111 name_pos += 1;
112 }
113 name = line + name_pos;
114 nameLen = strlen(name);
115
116 if (nameLen >= 8 &&
117 (!strncmp(name, "/dev/mali", 6) || !strncmp(name, "/dev/ump", 6))) {
118 skip = 0;
119 } else {
120 skip = 1;
121 }
122
123 }
124
125 while (1) {
126 if (fgets(line, 1024, fp) == 0) {
127 done = 1;
128 break;
129 }
130
131 if(!skip) {
132 if (line[0] == 'S' && sscanf(line, "Size: %d kB", &size) == 1) {
133 sum += size;
134 }
135 }
136
137 if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
138 // looks like a new mapping
139 // example: "10000000-10001000 ---p 10000000 00:00 0"
140 break;
141 }
142 }
143
144 }
145
146 // converted into Bytes
147 return (sum * 1024);
148}
149
150static unsigned int memtrack_get_gpuMem(int pid)
151{
152 FILE *fp;
153 char tmp[128];
154 unsigned int result;
155
156 sprintf(tmp, "/proc/%d/smaps", pid);
157 fp = fopen(tmp, "r");
158 if (fp == NULL) {
159 ALOGD("open file %s error %s", tmp, strerror(errno));
160 return 0;
161 }
162
163 result = memtrack_read_smaps(fp);
164
165 fclose(fp);
166 return result;
167}
168
169static int memtrack_get_memory(pid_t pid, enum memtrack_type type,
170 struct memtrack_record *records,
171 size_t *num_records)
172{
173 FILE *fp;
174 FILE *ion_fp;
175 char line[1024];
176 char tmp[128];
177 unsigned int mali_inuse = 0;
178 unsigned int size;
179 size_t unaccounted_size = 0;
180
181 char ion_name[128];
182 int ion_pid;
183 unsigned int ion_size;
184 unsigned int gpu_size;
185
186
187 // ALOGD("type is %d, pid is %d\n", type, pid);
188 size_t allocated_records = ARRAY_SIZE(record_templates);
189 *num_records = ARRAY_SIZE(record_templates);
190
191 if (records == NULL) {
192 return 0;
193 }
194
195 memcpy(records, record_templates, sizeof(struct memtrack_record) * allocated_records);
196
197 if (type == MEMTRACK_TYPE_GL) {
198 // find the user id of the process, only support calculate the non root process
199 int ret = memtrack_find_userid(pid);
200 if (ret <= 0) {
201 return -1;
202 }
203 gpu_size = memtrack_get_gpuMem(pid);
204 unaccounted_size += gpu_size;
205 } else if (type == MEMTRACK_TYPE_GRAPHICS) {
206 sprintf(tmp, "/proc/ion/vmalloc_ion");
207 // sprintf(tmp, "/sys/kernel/debug/ion/vmalloc_ion");
208 if ((ion_fp = fopen(tmp, "r")) == NULL) {
209 ALOGD("open file %s error %s", tmp, strerror(errno));
210 return -errno;
211 }
212
213 while(fgets(line, sizeof(line), ion_fp) != NULL) {
214 if (sscanf(line, "%s%d%u", ion_name, &ion_pid, &ion_size) != 3) {
215 continue;
216 } else {
217 if (ion_pid == pid) {
218 unaccounted_size += ion_size;
219 }
220 }
221
222 }
223
224 fclose(ion_fp);
225 }
226
227 if (allocated_records > 0) {
228 records[0].size_in_bytes = unaccounted_size;
229 // ALOGD("graphic %u\n", unaccounted_size);
230 }
231
232 return 0;
233}
234
235int aml_memtrack_get_memory(const struct memtrack_module *module,
236 pid_t pid,
237 int type,
238 struct memtrack_record *records,
239 size_t *num_records)
240{
241 if (type == MEMTRACK_TYPE_GL || type == MEMTRACK_TYPE_GRAPHICS) {
242 return memtrack_get_memory(pid, type, records, num_records);
243
244 } else {
245 return -EINVAL;
246 }
247}
248
249
250struct memtrack_module HAL_MODULE_INFO_SYM = {
251 common: {
252 tag: HARDWARE_MODULE_TAG,
253 module_api_version: MEMTRACK_MODULE_API_VERSION_0_1,
254 hal_api_version: HARDWARE_HAL_API_VERSION,
255 id: MEMTRACK_HARDWARE_MODULE_ID,
256 name: "aml Memory Tracker HAL",
257 author: "amlogic",
258 methods: &memtrack_module_methods,
259 },
260
261 init: aml_memtrack_init,
262 getMemory: aml_memtrack_get_memory,
263};
264