public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Add simple way to add statistic counters to debugfs
@ 2011-12-02 18:43 Andi Kleen
  2011-12-02 18:43 ` [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files Andi Kleen
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Andi Kleen @ 2011-12-02 18:43 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, linux-fsdevel, fengguang.wu

This extends debugfs to make it very simple to add per cpu counters
statistics that are exported there. This is useful for all kind
of debugging situations. The counters have very little overhead
and are simpler to use than trace points.

This is the infrastructure for debugfs and a demo application 
to instrument the dcache RCU which I developed some time ago
to track down some problems there.

Posting here also so that Fengguang can use it.

Module support is still missing, but could be added without too 
much work.

-Andi


^ permalink raw reply	[flat|nested] 20+ messages in thread
* [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files v2
@ 2011-12-02 20:02 Andi Kleen
  2011-12-02 20:02 ` [PATCH 2/3] DEBUGFS: Add per cpu counters Andi Kleen
  0 siblings, 1 reply; 20+ messages in thread
From: Andi Kleen @ 2011-12-02 20:02 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Allow passing path names to debugfs_create* and automatically create
the parents. This makes it much simpler for the caller to create hierarchies.

The way the reference counts are handled is admittedly a bit ugly.

There is no way to clean them up currently other than to delete the tree,
but that doesn't seem like a big problem for debugfs to leave
behind a few empty directories.

v2: Comment fixes based on review comments.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 fs/debugfs/inode.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index f3a257d..b66ab79 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -146,6 +146,55 @@ static struct file_system_type debug_fs_type = {
 	.kill_sb =	kill_litter_super,
 };
 
+/*
+ * Created parents stay around later. Sorry, but it shouldn't be a big issue.
+ */
+static const char *create_parents(const char *name, struct dentry *parent,
+				  struct dentry **pp, int *ref)
+{
+	char fn[strlen(name) + 1];
+	char *tail;
+	char *s, *p;
+	struct dentry *new_parent, *dentry, *old_parent = NULL;
+
+	strcpy(fn, name);
+	tail = strrchr(fn, '/');
+	if (!tail)
+		return name;
+	tail++;
+
+	s = fn;
+	while ((p = strsep(&s, "/")) != NULL && p != tail) {
+		/* 
+ 		 * When the parent already exists, this will error out.
+ 		 * Ignore that error. We'll just look the dentry up below.
+ 		 */
+		dentry = debugfs_create_dir(p, parent);
+
+		/* Is it there now? */
+		mutex_lock(&parent->d_inode->i_mutex);
+		new_parent = lookup_one_len(p, parent, strlen(p));
+		mutex_unlock(&parent->d_inode->i_mutex);
+
+		if (!PTR_ERR(dentry))
+			dput(dentry);
+		if (IS_ERR(new_parent))
+			return NULL;
+		if (old_parent)
+			dput(old_parent);
+		if (parent != *pp)
+			old_parent = parent;
+		parent = new_parent;
+	}
+	if (parent) {
+		*ref = 1;
+		*pp = parent;
+	}
+	if (old_parent)
+		dput(old_parent);
+	return strrchr(name, '/') + 1;
+}
+
 static int debugfs_create_by_name(const char *name, mode_t mode,
 				  struct dentry *parent,
 				  struct dentry **dentry,
@@ -153,6 +202,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 				  const struct file_operations *fops)
 {
 	int error = 0;
+	int ref = 0;
 
 	/* If the parent is not specified, we create it in the root.
 	 * We need the root dentry to do this, which is in the super 
@@ -161,6 +211,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 	 */
 	if (!parent)
 		parent = debugfs_mount->mnt_sb->s_root;
+	name = create_parents(name, parent, &parent, &ref);
 
 	*dentry = NULL;
 	mutex_lock(&parent->d_inode->i_mutex);
@@ -185,12 +236,17 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 		error = PTR_ERR(*dentry);
 	mutex_unlock(&parent->d_inode->i_mutex);
 
+	if (ref)
+		dput(parent);
+
 	return error;
 }
 
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
  * @name: a pointer to a string containing the name of the file to create.
+ *        This can also contain directories (dir/file), in this case missing
+ *        directories will be automatically created.
  * @mode: the permission that the file should have.
  * @parent: a pointer to the parent dentry for this file.  This should be a
  *          directory dentry if set.  If this paramater is NULL, then the
