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