1 /*
2 * $FreeBSD: releng/5.0/sys/dev/drm/drm_sysctl.h 95584 2002-04-27 20:47:57Z anholt $
3 */
4
5 #include "dev/drm/drm.h"
6 #include "dev/drm/drmP.h"
7 #include <sys/sysctl.h>
8
9 static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
10 static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
11 static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS;
12 static int DRM(queues_info)DRM_SYSCTL_HANDLER_ARGS;
13 static int DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS;
14 #if DRM_DEBUG_CODExx
15 static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS;
16 #endif
17 #if DRM_DMA_HISTOGRAM
18 static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS;
19 #endif
20
21 struct DRM(sysctl_list) {
22 const char *name;
23 int (*f) DRM_SYSCTL_HANDLER_ARGS;
24 } DRM(sysctl_list)[] = {
25 { "name", DRM(name_info) },
26 { "mem", DRM(mem_info) },
27 { "vm", DRM(vm_info) },
28 { "clients", DRM(clients_info) },
29 { "queues", DRM(queues_info) },
30 { "bufs", DRM(bufs_info) },
31 #if DRM_DEBUG_CODExx
32 { "vma", DRM(vma_info) },
33 #endif
34 #if DRM_DMA_HISTOGRAM
35 { "histo", drm_histo_info) },
36 #endif
37 };
38 #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
39
40 struct drm_sysctl_info {
41 struct sysctl_ctx_list ctx;
42 char name[2];
43 };
44
45 int DRM(sysctl_init)(drm_device_t *dev)
46 {
47 struct drm_sysctl_info *info;
48 struct sysctl_oid *oid;
49 struct sysctl_oid *top, *drioid;
50 int i;
51
52 info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
53 if ( !info )
54 return 1;
55 bzero(info, sizeof *info);
56 dev->sysctl = info;
57
58 /* Add the sysctl node for DRI if it doesn't already exist */
59 drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
60 if (!drioid)
61 return 1;
62
63 /* Find the next free slot under hw.dri */
64 i = 0;
65 SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
66 if (i <= oid->oid_arg2)
67 i = oid->oid_arg2 + 1;
68 }
69 if (i>9)
70 return 1;
71
72 /* Add the hw.dri.x for our device */
73 info->name[0] = '' + i;
74 info->name[1] = 0;
75 top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
76 if (!top)
77 return 1;
78
79 for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
80 oid = sysctl_add_oid( &info->ctx,
81 SYSCTL_CHILDREN(top),
82 OID_AUTO,
83 DRM(sysctl_list)[i].name,
84 CTLTYPE_INT | CTLFLAG_RD,
85 dev,
86 0,
87 DRM(sysctl_list)[i].f,
88 "A",
89 NULL);
90 if (!oid)
91 return 1;
92 }
93 return 0;
94 }
95
96 int DRM(sysctl_cleanup)(drm_device_t *dev)
97 {
98 int error;
99 error = sysctl_ctx_free( &dev->sysctl->ctx );
100
101 DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
102 dev->sysctl = NULL;
103
104 return error;
105 }
106
107 static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
108 {
109 drm_device_t *dev = arg1;
110 char buf[128];
111 int error;
112
113 if (dev->unique) {
114 DRM_SYSCTL_PRINT("%s 0x%x %s\n",
115 dev->name, dev2udev(dev->devnode), dev->unique);
116 } else {
117 DRM_SYSCTL_PRINT("%s 0x%x\n", dev->name, dev2udev(dev->devnode));
118 }
119
120 SYSCTL_OUT(req, "", 1);
121
122 return 0;
123 }
124
125 static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
126 {
127 drm_device_t *dev = arg1;
128 drm_map_t *map;
129 drm_map_list_entry_t *listentry;
130 const char *types[] = { "FB", "REG", "SHM" };
131 const char *type;
132 int i=0;
133 char buf[128];
134 int error;
135
136 DRM_SYSCTL_PRINT("slot offset size type flags "
137 "address mtrr\n\n");
138 error = SYSCTL_OUT(req, buf, strlen(buf));
139 if (error) return error;
140
141 if (dev->maplist != NULL) {
142 TAILQ_FOREACH(listentry, dev->maplist, link) {
143 map = listentry->map;
144 if (map->type < 0 || map->type > 2) type = "??";
145 else type = types[map->type];
146 DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
147 i,
148 map->offset,
149 map->size,
150 type,
151 map->flags,
152 (unsigned long)map->handle);
153 if (map->mtrr < 0) {
154 DRM_SYSCTL_PRINT("none\n");
155 } else {
156 DRM_SYSCTL_PRINT("%4d\n", map->mtrr);
157 }
158 i++;
159 }
160 }
161 SYSCTL_OUT(req, "", 1);
162
163 return 0;
164 }
165
166 static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
167 {
168 drm_device_t *dev = arg1;
169 int ret;
170
171 DRM_OS_LOCK;
172 ret = DRM(_vm_info)(oidp, arg1, arg2, req);
173 DRM_OS_UNLOCK;
174
175 return ret;
176 }
177
178
179 static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
180 {
181 drm_device_t *dev = arg1;
182 int i;
183 drm_queue_t *q;
184 char buf[128];
185 int error;
186
187 DRM_SYSCTL_PRINT(" ctx/flags use fin"
188 " blk/rw/rwf wait flushed queued"
189 " locks\n\n");
190 for (i = 0; i < dev->queue_count; i++) {
191 q = dev->queuelist[i];
192 atomic_inc(&q->use_count);
193 DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
194 "%5d/0x%03x %5ld %5ld"
195 " %5ld/%c%c/%c%c%c %5d %10ld %10ld %10ld\n",
196 i,
197 q->flags,
198 atomic_read(&q->use_count),
199 atomic_read(&q->finalization),
200 atomic_read(&q->block_count),
201 atomic_read(&q->block_read) ? 'r' : '-',
202 atomic_read(&q->block_write) ? 'w' : '-',
203 q->read_queue ? 'r':'-',
204 q->write_queue ? 'w':'-',
205 q->flush_queue ? 'f':'-',
206 DRM_BUFCOUNT(&q->waitlist),
207 atomic_read(&q->total_flushed),
208 atomic_read(&q->total_queued),
209 atomic_read(&q->total_locks));
210 atomic_dec(&q->use_count);
211 }
212
213 SYSCTL_OUT(req, "", 1);
214 return 0;
215 }
216
217 static int DRM(queues_info) DRM_SYSCTL_HANDLER_ARGS
218 {
219 drm_device_t *dev = arg1;
220 int ret;
221
222 DRM_OS_LOCK;
223 ret = DRM(_queues_info)(oidp, arg1, arg2, req);
224 DRM_OS_UNLOCK;
225 return ret;
226 }
227
228 /* drm_bufs_info is called whenever a process reads
229 hw.dri.0.bufs. */
230
231 static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
232 {
233 drm_device_t *dev = arg1;
234 drm_device_dma_t *dma = dev->dma;
235 int i;
236 char buf[128];
237 int error;
238
239 if (!dma) return 0;
240 DRM_SYSCTL_PRINT(" o size count free segs pages kB\n\n");
241 for (i = 0; i <= DRM_MAX_ORDER; i++) {
242 if (dma->bufs[i].buf_count)
243 DRM_SYSCTL_PRINT("%2d %8d %5d %5ld %5d %5d %5d\n",
244 i,
245 dma->bufs[i].buf_size,
246 dma->bufs[i].buf_count,
247 atomic_read(&dma->bufs[i]
248 .freelist.count),
249 dma->bufs[i].seg_count,
250 dma->bufs[i].seg_count
251 *(1 << dma->bufs[i].page_order),
252 (dma->bufs[i].seg_count
253 * (1 << dma->bufs[i].page_order))
254 * PAGE_SIZE / 1024);
255 }
256 DRM_SYSCTL_PRINT("\n");
257 for (i = 0; i < dma->buf_count; i++) {
258 if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
259 DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
260 }
261 DRM_SYSCTL_PRINT("\n");
262
263 SYSCTL_OUT(req, "", 1);
264 return 0;
265 }
266
267 static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
268 {
269 drm_device_t *dev = arg1;
270 int ret;
271
272 DRM_OS_LOCK;
273 ret = DRM(_bufs_info)(oidp, arg1, arg2, req);
274 DRM_OS_UNLOCK;
275 return ret;
276 }
277
278
279 static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
280 {
281 drm_device_t *dev = arg1;
282 drm_file_t *priv;
283 char buf[128];
284 int error;
285
286 DRM_SYSCTL_PRINT("a dev pid uid magic ioctls\n\n");
287 TAILQ_FOREACH(priv, &dev->files, link) {
288 DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
289 priv->authenticated ? 'y' : 'n',
290 priv->minor,
291 priv->pid,
292 priv->uid,
293 priv->magic,
294 priv->ioctl_count);
295 }
296
297 SYSCTL_OUT(req, "", 1);
298 return 0;
299 }
300
301 static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
302 {
303 drm_device_t *dev = arg1;
304 int ret;
305
306 DRM_OS_LOCK;
307 ret = DRM(_clients_info)(oidp, arg1, arg2, req);
308 DRM_OS_UNLOCK;
309 return ret;
310 }
311
312 #if DRM_DEBUG_CODExx
313
314 static int DRM(_vma_info)DRM_SYSCTL_HANDLER_ARGS
315 {
316 drm_device_t *dev = arg1;
317 drm_vma_entry_t *pt;
318 pgd_t *pgd;
319 pmd_t *pmd;
320 pte_t *pte;
321 unsigned long i;
322 struct vm_area_struct *vma;
323 unsigned long address;
324 #if defined(__i386__)
325 unsigned int pgprot;
326 #endif
327 char buf[128];
328 int error;
329
330 DRM_SYSCTL_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
331 atomic_read(&dev->vma_count),
332 high_memory, virt_to_phys(high_memory));
333 for (pt = dev->vmalist; pt; pt = pt->next) {
334 if (!(vma = pt->vma)) continue;
335 DRM_SYSCTL_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
336 pt->pid,
337 vma->vm_start,
338 vma->vm_end,
339 vma->vm_flags & VM_READ ? 'r' : '-',
340 vma->vm_flags & VM_WRITE ? 'w' : '-',
341 vma->vm_flags & VM_EXEC ? 'x' : '-',
342 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
343 vma->vm_flags & VM_LOCKED ? 'l' : '-',
344 vma->vm_flags & VM_IO ? 'i' : '-',
345 vma->vm_offset );
346 #if defined(__i386__)
347 pgprot = pgprot_val(vma->vm_page_prot);
348 DRM_SYSCTL_PRINT(" %c%c%c%c%c%c%c%c%c",
349 pgprot & _PAGE_PRESENT ? 'p' : '-',
350 pgprot & _PAGE_RW ? 'w' : 'r',
351 pgprot & _PAGE_USER ? 'u' : 's',
352 pgprot & _PAGE_PWT ? 't' : 'b',
353 pgprot & _PAGE_PCD ? 'u' : 'c',
354 pgprot & _PAGE_ACCESSED ? 'a' : '-',
355 pgprot & _PAGE_DIRTY ? 'd' : '-',
356 pgprot & _PAGE_4M ? 'm' : 'k',
357 pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
358 #endif
359 DRM_SYSCTL_PRINT("\n");
360 for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
361 pgd = pgd_offset(vma->vm_mm, i);
362 pmd = pmd_offset(pgd, i);
363 pte = pte_offset(pmd, i);
364 if (pte_present(*pte)) {
365 address = __pa(pte_page(*pte))
366 + (i & (PAGE_SIZE-1));
367 DRM_SYSCTL_PRINT(" 0x%08lx -> 0x%08lx"
368 " %c%c%c%c%c\n",
369 i,
370 address,
371 pte_read(*pte) ? 'r' : '-',
372 pte_write(*pte) ? 'w' : '-',
373 pte_exec(*pte) ? 'x' : '-',
374 pte_dirty(*pte) ? 'd' : '-',
375 pte_young(*pte) ? 'a' : '-' );
376 } else {
377 DRM_SYSCTL_PRINT(" 0x%08lx\n", i);
378 }
379 }
380 }
381
382 SYSCTL_OUT(req, "", 1);
383 return 0;
384 }
385
386 static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS
387 {
388 drm_device_t *dev = arg1;
389 int ret;
390
391 DRM_OS_LOCK;
392 ret = DRM(_vma_info)(oidp, arg1, arg2, req);
393 DRM_OS_UNLOCK;
394 return ret;
395 }
396 #endif
397
398
399 #if DRM_DMA_HISTOGRAM
400 static int DRM(_histo_info)DRM_SYSCTL_HANDLER_ARGS
401 {
402 drm_device_t *dev = arg1;
403 drm_device_dma_t *dma = dev->dma;
404 int i;
405 unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL;
406 unsigned long prev_value = 0;
407 drm_buf_t *buffer;
408 char buf[128];
409 int error;
410
411 DRM_SYSCTL_PRINT("general statistics:\n");
412 DRM_SYSCTL_PRINT("total %10u\n", atomic_read(&dev->histo.total));
413 DRM_SYSCTL_PRINT("open %10u\n", atomic_read(&dev->total_open));
414 DRM_SYSCTL_PRINT("close %10u\n", atomic_read(&dev->total_close));
415 DRM_SYSCTL_PRINT("ioctl %10u\n", atomic_read(&dev->total_ioctl));
416 DRM_SYSCTL_PRINT("irq %10u\n", atomic_read(&dev->total_irq));
417 DRM_SYSCTL_PRINT("ctx %10u\n", atomic_read(&dev->total_ctx));
418
419 DRM_SYSCTL_PRINT("\nlock statistics:\n");
420 DRM_SYSCTL_PRINT("locks %10u\n", atomic_read(&dev->total_locks));
421 DRM_SYSCTL_PRINT("unlocks %10u\n", atomic_read(&dev->total_unlocks));
422 DRM_SYSCTL_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
423 DRM_SYSCTL_PRINT("sleeps %10u\n", atomic_read(&dev->total_sleeps));
424
425
426 if (dma) {
427 DRM_SYSCTL_PRINT("\ndma statistics:\n");
428 DRM_SYSCTL_PRINT("prio %10u\n",
429 atomic_read(&dma->total_prio));
430 DRM_SYSCTL_PRINT("bytes %10u\n",
431 atomic_read(&dma->total_bytes));
432 DRM_SYSCTL_PRINT("dmas %10u\n",
433 atomic_read(&dma->total_dmas));
434 DRM_SYSCTL_PRINT("missed:\n");
435 DRM_SYSCTL_PRINT(" dma %10u\n",
436 atomic_read(&dma->total_missed_dma));
437 DRM_SYSCTL_PRINT(" lock %10u\n",
438 atomic_read(&dma->total_missed_lock));
439 DRM_SYSCTL_PRINT(" free %10u\n",
440 atomic_read(&dma->total_missed_free));
441 DRM_SYSCTL_PRINT(" sched %10u\n",
442 atomic_read(&dma->total_missed_sched));
443 DRM_SYSCTL_PRINT("tried %10u\n",
444 atomic_read(&dma->total_tried));
445 DRM_SYSCTL_PRINT("hit %10u\n",
446 atomic_read(&dma->total_hit));
447 DRM_SYSCTL_PRINT("lost %10u\n",
448 atomic_read(&dma->total_lost));
449
450 buffer = dma->next_buffer;
451 if (buffer) {
452 DRM_SYSCTL_PRINT("next_buffer %7d\n", buffer->idx);
453 } else {
454 DRM_SYSCTL_PRINT("next_buffer none\n");
455 }
456 buffer = dma->this_buffer;
457 if (buffer) {
458 DRM_SYSCTL_PRINT("this_buffer %7d\n", buffer->idx);
459 } else {
460 DRM_SYSCTL_PRINT("this_buffer none\n");
461 }
462 }
463
464
465 DRM_SYSCTL_PRINT("\nvalues:\n");
466 if (dev->lock.hw_lock) {
467 DRM_SYSCTL_PRINT("lock 0x%08x\n",
468 dev->lock.hw_lock->lock);
469 } else {
470 DRM_SYSCTL_PRINT("lock none\n");
471 }
472 DRM_SYSCTL_PRINT("context_flag 0x%08x\n", dev->context_flag);
473 DRM_SYSCTL_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
474 DRM_SYSCTL_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
475
476 DRM_SYSCTL_PRINT("queue_count %10d\n", dev->queue_count);
477 DRM_SYSCTL_PRINT("last_context %10d\n", dev->last_context);
478 DRM_SYSCTL_PRINT("last_switch %10u\n", dev->last_switch);
479 DRM_SYSCTL_PRINT("last_checked %10d\n", dev->last_checked);
480
481
482 DRM_SYSCTL_PRINT("\n q2d d2c c2f"
483 " q2c q2f dma sch"
484 " ctx lacq lhld\n\n");
485 for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
486 DRM_SYSCTL_PRINT("%s %10lu %10u %10u %10u %10u %10u"
487 " %10u %10u %10u %10u %10u\n",
488 i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
489 i == DRM_DMA_HISTOGRAM_SLOTS - 1
490 ? prev_value : slot_value ,
491
492 atomic_read(&dev->histo
493 .queued_to_dispatched[i]),
494 atomic_read(&dev->histo
495 .dispatched_to_completed[i]),
496 atomic_read(&dev->histo
497 .completed_to_freed[i]),
498
499 atomic_read(&dev->histo
500 .queued_to_completed[i]),
501 atomic_read(&dev->histo
502 .queued_to_freed[i]),
503 atomic_read(&dev->histo.dma[i]),
504 atomic_read(&dev->histo.schedule[i]),
505 atomic_read(&dev->histo.ctx[i]),
506 atomic_read(&dev->histo.lacq[i]),
507 atomic_read(&dev->histo.lhld[i]));
508 prev_value = slot_value;
509 slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
510 }
511 SYSCTL_OUT(req, "", 1);
512 return 0;
513 }
514
515 static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS
516 {
517 drm_device_t *dev = arg1;
518 int ret;
519
520 DRM_OS_LOCK;
521 ret = _drm_histo_info(oidp, arg1, arg2, req);
522 DRM_OS_UNLOCK;
523 return ret;
524 }
525 #endif
Cache object: b6a854691ff447da208961e700a3cef3
|