aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_proc.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-07-30 15:06:12 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:12 -0400
commit673a394b1e3b69be886ff24abfd6df97c52e8d08 (patch)
tree61ca8299333ab50ffc46cf328b20eb25133392ff /drivers/gpu/drm/drm_proc.c
parentd1d8c925b71dd6753bf438f9e14a9e5c5183bcc6 (diff)
drm: Add GEM ("graphics execution manager") to i915 driver.
GEM allows the creation of persistent buffer objects accessible by the graphics device through new ioctls for managing execution of commands on the device. The userland API is almost entirely driver-specific to ensure that any driver building on this model can easily map the interface to individual driver requirements. GEM is used by the 2d driver for managing its internal state allocations and will be used for pixmap storage to reduce memory consumption and enable zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_proc.c')
-rw-r--r--drivers/gpu/drm/drm_proc.c135
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);
50static int drm_bufs_info(char *buf, char **start, off_t offset, 50static 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);
52static int drm_gem_name_info(char *buf, char **start, off_t offset,
53 int request, int *eof, void *data);
54static 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
53static int drm_vma_info(char *buf, char **start, off_t offset, 57static 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,
60static struct drm_proc_list { 64static 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 {
90int drm_proc_init(struct drm_minor *minor, int minor_id, 97int 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 */
134int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) 161int 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
514struct drm_gem_name_info_data {
515 int len;
516 char *buf;
517 int eof;
518};
519
520static 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
541static 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
566static 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
485static int drm__vma_info(char *buf, char **start, off_t offset, int request, 594static int drm__vma_info(char *buf, char **start, off_t offset, int request,