diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-17 15:09:20 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-17 15:09:20 -0700 |
commit | f7ea4a4ba84f382e8eb143e435551de0feee5b4b (patch) | |
tree | 0771d5413f1b9104816ca0ddec21c5503d562a3d /drivers/gpu/drm/drm_proc.c | |
parent | 5564da7e9d12ea80745f66c8d2ec7bd00f3f94eb (diff) | |
parent | 4b40893918203ee1a1f6a114316c2a19c072e9bd (diff) | |
download | talos-op-linux-f7ea4a4ba84f382e8eb143e435551de0feee5b4b.tar.gz talos-op-linux-f7ea4a4ba84f382e8eb143e435551de0feee5b4b.zip |
Merge branch 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (44 commits)
drm/i915: fix ioremap of a user address for non-root (CVE-2008-3831)
drm: make CONFIG_DRM depend on CONFIG_SHMEM.
radeon: fix PCI bus mastering support enables.
radeon: add RS400 family support.
drm/radeon: add support for RS740 IGP chipsets.
i915: GM45 has GM965-style MCH setup.
i915: Don't run retire work handler while suspended
i915: Map status page cached for chips with GTT-based HWS location.
i915: Fix up ring initialization to cover G45 oddities
i915: Use non-reserved status page index for breadcrumb
drm: Increment dev_priv->irq_received so i915_gem_interrupts count works.
drm: kill drm_device->irq
drm: wbinvd is cache coherent.
i915: add missing return in error path.
i915: fixup permissions on gem ioctls.
drm: Clean up many sparse warnings in i915.
drm: Use ioremap_wc in i915_driver instead of ioremap, since we always want WC.
drm: G33-class hardware has a newer 965-style MCH (no DCC register).
drm: Avoid oops in GEM execbuffers with bad arguments.
DRM: Return -EBADF on bad object in flink, and return curent name if it exists.
...
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, int request, int *eof, void *data); static int drm_bufs_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); @@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset, static struct drm_proc_list { const char *name; /**< file name */ int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ + u32 driver_features; /**< Required driver features for this entry */ } drm_proc_list[] = { - {"name", drm_name_info}, - {"mem", drm_mem_info}, - {"vm", drm_vm_info}, - {"clients", drm_clients_info}, - {"queues", drm_queues_info}, - {"bufs", drm_bufs_info}, + {"name", drm_name_info, 0}, + {"mem", drm_mem_info, 0}, + {"vm", drm_vm_info, 0}, + {"clients", drm_clients_info, 0}, + {"queues", drm_queues_info, 0}, + {"bufs", drm_bufs_info, 0}, + {"gem_names", drm_gem_name_info, DRIVER_GEM}, + {"gem_objects", drm_gem_object_info, DRIVER_GEM}, #if DRM_DEBUG_CODE {"vma", drm_vma_info}, #endif @@ -90,8 +97,9 @@ static struct drm_proc_list { int drm_proc_init(struct drm_minor *minor, int minor_id, struct proc_dir_entry *root) { + struct drm_device *dev = minor->dev; struct proc_dir_entry *ent; - int i, j; + int i, j, ret; char name[64]; sprintf(name, "%d", minor_id); @@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, } for (i = 0; i < DRM_PROC_ENTRIES; i++) { + u32 features = drm_proc_list[i].driver_features; + + if (features != 0 && + (dev->driver->driver_features & features) != features) + continue; + ent = create_proc_entry(drm_proc_list[i].name, S_IFREG | S_IRUGO, minor->dev_root); if (!ent) { DRM_ERROR("Cannot create /proc/dri/%s/%s\n", name, drm_proc_list[i].name); - for (j = 0; j < i; j++) - remove_proc_entry(drm_proc_list[i].name, - minor->dev_root); - remove_proc_entry(name, root); - minor->dev_root = NULL; - return -1; + ret = -1; + goto fail; } ent->read_proc = drm_proc_list[i].f; ent->data = minor; } + if (dev->driver->proc_init) { + ret = dev->driver->proc_init(minor); + if (ret) { + DRM_ERROR("DRM: Driver failed to initialize " + "/proc/dri.\n"); + goto fail; + } + } + return 0; + fail: + + for (j = 0; j < i; j++) + remove_proc_entry(drm_proc_list[i].name, + minor->dev_root); + remove_proc_entry(name, root); + minor->dev_root = NULL; + return ret; } /** @@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, */ int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) { + struct drm_device *dev = minor->dev; int i; char name[64]; if (!root || !minor->dev_root) return 0; + if (dev->driver->proc_cleanup) + dev->driver->proc_cleanup(minor); + for (i = 0; i < DRM_PROC_ENTRIES; i++) remove_proc_entry(drm_proc_list[i].name, minor->dev_root); sprintf(name, "%d", minor->index); @@ -480,6 +511,84 @@ 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)); + DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); + DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); + DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); + DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); + DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); + 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, |