diff options
Diffstat (limited to 'drivers/gpu/drm/drm_proc.c')
-rw-r--r-- | drivers/gpu/drm/drm_proc.c | 135 |
1 files changed, 122 insertions, 13 deletions
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 93b1e0475c93..d490db4c0de0 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset, | |||
49 | int request, int *eof, void *data); | 49 | int request, int *eof, void *data); |
50 | static int drm_bufs_info(char *buf, char **start, off_t offset, | 50 | static int drm_bufs_info(char *buf, char **start, off_t offset, |
51 | int request, int *eof, void *data); | 51 | int request, int *eof, void *data); |
52 | static int drm_gem_name_info(char *buf, char **start, off_t offset, | ||
53 | int request, int *eof, void *data); | ||
54 | static int drm_gem_object_info(char *buf, char **start, off_t offset, | ||
55 | int request, int *eof, void *data); | ||
52 | #if DRM_DEBUG_CODE | 56 | #if DRM_DEBUG_CODE |
53 | static int drm_vma_info(char *buf, char **start, off_t offset, | 57 | static int drm_vma_info(char *buf, char **start, off_t offset, |
54 | int request, int *eof, void *data); | 58 | int request, int *eof, void *data); |
@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset, | |||
60 | static struct drm_proc_list { | 64 | static struct drm_proc_list { |
61 | const char *name; /**< file name */ | 65 | const char *name; /**< file name */ |
62 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ | 66 | int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ |
67 | u32 driver_features; /**< Required driver features for this entry */ | ||
63 | } drm_proc_list[] = { | 68 | } drm_proc_list[] = { |
64 | {"name", drm_name_info}, | 69 | {"name", drm_name_info, 0}, |
65 | {"mem", drm_mem_info}, | 70 | {"mem", drm_mem_info, 0}, |
66 | {"vm", drm_vm_info}, | 71 | {"vm", drm_vm_info, 0}, |
67 | {"clients", drm_clients_info}, | 72 | {"clients", drm_clients_info, 0}, |
68 | {"queues", drm_queues_info}, | 73 | {"queues", drm_queues_info, 0}, |
69 | {"bufs", drm_bufs_info}, | 74 | {"bufs", drm_bufs_info, 0}, |
75 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, | ||
76 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, | ||
70 | #if DRM_DEBUG_CODE | 77 | #if DRM_DEBUG_CODE |
71 | {"vma", drm_vma_info}, | 78 | {"vma", drm_vma_info}, |
72 | #endif | 79 | #endif |
@@ -90,8 +97,9 @@ static struct drm_proc_list { | |||
90 | int drm_proc_init(struct drm_minor *minor, int minor_id, | 97 | int drm_proc_init(struct drm_minor *minor, int minor_id, |
91 | struct proc_dir_entry *root) | 98 | struct proc_dir_entry *root) |
92 | { | 99 | { |
100 | struct drm_device *dev = minor->dev; | ||
93 | struct proc_dir_entry *ent; | 101 | struct proc_dir_entry *ent; |
94 | int i, j; | 102 | int i, j, ret; |
95 | char name[64]; | 103 | char name[64]; |
96 | 104 | ||
97 | sprintf(name, "%d", minor_id); | 105 | sprintf(name, "%d", minor_id); |
@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
102 | } | 110 | } |
103 | 111 | ||
104 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { | 112 | for (i = 0; i < DRM_PROC_ENTRIES; i++) { |
113 | u32 features = drm_proc_list[i].driver_features; | ||
114 | |||
115 | if (features != 0 && | ||
116 | (dev->driver->driver_features & features) != features) | ||
117 | continue; | ||
118 | |||
105 | ent = create_proc_entry(drm_proc_list[i].name, | 119 | ent = create_proc_entry(drm_proc_list[i].name, |
106 | S_IFREG | S_IRUGO, minor->dev_root); | 120 | S_IFREG | S_IRUGO, minor->dev_root); |
107 | if (!ent) { | 121 | if (!ent) { |
108 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", | 122 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
109 | name, drm_proc_list[i].name); | 123 | name, drm_proc_list[i].name); |
110 | for (j = 0; j < i; j++) | 124 | ret = -1; |
111 | remove_proc_entry(drm_proc_list[i].name, | 125 | goto fail; |
112 | minor->dev_root); | ||
113 | remove_proc_entry(name, root); | ||
114 | minor->dev_root = NULL; | ||
115 | return -1; | ||
116 | } | 126 | } |
117 | ent->read_proc = drm_proc_list[i].f; | 127 | ent->read_proc = drm_proc_list[i].f; |
118 | ent->data = minor; | 128 | ent->data = minor; |
119 | } | 129 | } |
120 | 130 | ||
131 | if (dev->driver->proc_init) { | ||
132 | ret = dev->driver->proc_init(minor); | ||
133 | if (ret) { | ||
134 | DRM_ERROR("DRM: Driver failed to initialize " | ||
135 | "/proc/dri.\n"); | ||
136 | goto fail; | ||
137 | } | ||
138 | } | ||
139 | |||
121 | return 0; | 140 | return 0; |
141 | fail: | ||
142 | |||
143 | for (j = 0; j < i; j++) | ||
144 | remove_proc_entry(drm_proc_list[i].name, | ||
145 | minor->dev_root); | ||
146 | remove_proc_entry(name, root); | ||
147 | minor->dev_root = NULL; | ||
148 | return ret; | ||
122 | } | 149 | } |
123 | 150 | ||
124 | /** | 151 | /** |
@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
133 | */ | 160 | */ |
134 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) | 161 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) |
135 | { | 162 | { |
163 | struct drm_device *dev = minor->dev; | ||
136 | int i; | 164 | int i; |
137 | char name[64]; | 165 | char name[64]; |
138 | 166 | ||
139 | if (!root || !minor->dev_root) | 167 | if (!root || !minor->dev_root) |
140 | return 0; | 168 | return 0; |
141 | 169 | ||
170 | if (dev->driver->proc_cleanup) | ||
171 | dev->driver->proc_cleanup(minor); | ||
172 | |||
142 | for (i = 0; i < DRM_PROC_ENTRIES; i++) | 173 | for (i = 0; i < DRM_PROC_ENTRIES; i++) |
143 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); | 174 | remove_proc_entry(drm_proc_list[i].name, minor->dev_root); |
144 | sprintf(name, "%d", minor->index); | 175 | sprintf(name, "%d", minor->index); |
@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset, | |||
480 | return ret; | 511 | return ret; |
481 | } | 512 | } |
482 | 513 | ||
514 | struct drm_gem_name_info_data { | ||
515 | int len; | ||
516 | char *buf; | ||
517 | int eof; | ||
518 | }; | ||
519 | |||
520 | static int drm_gem_one_name_info(int id, void *ptr, void *data) | ||
521 | { | ||
522 | struct drm_gem_object *obj = ptr; | ||
523 | struct drm_gem_name_info_data *nid = data; | ||
524 | |||
525 | DRM_INFO("name %d size %d\n", obj->name, obj->size); | ||
526 | if (nid->eof) | ||
527 | return 0; | ||
528 | |||
529 | nid->len += sprintf(&nid->buf[nid->len], | ||
530 | "%6d%9d%8d%9d\n", | ||
531 | obj->name, obj->size, | ||
532 | atomic_read(&obj->handlecount.refcount), | ||
533 | atomic_read(&obj->refcount.refcount)); | ||
534 | if (nid->len > DRM_PROC_LIMIT) { | ||
535 | nid->eof = 1; | ||
536 | return 0; | ||
537 | } | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | static int drm_gem_name_info(char *buf, char **start, off_t offset, | ||
542 | int request, int *eof, void *data) | ||
543 | { | ||
544 | struct drm_minor *minor = (struct drm_minor *) data; | ||
545 | struct drm_device *dev = minor->dev; | ||
546 | struct drm_gem_name_info_data nid; | ||
547 | |||
548 | if (offset > DRM_PROC_LIMIT) { | ||
549 | *eof = 1; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | nid.len = sprintf(buf, " name size handles refcount\n"); | ||
554 | nid.buf = buf; | ||
555 | nid.eof = 0; | ||
556 | idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid); | ||
557 | |||
558 | *start = &buf[offset]; | ||
559 | *eof = 0; | ||
560 | if (nid.len > request + offset) | ||
561 | return request; | ||
562 | *eof = 1; | ||
563 | return nid.len - offset; | ||
564 | } | ||
565 | |||
566 | static int drm_gem_object_info(char *buf, char **start, off_t offset, | ||
567 | int request, int *eof, void *data) | ||
568 | { | ||
569 | struct drm_minor *minor = (struct drm_minor *) data; | ||
570 | struct drm_device *dev = minor->dev; | ||
571 | int len = 0; | ||
572 | |||
573 | if (offset > DRM_PROC_LIMIT) { | ||
574 | *eof = 1; | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | *start = &buf[offset]; | ||
579 | *eof = 0; | ||
580 | DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count)); | ||
581 | DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); | ||
582 | DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); | ||
583 | DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); | ||
584 | DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); | ||
585 | DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); | ||
586 | if (len > request + offset) | ||
587 | return request; | ||
588 | *eof = 1; | ||
589 | return len - offset; | ||
590 | } | ||
591 | |||
483 | #if DRM_DEBUG_CODE | 592 | #if DRM_DEBUG_CODE |
484 | 593 | ||
485 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, | 594 | static int drm__vma_info(char *buf, char **start, off_t offset, int request, |