From cd97146ad0783f80abf41ed31ec881d90e6b7c27 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 9 Jul 2014 13:01:10 +0900 Subject: [PATCH] drm/exynos: debugfs: add debugfs interface and gem_info node The memps requires gem_info with gem_names to analyze graphics(video) shared memory, so adds gem_info node with debugfs interface. Change-Id: Ia923aa53c1508174e874d36001f53b0c42daac21 Signed-off-by: YoungJun Cho --- drivers/gpu/drm/exynos/Makefile | 1 + drivers/gpu/drm/exynos/exynos_drm_debugfs.c | 93 +++++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_debugfs.h | 27 +++++++++ drivers/gpu/drm/exynos/exynos_drm_drv.c | 9 +++ drivers/gpu/drm/exynos/exynos_drm_drv.h | 3 + 5 files changed, 133 insertions(+) create mode 100644 drivers/gpu/drm/exynos/exynos_drm_debugfs.c create mode 100644 drivers/gpu/drm/exynos/exynos_drm_debugfs.h diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 6944db4..f011cfb 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile @@ -22,5 +22,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC) += exynos_drm_fimc.o exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += exynos_drm_rotator.o exynosdrm-$(CONFIG_DRM_EXYNOS_GSC) += exynos_drm_gsc.o exynosdrm-$(CONFIG_DRM_EXYNOS_SC) += exynos_drm_sc.o +exynosdrm-$(CONFIG_DEBUG_FS) += exynos_drm_debugfs.o obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o diff --git a/drivers/gpu/drm/exynos/exynos_drm_debugfs.c b/drivers/gpu/drm/exynos/exynos_drm_debugfs.c new file mode 100644 index 0000000..ad65c7b --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_drm_debugfs.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd + * Author: YoungJun Cho + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include + +#include + +#include "exynos_drm_drv.h" +#include "exynos_drm_gem.h" + +struct exynos_drm_debugfs_gem_info_data { + struct drm_file *filp; + struct seq_file *m; +}; + +static int exynos_drm_debugfs_gem_one_info(int id, void *ptr, void *data) +{ + struct exynos_drm_debugfs_gem_info_data *gem_info_data = + (struct exynos_drm_debugfs_gem_info_data *)data; + struct drm_file *filp = gem_info_data->filp; + struct drm_exynos_file_private *file_priv = filp->driver_priv; + struct drm_gem_object *obj = (struct drm_gem_object *)ptr; + struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); + struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; + + seq_printf(gem_info_data->m, + "%5d\t%5d\t%4d\t%4d\t%4d\t0x%08lx\t0x%x\t%4d\t%4d\t" + "%4d\t0x%p\n", + pid_nr(filp->pid), + file_priv->tgid, + id, + atomic_read(&obj->refcount.refcount), + obj->handle_count, + exynos_gem_obj->size, + exynos_gem_obj->flags, + buf->pfnmap, + obj->dma_buf ? 1 : 0, + obj->import_attach ? 1 : 0, + obj); + + return 0; +} + +static int exynos_drm_debugfs_gem_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *)m->private; + struct drm_minor *minor = node->minor; + struct drm_device *drm_dev = minor->dev; + struct exynos_drm_debugfs_gem_info_data gem_info_data; + struct drm_file *filp; + + gem_info_data.m = m; + + seq_puts(m, "pid\ttgid\thandle\tref_cnt\thdl_cnt\tsize\t\tflags\t" + "pfnmap\texport\timport\tobj_addr\n"); + + mutex_lock(&drm_dev->struct_mutex); + list_for_each_entry(filp, &drm_dev->filelist, lhead) { + gem_info_data.filp = filp; + + spin_lock(&filp->table_lock); + idr_for_each(&filp->object_idr, exynos_drm_debugfs_gem_one_info, + &gem_info_data); + spin_unlock(&filp->table_lock); + } + mutex_unlock(&drm_dev->struct_mutex); + + return 0; +} + +static struct drm_info_list exynos_drm_debugfs_list[] = { + {"gem_info", exynos_drm_debugfs_gem_info, DRIVER_GEM}, +}; +#define EXYNOS_DRM_DEBUGFS_ENTRIES ARRAY_SIZE(exynos_drm_debugfs_list) + +int exynos_drm_debugfs_init(struct drm_minor *minor) +{ + return drm_debugfs_create_files(exynos_drm_debugfs_list, + EXYNOS_DRM_DEBUGFS_ENTRIES, + minor->debugfs_root, minor); +} + +void exynos_drm_debugfs_cleanup(struct drm_minor *minor) +{ + drm_debugfs_remove_files(exynos_drm_debugfs_list, + EXYNOS_DRM_DEBUGFS_ENTRIES, minor); +} diff --git a/drivers/gpu/drm/exynos/exynos_drm_debugfs.h b/drivers/gpu/drm/exynos/exynos_drm_debugfs.h new file mode 100644 index 0000000..17a50b2 --- /dev/null +++ b/drivers/gpu/drm/exynos/exynos_drm_debugfs.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Samsung Electronics Co.Ltd + * Author: YoungJun Cho + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundationr + */ + +#ifndef _EXYNOS_DRM_DEBUGFS_H_ +#define _EXYNOS_DRM_DEBUGFS_H_ + +#if defined(CONFIG_DEBUG_FS) +extern int exynos_drm_debugfs_init(struct drm_minor *minor); +extern void exynos_drm_debugfs_cleanup(struct drm_minor *minor); +#else +static inline int exynos_drm_debugfs_init(struct drm_minor *minor) +{ + return 0; +} + +static inline void exynos_drm_debugfs_cleanup(struct drm_minor *minor) +{ +} +#endif + +#endif /* _EXYNOS_DRM_DEBUGFS_H_ */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 8fc02be..89285b0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -32,6 +32,7 @@ #include "exynos_drm_ipp.h" #include "exynos_drm_iommu.h" #include "exynos_drm_iommu_init.h" +#include "exynos_drm_debugfs.h" #define DRIVER_NAME "exynos" #define DRIVER_DESC "Samsung SoC DRM" @@ -205,6 +206,10 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) if (!file_priv) return -ENOMEM; +#if defined(CONFIG_DEBUG_FS) + file_priv->tgid = task_tgid_nr(current); +#endif + file->driver_priv = file_priv; ret = exynos_drm_subdrv_open(dev, file); @@ -340,6 +345,10 @@ static struct drm_driver exynos_drm_driver = { .get_vblank_counter = drm_vblank_count, .enable_vblank = exynos_drm_crtc_enable_vblank, .disable_vblank = exynos_drm_crtc_disable_vblank, +#if defined(CONFIG_DEBUG_FS) + .debugfs_init = exynos_drm_debugfs_init, + .debugfs_cleanup = exynos_drm_debugfs_cleanup, +#endif .gem_init_object = exynos_drm_gem_init_object, .gem_free_object = exynos_drm_gem_free_object, .gem_vm_ops = &exynos_drm_gem_vm_ops, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 1a790b1..d93adc9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -263,6 +263,9 @@ struct drm_exynos_file_private { struct exynos_drm_g2d_private *g2d_priv; struct exynos_drm_ipp_private *ipp_priv; struct file *anon_filp; +#if defined(CONFIG_DEBUG_FS) + pid_t tgid; +#endif }; /* -- 2.7.4