@@ -243,7 +299,8 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
 /**
  * debugfs_create_dir - create a directory in the debugfs filesystem
  * @name: a pointer to a string containing the name of the directory to
- *        create.
+ *        create. This can also contain directories (dir/file), in this case 
+ *        missing directories will be automatically created.
  * @parent: a pointer to the parent dentry for this file.  This should be a
  *          directory dentry if set.  If this paramater is NULL, then the
  *          directory will be created in the root of the debugfs filesystem.
@@ -269,7 +326,8 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
 /**
  * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
  * @name: a pointer to a string containing the name of the symbolic link to
- *        create.
+ *        create.  This can also contain directories (dir/file), in this case 
+ *        missing directories will be automatically created
  * @parent: a pointer to the parent dentry for this symbolic link.  This
  *          should be a directory dentry if set.  If this paramater is NULL,
  *          then the symbolic link will be created in the root of the debugfs
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread
* [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files v2
@ 2011-12-13 21:45 Andi Kleen
  2011-12-13 21:45 ` [PATCH 2/3] DEBUGFS: Add per cpu counters Andi Kleen
  0 siblings, 1 reply; 20+ messages in thread
From: Andi Kleen @ 2011-12-13 21:45 UTC (permalink / raw)
  To: greg; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Allow passing path names to debugfs_create* and automatically create
the parents. This makes it much simpler for the caller to create hierarchies.

The way the reference counts are handled is admittedly a bit ugly.

There is no way to clean them up currently other than to delete the tree,
but that doesn't seem like a big problem for debugfs to leave
behind a few empty directories.

v2: Comment fixes based on review comments.
v3: satisfy the kernel community's white space obsession.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 fs/debugfs/inode.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index f3a257d..0081ac0 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -146,6 +146,55 @@ static struct file_system_type debug_fs_type = {
 	.kill_sb =	kill_litter_super,
 };
 
+/*
+ * Created parents stay around later. Sorry, but it shouldn't be a big issue.
+ */
+static const char *create_parents(const char *name, struct dentry *parent,
+				  struct dentry **pp, int *ref)
+{
+	char fn[strlen(name) + 1];
+	char *tail;
+	char *s, *p;
+	struct dentry *new_parent, *dentry, *old_parent = NULL;
+
+	strcpy(fn, name);
+	tail = strrchr(fn, '/');
+	if (!tail)
+		return name;
+	tail++;
+
+	s = fn;
+	while ((p = strsep(&s, "/")) != NULL && p != tail) {
+		/*
+		 * When the parent already exists, this will error out.
+		 * Ignore that error. We'll just look the dentry up below.
+		 */
+		dentry = debugfs_create_dir(p, parent);
+
+		/* Is it there now? */
+		mutex_lock(&parent->d_inode->i_mutex);
+		new_parent = lookup_one_len(p, parent, strlen(p));
+		mutex_unlock(&parent->d_inode->i_mutex);
+
+		if (!PTR_ERR(dentry))
+			dput(dentry);
+		if (IS_ERR(new_parent))
+			return NULL;
+		if (old_parent)
+			dput(old_parent);
+		if (parent != *pp)
+			old_parent = parent;
+		parent = new_parent;
+	}
+	if (parent) {
+		*ref = 1;
+		*pp = parent;
+	}
+	if (old_parent)
+		dput(old_parent);
+	return strrchr(name, '/') + 1;
+}
+
 static int debugfs_create_by_name(const char *name, mode_t mode,
 				  struct dentry *parent,
 				  struct dentry **dentry,
@@ -153,6 +202,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 				  const struct file_operations *fops)
 {
 	int error = 0;
+	int ref = 0;
 
 	/* If the parent is not specified, we create it in the root.
 	 * We need the root dentry to do this, which is in the super 
@@ -161,6 +211,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 	 */
 	if (!parent)
 		parent = debugfs_mount->mnt_sb->s_root;
+	name = create_parents(name, parent, &parent, &ref);
 
 	*dentry = NULL;
 	mutex_lock(&parent->d_inode->i_mutex);
@@ -185,12 +236,17 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
 		error = PTR_ERR(*dentry);
 	mutex_unlock(&parent->d_inode->i_mutex);
 
+	if (ref)
+		dput(parent);
+
 	return error;
 }
 
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
  * @name: a pointer to a string containing the name of the file to create.
+ *        This can also contain directories (dir/file), in this case missing
+ *        directories will be automatically created.
  * @mode: the permission that the file should have.
  * @parent: a pointer to the parent dentry for this file.  This should be a
  *          directory dentry if set.  If this paramater is NULL, then the
@@ -243,7 +299,8 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
 /**
  * debugfs_create_dir - create a directory in the debugfs filesystem
  * @name: a pointer to a string containing the name of the directory to
- *        create.
+ *        create. This can also contain directories (dir/file), in this case
+ *        missing directories will be automatically created.
  * @parent: a pointer to the parent dentry for this file.  This should be a
  *          directory dentry if set.  If this paramater is NULL, then the
  *          directory will be created in the root of the debugfs filesystem.
@@ -269,7 +326,8 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
 /**
  * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
  * @name: a pointer to a string containing the name of the symbolic link to
- *        create.
+ *        create.  This can also contain directories (dir/file), in this case
+ *        missing directories will be automatically created
  * @parent: a pointer to the parent dentry for this symbolic link.  This
  *          should be a directory dentry if set.  If this paramater is NULL,
  *          then the symbolic link will be created in the root of the debugfs
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-12-13 23:17 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-02 18:43 Add simple way to add statistic counters to debugfs Andi Kleen
2011-12-02 18:43 ` [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files Andi Kleen
2011-12-02 19:17   ` Greg KH
2011-12-02 19:42     ` Andi Kleen
2011-12-02 19:58       ` Greg KH
2011-12-02 18:43 ` [PATCH 2/3] DEBUGFS: Add per cpu counters Andi Kleen
2011-12-06 11:44   ` Wu Fengguang
2011-12-06 17:17     ` Andi Kleen
2011-12-09  3:00       ` Wu Fengguang
2011-12-02 18:43 ` [PATCH 3/3] VFS: Add event counting to dcache Andi Kleen
2011-12-02 19:18 ` Add simple way to add statistic counters to debugfs Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2011-12-02 20:02 [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files v2 Andi Kleen
2011-12-02 20:02 ` [PATCH 2/3] DEBUGFS: Add per cpu counters Andi Kleen
2011-12-12 22:20   ` Greg KH
2011-12-13 21:45 [PATCH 1/3] DEBUGFS: Automatically create parents for debugfs files v2 Andi Kleen
2011-12-13 21:45 ` [PATCH 2/3] DEBUGFS: Add per cpu counters Andi Kleen
2011-12-13 22:43   ` Thomas Gleixner
2011-12-13 22:56     ` Andi Kleen
2011-12-13 23:08       ` Steven Rostedt
2011-12-13 23:15         ` Mathieu Desnoyers
2011-12-13 23:16         ` Steven Rostedt
2011-12-13 23:17       ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox