blob: 7b8e2370e2401a33b0971f5c24956bec0fc48297 [file] [log] [blame]
Steve Kondikf7652b32013-11-26 15:20:51 -08001/* Copyright (c) 2002,2008-2013, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/debugfs.h>
16
17#include "kgsl.h"
18#include "kgsl_device.h"
19#include "kgsl_sharedmem.h"
20
21/*default log levels is error for everything*/
22#define KGSL_LOG_LEVEL_MAX 7
23
24struct dentry *kgsl_debugfs_dir;
25static struct dentry *pm_d_debugfs;
26struct dentry *proc_d_debugfs;
27
28static int pm_dump_set(void *data, u64 val)
29{
30 struct kgsl_device *device = data;
31
32 if (val) {
33 mutex_lock(&device->mutex);
34 kgsl_postmortem_dump(device, 1);
35 mutex_unlock(&device->mutex);
36 }
37
38 return 0;
39}
40DEFINE_SIMPLE_ATTRIBUTE(pm_dump_fops,
41 NULL,
42 pm_dump_set, "%llu\n");
43
44static int pm_regs_enabled_set(void *data, u64 val)
45{
46 struct kgsl_device *device = data;
47 device->pm_regs_enabled = val ? 1 : 0;
48 return 0;
49}
50
51static int pm_regs_enabled_get(void *data, u64 *val)
52{
53 struct kgsl_device *device = data;
54 *val = device->pm_regs_enabled;
55 return 0;
56}
57
58static int pm_ib_enabled_set(void *data, u64 val)
59{
60 struct kgsl_device *device = data;
61 device->pm_ib_enabled = val ? 1 : 0;
62 return 0;
63}
64
65static int pm_ib_enabled_get(void *data, u64 *val)
66{
67 struct kgsl_device *device = data;
68 *val = device->pm_ib_enabled;
69 return 0;
70}
71
72static int pm_enabled_set(void *data, u64 val)
73{
74 struct kgsl_device *device = data;
75 device->pm_dump_enable = val;
76 return 0;
77}
78
79static int pm_enabled_get(void *data, u64 *val)
80{
81 struct kgsl_device *device = data;
82 *val = device->pm_dump_enable;
83 return 0;
84}
85
86
87DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
88 pm_regs_enabled_get,
89 pm_regs_enabled_set, "%llu\n");
90
91DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
92 pm_ib_enabled_get,
93 pm_ib_enabled_set, "%llu\n");
94
95DEFINE_SIMPLE_ATTRIBUTE(pm_enabled_fops,
96 pm_enabled_get,
97 pm_enabled_set, "%llu\n");
98
99static inline int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
100{
101 *log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
102 return 0;
103}
104
105#define KGSL_DEBUGFS_LOG(__log) \
106static int __log ## _set(void *data, u64 val) \
107{ \
108 struct kgsl_device *device = data; \
109 return kgsl_log_set(&device->__log, data, val); \
110} \
111static int __log ## _get(void *data, u64 *val) \
112{ \
113 struct kgsl_device *device = data; \
114 *val = device->__log; \
115 return 0; \
116} \
117DEFINE_SIMPLE_ATTRIBUTE(__log ## _fops, \
118__log ## _get, __log ## _set, "%llu\n"); \
119
120KGSL_DEBUGFS_LOG(drv_log);
121KGSL_DEBUGFS_LOG(cmd_log);
122KGSL_DEBUGFS_LOG(ctxt_log);
123KGSL_DEBUGFS_LOG(mem_log);
124KGSL_DEBUGFS_LOG(pwr_log);
125
126static int memfree_hist_print(struct seq_file *s, void *unused)
127{
128 void *base = kgsl_driver.memfree_hist.base_hist_rb;
129
130 struct kgsl_memfree_hist_elem *wptr = kgsl_driver.memfree_hist.wptr;
131 struct kgsl_memfree_hist_elem *p;
132 char str[16];
133
134 seq_printf(s, "%8s %8s %8s %11s\n",
135 "pid", "gpuaddr", "size", "flags");
136
137 mutex_lock(&kgsl_driver.memfree_hist_mutex);
138 p = wptr;
139 for (;;) {
140 kgsl_get_memory_usage(str, sizeof(str), p->flags);
141 /*
142 * if the ring buffer is not filled up yet
143 * all its empty elems have size==0
144 * just skip them ...
145 */
146 if (p->size)
147 seq_printf(s, "%8d %08x %8d %11s\n",
148 p->pid, p->gpuaddr, p->size, str);
149 p++;
150 if ((void *)p >= base + kgsl_driver.memfree_hist.size)
151 p = (struct kgsl_memfree_hist_elem *) base;
152
153 if (p == kgsl_driver.memfree_hist.wptr)
154 break;
155 }
156 mutex_unlock(&kgsl_driver.memfree_hist_mutex);
157 return 0;
158}
159
160static int memfree_hist_open(struct inode *inode, struct file *file)
161{
162 return single_open(file, memfree_hist_print, inode->i_private);
163}
164
165static const struct file_operations memfree_hist_fops = {
166 .open = memfree_hist_open,
167 .read = seq_read,
168 .llseek = seq_lseek,
169 .release = single_release,
170};
171
172void kgsl_device_debugfs_init(struct kgsl_device *device)
173{
174 if (kgsl_debugfs_dir && !IS_ERR(kgsl_debugfs_dir))
175 device->d_debugfs = debugfs_create_dir(device->name,
176 kgsl_debugfs_dir);
177
178 if (!device->d_debugfs || IS_ERR(device->d_debugfs))
179 return;
180
181 debugfs_create_file("log_level_cmd", 0644, device->d_debugfs, device,
182 &cmd_log_fops);
183 debugfs_create_file("log_level_ctxt", 0644, device->d_debugfs, device,
184 &ctxt_log_fops);
185 debugfs_create_file("log_level_drv", 0644, device->d_debugfs, device,
186 &drv_log_fops);
187 debugfs_create_file("log_level_mem", 0644, device->d_debugfs, device,
188 &mem_log_fops);
189 debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
190 &pwr_log_fops);
191 debugfs_create_file("memfree_history", 0444, device->d_debugfs, device,
192 &memfree_hist_fops);
193
194 /* Create postmortem dump control files */
195
196 pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs);
197
198 if (IS_ERR(pm_d_debugfs))
199 return;
200
201 debugfs_create_file("dump", 0600, pm_d_debugfs, device,
202 &pm_dump_fops);
203 debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
204 &pm_regs_enabled_fops);
205 debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
206 &pm_ib_enabled_fops);
207 debugfs_create_file("enable", 0644, pm_d_debugfs, device,
208 &pm_enabled_fops);
209
210}
211
212static const char * const memtype_strings[] = {
213 "gpumem",
214 "pmem",
215 "ashmem",
216 "usermap",
217 "ion",
218};
219
220static const char *memtype_str(int memtype)
221{
222 if (memtype < ARRAY_SIZE(memtype_strings))
223 return memtype_strings[memtype];
224 return "unknown";
225}
226
227static char get_alignflag(const struct kgsl_memdesc *m)
228{
229 int align = kgsl_memdesc_get_align(m);
230 if (align >= ilog2(SZ_1M))
231 return 'L';
232 else if (align >= ilog2(SZ_64K))
233 return 'l';
234 return '-';
235}
236
237static char get_cacheflag(const struct kgsl_memdesc *m)
238{
239 static const char table[] = {
240 [KGSL_CACHEMODE_WRITECOMBINE] = '-',
241 [KGSL_CACHEMODE_UNCACHED] = 'u',
242 [KGSL_CACHEMODE_WRITEBACK] = 'b',
243 [KGSL_CACHEMODE_WRITETHROUGH] = 't',
244 };
245 return table[kgsl_memdesc_get_cachemode(m)];
246}
247
248static void print_mem_entry(struct seq_file *s, struct kgsl_mem_entry *entry)
249{
Ethan Chen7b185902014-11-16 16:48:31 -0800250 char flags[7];
Steve Kondikf7652b32013-11-26 15:20:51 -0800251 char usage[16];
252 struct kgsl_memdesc *m = &entry->memdesc;
253
254 flags[0] = kgsl_memdesc_is_global(m) ? 'g' : '-';
255 flags[1] = m->flags & KGSL_MEMFLAGS_GPUREADONLY ? 'r' : '-';
256 flags[2] = get_alignflag(m);
257 flags[3] = get_cacheflag(m);
258 flags[4] = kgsl_memdesc_use_cpu_map(m) ? 'p' : '-';
Ethan Chen7b185902014-11-16 16:48:31 -0800259 flags[5] = (m->useraddr) ? 'Y' : 'N';
260 flags[6] = '\0';
Steve Kondikf7652b32013-11-26 15:20:51 -0800261
262 kgsl_get_memory_usage(usage, sizeof(usage), m->flags);
263
Ethan Chen7b185902014-11-16 16:48:31 -0800264 seq_printf(s, "%pK %pK %8zd %5d %6s %10s %16s %5d\n",
265 (unsigned long *)(uintptr_t) m->gpuaddr,
266 (unsigned long *) m->useraddr,
267 m->size, entry->id, flags,
268 memtype_str(entry->memtype), usage, m->sglen);
Steve Kondikf7652b32013-11-26 15:20:51 -0800269}
270
271static int process_mem_print(struct seq_file *s, void *unused)
272{
273 struct kgsl_mem_entry *entry;
274 struct rb_node *node;
275 struct kgsl_process_private *private = s->private;
276 int next = 0;
277
Ethan Chen7b185902014-11-16 16:48:31 -0800278 seq_printf(s, "%8s %8s %8s %5s %6s %10s %16s %5s\n",
Steve Kondikf7652b32013-11-26 15:20:51 -0800279 "gpuaddr", "useraddr", "size", "id", "flags", "type",
280 "usage", "sglen");
281
282 /* print all entries with a GPU address */
283 spin_lock(&private->mem_lock);
284
285 for (node = rb_first(&private->mem_rb); node; node = rb_next(node)) {
286 entry = rb_entry(node, struct kgsl_mem_entry, node);
287 print_mem_entry(s, entry);
288 }
289
290
291 /* now print all the unbound entries */
292 while (1) {
293 entry = idr_get_next(&private->mem_idr, &next);
294 if (entry == NULL)
295 break;
296 if (entry->memdesc.gpuaddr == 0)
297 print_mem_entry(s, entry);
298 next++;
299 }
300 spin_unlock(&private->mem_lock);
301
302 return 0;
303}
304
305static int process_mem_open(struct inode *inode, struct file *file)
306{
Ethan Chen7b185902014-11-16 16:48:31 -0800307 struct kgsl_process_private *private = inode->i_private;
308
309 /*
310 * Hold a reference count on the process while open
311 * in case the process tries to die in the meantime.
312 * If the process is already dying we cannot get a
313 * refcount, print nothing.
314 */
315
316 if (!private || !kgsl_process_private_get(private))
317 return -ENODEV;
318
319 return single_open(file, process_mem_print, private);
320}
321
322static int process_mem_release(struct inode *inode, struct file *file)
323{
324 struct kgsl_process_private *private = inode->i_private;
325
326 if (private)
327 kgsl_process_private_put(private);
328
329 return single_release(inode, file);
Steve Kondikf7652b32013-11-26 15:20:51 -0800330}
331
332static const struct file_operations process_mem_fops = {
333 .open = process_mem_open,
334 .read = seq_read,
335 .llseek = seq_lseek,
Ethan Chen7b185902014-11-16 16:48:31 -0800336 .release = process_mem_release,
Steve Kondikf7652b32013-11-26 15:20:51 -0800337};
338
339
340/**
341 * kgsl_process_init_debugfs() - Initialize debugfs for a process
342 * @private: Pointer to process private structure created for the process
343 *
344 * @returns: 0 on success, error code otherwise
345 *
346 * kgsl_process_init_debugfs() is called at the time of creating the
347 * process struct when a process opens kgsl device for the first time.
348 * The function creates the debugfs files for the process. If debugfs is
349 * disabled in the kernel, we ignore that error and return as successful.
350 */
351int
352kgsl_process_init_debugfs(struct kgsl_process_private *private)
353{
354 unsigned char name[16];
355 int ret = 0;
356 struct dentry *dentry;
357
358 snprintf(name, sizeof(name), "%d", private->pid);
359
360 private->debug_root = debugfs_create_dir(name, proc_d_debugfs);
361
362 if (!private->debug_root)
363 return -EINVAL;
364
365 private->debug_root->d_inode->i_uid = proc_d_debugfs->d_inode->i_uid;
366 private->debug_root->d_inode->i_gid = proc_d_debugfs->d_inode->i_gid;
367
368 /*
369 * debugfs_create_dir() and debugfs_create_file() both
370 * return -ENODEV if debugfs is disabled in the kernel.
371 * We make a distinction between these two functions
372 * failing and debugfs being disabled in the kernel.
373 * In the first case, we abort process private struct
374 * creation, in the second we continue without any changes.
375 * So if debugfs is disabled in kernel, return as
376 * success.
377 */
Ethan Chen7b185902014-11-16 16:48:31 -0800378 dentry = debugfs_create_file("mem", 0444, private->debug_root, private,
Steve Kondikf7652b32013-11-26 15:20:51 -0800379 &process_mem_fops);
380
381 if (IS_ERR(dentry)) {
382 ret = PTR_ERR(dentry);
383
384 if (ret == -ENODEV)
385 ret = 0;
386 } else if (dentry) {
387 dentry->d_inode->i_uid = proc_d_debugfs->d_inode->i_uid;
388 dentry->d_inode->i_gid = proc_d_debugfs->d_inode->i_gid;
389 }
390
391 return ret;
392}
393
394void kgsl_core_debugfs_init(void)
395{
396 kgsl_debugfs_dir = debugfs_create_dir("kgsl", 0);
397 proc_d_debugfs = debugfs_create_dir("proc", kgsl_debugfs_dir);
398}
399
400void kgsl_core_debugfs_close(void)
401{
402 debugfs_remove_recursive(kgsl_debugfs_dir);
403}