[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu

[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu

[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu

[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu

[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu

[PATCH v3 2/2] dma-buf: Add debugfs support

2013-04-03 Thread Sumit Semwal
Add debugfs support to make it easier to print debug information
about the dma-buf buffers.

Cc: Dave Airlie 
 [minor fixes on init and warning fix]
Signed-off-by: Sumit Semwal 
---
changes since v2: (based on review comments from Laurent Pinchart)
 - reordered functions to avoid forward declaration
 - added __exitcall for dma_buf_deinit()

changes since v1:
 - fixes on init and warnings as reported and corrected by Dave Airlie.
 - add locking while walking attachment list - reported by Daniel Vetter.
---
 drivers/base/dma-buf.c  |  159 +++
 include/linux/dma-buf.h |5 +-
 2 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index d89102a..466476f 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,9 +27,18 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
+struct dma_buf_list {
+   struct list_head head;
+   struct mutex lock;
+};
+
+static struct dma_buf_list db_list;
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
struct dma_buf *dmabuf;
@@ -42,6 +51,11 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
BUG_ON(dmabuf->vmapping_counter);
 
dmabuf->ops->release(dmabuf);
+
+   mutex_lock(&db_list.lock);
+   list_del(&dmabuf->list_node);
+   mutex_unlock(&db_list.lock);
+
kfree(dmabuf);
return 0;
 }
@@ -125,6 +139,10 @@ struct dma_buf *dma_buf_export_named(void *priv, const 
struct dma_buf_ops *ops,
mutex_init(&dmabuf->lock);
INIT_LIST_HEAD(&dmabuf->attachments);
 
+   mutex_lock(&db_list.lock);
+   list_add(&dmabuf->list_node, &db_list.head);
+   mutex_unlock(&db_list.lock);
+
return dmabuf;
 }
 EXPORT_SYMBOL_GPL(dma_buf_export_named);
@@ -551,3 +569,144 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
mutex_unlock(&dmabuf->lock);
 }
 EXPORT_SYMBOL_GPL(dma_buf_vunmap);
+
+#ifdef CONFIG_DEBUG_FS
+static int dma_buf_describe(struct seq_file *s)
+{
+   int ret;
+   struct dma_buf *buf_obj;
+   struct dma_buf_attachment *attach_obj;
+   int count = 0, attach_count;
+   size_t size = 0;
+
+   ret = mutex_lock_interruptible(&db_list.lock);
+
+   if (ret)
+   return ret;
+
+   seq_printf(s, "\nDma-buf Objects:\n");
+   seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n");
+
+   list_for_each_entry(buf_obj, &db_list.head, list_node) {
+   ret = mutex_lock_interruptible(&buf_obj->lock);
+
+   if (ret) {
+   seq_printf(s,
+ "\tERROR locking buffer object: skipping\n");
+   goto skip_buffer;
+   }
+
+   seq_printf(s, "\t");
+
+   seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08d\n",
+   buf_obj->exp_name, buf_obj->size,
+   buf_obj->file->f_flags, buf_obj->file->f_mode,
+   buf_obj->file->f_count.counter);
+
+   seq_printf(s, "\t\tAttached Devices:\n");
+   attach_count = 0;
+
+   list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
+   seq_printf(s, "\t\t");
+
+   seq_printf(s, "%s\n", attach_obj->dev->init_name);
+   attach_count++;
+   }
+
+   seq_printf(s, "\n\t\tTotal %d devices attached\n",
+   attach_count);
+
+   count++;
+   size += buf_obj->size;
+skip_buffer:
+   mutex_unlock(&buf_obj->lock);
+   }
+
+   seq_printf(s, "\nTotal %d objects, %zu bytes\n", count, size);
+
+   mutex_unlock(&db_list.lock);
+   return 0;
+}
+
+static int dma_buf_show(struct seq_file *s, void *unused)
+{
+   void (*func)(struct seq_file *) = s->private;
+   func(s);
+   return 0;
+}
+
+static int dma_buf_debug_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, dma_buf_show, inode->i_private);
+}
+
+static const struct file_operations dma_buf_debug_fops = {
+   .open   = dma_buf_debug_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static struct dentry *dma_buf_debugfs_dir;
+
+static int dma_buf_init_debugfs(void)
+{
+   int err = 0;
+   dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL);
+   if (IS_ERR(dma_buf_debugfs_dir)) {
+   err = PTR_ERR(dma_buf_debugfs_dir);
+   dma_buf_debugfs_dir = NULL;
+   return err;
+   }
+
+   err = dma_buf_debugfs_create_file("bufinfo", dma_buf_describe);
+
+   if (err)
+   pr_debug("dma_buf: debugfs: failed to create node bufinfo\n");
+
+   return err;
+}
+
+static void dma_bu