1 /* drm_proc.h -- /proc support for DRM -*- linux-c -*-
2 * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
32 * Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
33 * the problem with the proc files not outputting all their information.
36 #define __NO_VERSION__
39 static int DRM(name_info)(char *buf, char **start, off_t offset,
40 int request, int *eof, void *data);
41 static int DRM(vm_info)(char *buf, char **start, off_t offset,
42 int request, int *eof, void *data);
43 static int DRM(clients_info)(char *buf, char **start, off_t offset,
44 int request, int *eof, void *data);
45 static int DRM(queues_info)(char *buf, char **start, off_t offset,
46 int request, int *eof, void *data);
47 static int DRM(bufs_info)(char *buf, char **start, off_t offset,
48 int request, int *eof, void *data);
50 static int DRM(vma_info)(char *buf, char **start, off_t offset,
51 int request, int *eof, void *data);
54 static int DRM(histo_info)(char *buf, char **start, off_t offset,
55 int request, int *eof, void *data);
58 struct drm_proc_list {
60 int (*f)(char *, char **, off_t, int, int *, void *);
61 } DRM(proc_list)[] = {
62 { "name", DRM(name_info) },
63 { "mem", DRM(mem_info) },
64 { "vm", DRM(vm_info) },
65 { "clients", DRM(clients_info) },
66 { "queues", DRM(queues_info) },
67 { "bufs", DRM(bufs_info) },
69 { "vma", DRM(vma_info) },
72 { "histo", DRM(histo_info) },
75 #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
77 struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
78 struct proc_dir_entry *root,
79 struct proc_dir_entry **dev_root)
81 struct proc_dir_entry *ent;
85 if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
87 DRM_ERROR("Cannot create /proc/dri\n");
91 sprintf(name, "%d", minor);
92 *dev_root = create_proc_entry(name, S_IFDIR, root);
94 DRM_ERROR("Cannot create /proc/%s\n", name);
98 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
99 ent = create_proc_entry(DRM(proc_list)[i].name,
100 S_IFREG|S_IRUGO, *dev_root);
102 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
103 name, DRM(proc_list)[i].name);
104 for (j = 0; j < i; j++)
105 remove_proc_entry(DRM(proc_list)[i].name,
107 remove_proc_entry(name, root);
108 if (!minor) remove_proc_entry("dri", NULL);
111 ent->read_proc = DRM(proc_list)[i].f;
119 int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
120 struct proc_dir_entry *dev_root)
125 if (!root || !dev_root) return 0;
127 for (i = 0; i < DRM_PROC_ENTRIES; i++)
128 remove_proc_entry(DRM(proc_list)[i].name, dev_root);
129 sprintf(name, "%d", minor);
130 remove_proc_entry(name, root);
131 if (!minor) remove_proc_entry("dri", NULL);
136 static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
137 int *eof, void *data)
139 drm_device_t *dev = (drm_device_t *)data;
142 if (offset > DRM_PROC_LIMIT) {
147 *start = &buf[offset];
151 DRM_PROC_PRINT("%s 0x%x %s\n",
152 dev->name, dev->device, dev->unique);
154 DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
157 if (len > request + offset) return request;
162 static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
163 int *eof, void *data)
165 drm_device_t *dev = (drm_device_t *)data;
168 /* Hardcoded from _DRM_FRAME_BUFFER,
169 _DRM_REGISTERS, _DRM_SHM, and
171 const char *types[] = { "FB", "REG", "SHM", "AGP" };
175 if (offset > DRM_PROC_LIMIT) {
180 *start = &buf[offset];
183 DRM_PROC_PRINT("slot offset size type flags "
185 for (i = 0; i < dev->map_count; i++) {
186 map = dev->maplist[i];
187 if (map->type < 0 || map->type > 3) type = "??";
188 else type = types[map->type];
189 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
195 (unsigned long)map->handle);
197 DRM_PROC_PRINT("none\n");
199 DRM_PROC_PRINT("%4d\n", map->mtrr);
203 if (len > request + offset) return request;
208 static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
209 int *eof, void *data)
211 drm_device_t *dev = (drm_device_t *)data;
214 down(&dev->struct_sem);
215 ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
216 up(&dev->struct_sem);
221 static int DRM(_queues_info)(char *buf, char **start, off_t offset,
222 int request, int *eof, void *data)
224 drm_device_t *dev = (drm_device_t *)data;
229 if (offset > DRM_PROC_LIMIT) {
234 *start = &buf[offset];
237 DRM_PROC_PRINT(" ctx/flags use fin"
238 " blk/rw/rwf wait flushed queued"
240 for (i = 0; i < dev->queue_count; i++) {
241 q = dev->queuelist[i];
242 atomic_inc(&q->use_count);
243 DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
245 " %5d/%c%c/%c%c%c %5Zd\n",
248 atomic_read(&q->use_count),
249 atomic_read(&q->finalization),
250 atomic_read(&q->block_count),
251 atomic_read(&q->block_read) ? 'r' : '-',
252 atomic_read(&q->block_write) ? 'w' : '-',
253 waitqueue_active(&q->read_queue) ? 'r':'-',
254 waitqueue_active(&q->write_queue) ? 'w':'-',
255 waitqueue_active(&q->flush_queue) ? 'f':'-',
256 DRM_BUFCOUNT(&q->waitlist));
257 atomic_dec(&q->use_count);
260 if (len > request + offset) return request;
265 static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
266 int *eof, void *data)
268 drm_device_t *dev = (drm_device_t *)data;
271 down(&dev->struct_sem);
272 ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
273 up(&dev->struct_sem);
277 /* drm_bufs_info is called whenever a process reads
278 /dev/dri/<dev>/bufs. */
280 static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
281 int *eof, void *data)
283 drm_device_t *dev = (drm_device_t *)data;
285 drm_device_dma_t *dma = dev->dma;
288 if (!dma || offset > DRM_PROC_LIMIT) {
293 *start = &buf[offset];
296 DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
297 for (i = 0; i <= DRM_MAX_ORDER; i++) {
298 if (dma->bufs[i].buf_count)
299 DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
301 dma->bufs[i].buf_size,
302 dma->bufs[i].buf_count,
303 atomic_read(&dma->bufs[i]
305 dma->bufs[i].seg_count,
306 dma->bufs[i].seg_count
307 *(1 << dma->bufs[i].page_order),
308 (dma->bufs[i].seg_count
309 * (1 << dma->bufs[i].page_order))
312 DRM_PROC_PRINT("\n");
313 for (i = 0; i < dma->buf_count; i++) {
314 if (i && !(i%32)) DRM_PROC_PRINT("\n");
315 DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
317 DRM_PROC_PRINT("\n");
319 if (len > request + offset) return request;
324 static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
325 int *eof, void *data)
327 drm_device_t *dev = (drm_device_t *)data;
330 down(&dev->struct_sem);
331 ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
332 up(&dev->struct_sem);
337 static int DRM(_clients_info)(char *buf, char **start, off_t offset,
338 int request, int *eof, void *data)
340 drm_device_t *dev = (drm_device_t *)data;
344 if (offset > DRM_PROC_LIMIT) {
349 *start = &buf[offset];
352 DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
353 for (priv = dev->file_first; priv; priv = priv->next) {
354 DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
355 priv->authenticated ? 'y' : 'n',
363 if (len > request + offset) return request;
368 static int DRM(clients_info)(char *buf, char **start, off_t offset,
369 int request, int *eof, void *data)
371 drm_device_t *dev = (drm_device_t *)data;
374 down(&dev->struct_sem);
375 ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
376 up(&dev->struct_sem);
382 #define DRM_VMA_VERBOSE 0
384 static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
385 int *eof, void *data)
387 drm_device_t *dev = (drm_device_t *)data;
390 struct vm_area_struct *vma;
393 unsigned long address;
398 #if defined(__i386__)
402 if (offset > DRM_PROC_LIMIT) {
407 *start = &buf[offset];
410 DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
411 atomic_read(&dev->vma_count),
412 high_memory, virt_to_phys(high_memory));
413 for (pt = dev->vmalist; pt; pt = pt->next) {
414 if (!(vma = pt->vma)) continue;
415 DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
419 vma->vm_flags & VM_READ ? 'r' : '-',
420 vma->vm_flags & VM_WRITE ? 'w' : '-',
421 vma->vm_flags & VM_EXEC ? 'x' : '-',
422 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
423 vma->vm_flags & VM_LOCKED ? 'l' : '-',
424 vma->vm_flags & VM_IO ? 'i' : '-',
427 #if defined(__i386__)
428 pgprot = pgprot_val(vma->vm_page_prot);
429 DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
430 pgprot & _PAGE_PRESENT ? 'p' : '-',
431 pgprot & _PAGE_RW ? 'w' : 'r',
432 pgprot & _PAGE_USER ? 'u' : 's',
433 pgprot & _PAGE_PWT ? 't' : 'b',
434 pgprot & _PAGE_PCD ? 'u' : 'c',
435 pgprot & _PAGE_ACCESSED ? 'a' : '-',
436 pgprot & _PAGE_DIRTY ? 'd' : '-',
437 pgprot & _PAGE_PSE ? 'm' : 'k',
438 pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
440 DRM_PROC_PRINT("\n");
442 for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
443 pgd = pgd_offset(vma->vm_mm, i);
444 pmd = pmd_offset(pgd, i);
445 pte = pte_offset(pmd, i);
446 if (pte_present(*pte)) {
447 address = __pa(pte_page(*pte))
448 + (i & (PAGE_SIZE-1));
449 DRM_PROC_PRINT(" 0x%08lx -> 0x%08lx"
453 pte_read(*pte) ? 'r' : '-',
454 pte_write(*pte) ? 'w' : '-',
455 pte_exec(*pte) ? 'x' : '-',
456 pte_dirty(*pte) ? 'd' : '-',
457 pte_young(*pte) ? 'a' : '-' );
459 DRM_PROC_PRINT(" 0x%08lx\n", i);
465 if (len > request + offset) return request;
470 static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
471 int *eof, void *data)
473 drm_device_t *dev = (drm_device_t *)data;
476 down(&dev->struct_sem);
477 ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
478 up(&dev->struct_sem);
484 #if DRM_DMA_HISTOGRAM
485 static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request,
486 int *eof, void *data)
488 drm_device_t *dev = (drm_device_t *)data;
490 drm_device_dma_t *dma = dev->dma;
492 unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL;
493 unsigned long prev_value = 0;
496 if (offset > DRM_PROC_LIMIT) {
501 *start = &buf[offset];
504 DRM_PROC_PRINT("general statistics:\n");
505 DRM_PROC_PRINT("total %10u\n", atomic_read(&dev->histo.total));
506 DRM_PROC_PRINT("open %10u\n",
507 atomic_read(&dev->counts[_DRM_STAT_OPENS]));
508 DRM_PROC_PRINT("close %10u\n",
509 atomic_read(&dev->counts[_DRM_STAT_CLOSES]));
510 DRM_PROC_PRINT("ioctl %10u\n",
511 atomic_read(&dev->counts[_DRM_STAT_IOCTLS]));
513 DRM_PROC_PRINT("\nlock statistics:\n");
514 DRM_PROC_PRINT("locks %10u\n",
515 atomic_read(&dev->counts[_DRM_STAT_LOCKS]));
516 DRM_PROC_PRINT("unlocks %10u\n",
517 atomic_read(&dev->counts[_DRM_STAT_UNLOCKS]));
521 DRM_PROC_PRINT("\ndma statistics:\n");
522 DRM_PROC_PRINT("prio %10u\n",
523 atomic_read(&dma->total_prio));
524 DRM_PROC_PRINT("bytes %10u\n",
525 atomic_read(&dma->total_bytes));
526 DRM_PROC_PRINT("dmas %10u\n",
527 atomic_read(&dma->total_dmas));
528 DRM_PROC_PRINT("missed:\n");
529 DRM_PROC_PRINT(" dma %10u\n",
530 atomic_read(&dma->total_missed_dma));
531 DRM_PROC_PRINT(" lock %10u\n",
532 atomic_read(&dma->total_missed_lock));
533 DRM_PROC_PRINT(" free %10u\n",
534 atomic_read(&dma->total_missed_free));
535 DRM_PROC_PRINT(" sched %10u\n",
536 atomic_read(&dma->total_missed_sched));
537 DRM_PROC_PRINT("tried %10u\n",
538 atomic_read(&dma->total_tried));
539 DRM_PROC_PRINT("hit %10u\n",
540 atomic_read(&dma->total_hit));
541 DRM_PROC_PRINT("lost %10u\n",
542 atomic_read(&dma->total_lost));
545 buffer = dma->next_buffer;
547 DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx);
549 DRM_PROC_PRINT("next_buffer none\n");
551 buffer = dma->this_buffer;
553 DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx);
555 DRM_PROC_PRINT("this_buffer none\n");
560 DRM_PROC_PRINT("\nvalues:\n");
561 if (dev->lock.hw_lock) {
562 DRM_PROC_PRINT("lock 0x%08x\n",
563 dev->lock.hw_lock->lock);
565 DRM_PROC_PRINT("lock none\n");
567 DRM_PROC_PRINT("context_flag 0x%08lx\n", dev->context_flag);
568 DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
569 DRM_PROC_PRINT("dma_flag 0x%08lx\n", dev->dma_flag);
571 DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count);
572 DRM_PROC_PRINT("last_context %10d\n", dev->last_context);
573 DRM_PROC_PRINT("last_switch %10lu\n", dev->last_switch);
574 DRM_PROC_PRINT("last_checked %10d\n", dev->last_checked);
577 DRM_PROC_PRINT("\n q2d d2c c2f"
579 " ctx lacq lhld\n\n");
580 for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
581 DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
582 " %10u %10u %10u %10u %10u\n",
583 i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
584 i == DRM_DMA_HISTOGRAM_SLOTS - 1
585 ? prev_value : slot_value ,
587 atomic_read(&dev->histo
588 .queued_to_dispatched[i]),
589 atomic_read(&dev->histo
590 .dispatched_to_completed[i]),
591 atomic_read(&dev->histo
592 .completed_to_freed[i]),
594 atomic_read(&dev->histo
595 .queued_to_completed[i]),
596 atomic_read(&dev->histo
597 .queued_to_freed[i]),
598 atomic_read(&dev->histo.dma[i]),
599 atomic_read(&dev->histo.schedule[i]),
600 atomic_read(&dev->histo.ctx[i]),
601 atomic_read(&dev->histo.lacq[i]),
602 atomic_read(&dev->histo.lhld[i]));
603 prev_value = slot_value;
604 slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
607 if (len > request + offset) return request;
612 static int DRM(histo_info)(char *buf, char **start, off_t offset, int request,
613 int *eof, void *data)
615 drm_device_t *dev = (drm_device_t *)data;
618 down(&dev->struct_sem);
619 ret = DRM(_histo_info)(buf, start, offset, request, eof, data);
620 up(&dev->struct_sem);