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