summaryrefslogtreecommitdiff
path: root/linux-core/drm_proc.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-02 16:34:16 -0700
committerKeith Packard <keithp@keithp.com>2008-05-02 16:34:16 -0700
commitab3549d1336fc6c08581a9fd14a83513649d9187 (patch)
treed267f50992fa987d8aca0aa19d2af015134c8cc9 /linux-core/drm_proc.c
parent39e20bcd5f4bf9fedac80188fda2e9fcab2f0360 (diff)
Add a bit of /proc/dri/*/gem support. Clean up some refcount/pagelock issues.
Track named objects in /proc/dri/0/gem_names. Track total object count in /proc/dri/0/gem_objects. Initialize device gem data. return -ENODEV for gem ioctls if the driver doesn't support gem. Call unlock_page when unbinding from gtt. Add numerous misssing calls to drm_gem_object_unreference.
Diffstat (limited to 'linux-core/drm_proc.c')
-rw-r--r--linux-core/drm_proc.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c
index 42da5c69..b1b976b2 100644
--- a/linux-core/drm_proc.c
+++ b/linux-core/drm_proc.c
@@ -51,6 +51,10 @@ static int drm_bufs_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int drm_objects_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
+static int drm_gem_name_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_gem_object_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
#if DRM_DEBUG_CODE
static int drm_vma_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
@@ -70,6 +74,8 @@ static struct drm_proc_list {
{"queues", drm_queues_info},
{"bufs", drm_bufs_info},
{"objects", drm_objects_info},
+ {"gem_names", drm_gem_name_info},
+ {"gem_objects", drm_gem_object_info},
#if DRM_DEBUG_CODE
{"vma", drm_vma_info},
#endif
@@ -582,6 +588,79 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
return ret;
}
+struct drm_gem_name_info_data {
+ int len;
+ char *buf;
+ int eof;
+};
+
+static int drm_gem_one_name_info (int id, void *ptr, void *data)
+{
+ struct drm_gem_object *obj = ptr;
+ struct drm_gem_name_info_data *nid = data;
+
+ DRM_INFO ("name %d size %d\n", obj->name, obj->size);
+ if (nid->eof)
+ return 0;
+
+ nid->len += sprintf (&nid->buf[nid->len],
+ "%6d%9d%8d%9d\n",
+ obj->name, obj->size,
+ atomic_read(&obj->handlecount.refcount),
+ atomic_read(&obj->refcount.refcount));
+ if (nid->len > DRM_PROC_LIMIT) {
+ nid->eof = 1;
+ return 0;
+ }
+ return 0;
+}
+
+static int drm_gem_name_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ struct drm_gem_name_info_data nid;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ nid.len = sprintf (buf, " name size handles refcount\n");
+ nid.buf = buf;
+ nid.eof = 0;
+ idr_for_each (&dev->object_name_idr, drm_gem_one_name_info, &nid);
+
+ *start = &buf[offset];
+ *eof = 0;
+ if (nid.len > request + offset)
+ return request;
+ *eof = 1;
+ return nid.len - offset;
+}
+
+static int drm_gem_object_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT ("%d objects\n", atomic_read (&dev->object_count));
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
#if DRM_DEBUG_CODE
static int drm__vma_info(char *buf, char **start, off_t offset, int request,