* [PATCH 1/2] debugfs: add debugfs_lookup_and_remove()
@ 2022-09-02 12:31 Greg Kroah-Hartman
2022-09-02 12:31 ` [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs Greg Kroah-Hartman
2022-09-02 14:59 ` [PATCH 1/2 v2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
0 siblings, 2 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-02 12:31 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, Kuyo Chang, stable
There is a very common pattern of using
debugfs_remove(debufs_lookup(..)) which results in a dentry leak of the
dentry that was looked up. Instead of having to open-code the correct
pattern of calling dput() on the dentry, create
debugfs_lookup_and_remove() to handle this pattern automatically and
properly without any memory leaks.
Reported-by: Kuyo Chang <kuyo.chang@mediatek.com>
Tested-by: Kuyo Chang <kuyo.chang@mediatek.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/debugfs/inode.c | 22 ++++++++++++++++++++++
include/linux/debugfs.h | 6 ++++++
2 files changed, 28 insertions(+)
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 3dcf0b8b4e93..87ccd6280a9b 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -744,6 +744,28 @@ void debugfs_remove(struct dentry *dentry)
}
EXPORT_SYMBOL_GPL(debugfs_remove);
+/**
+ * debugfs_lookup_and_remove - lookup a directory or file and recursively remove it
+ * @name: a pointer to a string containing the name of the item to look up.
+ * @parent: a pointer to the parent dentry of the item.
+ *
+ * This is the equlivant of doing something like
+ * debugfs_remove(debugfs_lookup(..)) but with the proper reference counting
+ * handled for the directory being looked up.
+ */
+void debugfs_lookup_and_remove(const char *name, struct dentry *parent)
+{
+ struct dentry *dentry;
+
+ dentry = debugfs_lookup(name, parent);
+ if (IS_ERR_OR_NULL(dentry))
+ return;
+
+ debugfs_remove(dentry);
+ dput(dentry);
+}
+EXPORT_SYMBOL_GPL(debugfs_lookup_and_remove);
+
/**
* debugfs_rename - rename a file/directory in the debugfs filesystem
* @old_dir: a pointer to the parent dentry for the renamed object. This
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index c869f1e73d75..f60674692d36 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -91,6 +91,8 @@ struct dentry *debugfs_create_automount(const char *name,
void debugfs_remove(struct dentry *dentry);
#define debugfs_remove_recursive debugfs_remove
+void debugfs_lookup_and_remove(const char *name, struct dentry *parent);
+
const struct file_operations *debugfs_real_fops(const struct file *filp);
int debugfs_file_get(struct dentry *dentry);
@@ -225,6 +227,10 @@ static inline void debugfs_remove(struct dentry *dentry)
static inline void debugfs_remove_recursive(struct dentry *dentry)
{ }
+static inline void debugfs_lookup_and_remove(const char *name,
+ struct dentry *parent)
+{ }
+
const struct file_operations *debugfs_real_fops(const struct file *filp);
static inline int debugfs_file_get(struct dentry *dentry)
--
2.37.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs
2022-09-02 12:31 [PATCH 1/2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
@ 2022-09-02 12:31 ` Greg Kroah-Hartman
2022-09-02 12:46 ` Greg Kroah-Hartman
2022-09-02 12:59 ` Peter Zijlstra
2022-09-02 14:59 ` [PATCH 1/2 v2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
1 sibling, 2 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-02 12:31 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, Major Chen, stable, Kuyo Chang, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Steven Rostedt, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Valentin Schneider, Matthias Brugger
Kuyo reports that the pattern of using debugfs_remove(debugfs_lookup())
leaks a dentry and with a hotplug stress test, the machine eventually
runs out of memory.
Fix this up by using the newly created debugfs_lookup_and_remove() call
instead which properly handles the dentry reference counting logic.
Cc: Major Chen <major.chen@samsung.com>
Cc: stable <stable@kernel.org>
Reported-by: Kuyo Chang <kuyo.chang@mediatek.com>
Tested-by: Kuyo Chang <kuyo.chang@mediatek.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/sched/debug.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index bb3d63bdf4ae..667876da8382 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -416,7 +416,7 @@ void update_sched_domain_debugfs(void)
char buf[32];
snprintf(buf, sizeof(buf), "cpu%d", cpu);
- debugfs_remove(debugfs_lookup(buf, sd_dentry));
+ debugfs_lookup_and_remove(buf, sd_dentry);
d_cpu = debugfs_create_dir(buf, sd_dentry);
i = 0;
--
2.37.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs
2022-09-02 12:31 ` [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs Greg Kroah-Hartman
@ 2022-09-02 12:46 ` Greg Kroah-Hartman
2022-09-02 12:59 ` Peter Zijlstra
1 sibling, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-02 12:46 UTC (permalink / raw)
To: linux-kernel
Cc: Major Chen, stable, Kuyo Chang, Ingo Molnar, Peter Zijlstra,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
Valentin Schneider, Matthias Brugger
On Fri, Sep 02, 2022 at 02:31:07PM +0200, Greg Kroah-Hartman wrote:
> Kuyo reports that the pattern of using debugfs_remove(debugfs_lookup())
> leaks a dentry and with a hotplug stress test, the machine eventually
> runs out of memory.
>
> Fix this up by using the newly created debugfs_lookup_and_remove() call
> instead which properly handles the dentry reference counting logic.
>
> Cc: Major Chen <major.chen@samsung.com>
> Cc: stable <stable@kernel.org>
> Reported-by: Kuyo Chang <kuyo.chang@mediatek.com>
> Tested-by: Kuyo Chang <kuyo.chang@mediatek.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Ben Segall <bsegall@google.com>
> Cc: Mel Gorman <mgorman@suse.de>
> Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Matthias Brugger <matthias.bgg@gmail.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> kernel/sched/debug.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
As this needs patch 1/2 to work properly, and Kuyo has tested this out
already, I'll take both of them through my driver core git tree to Linus
so that we can start getting the other debugfs_lookup() leaks fixed up
as well.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs
2022-09-02 12:31 ` [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs Greg Kroah-Hartman
2022-09-02 12:46 ` Greg Kroah-Hartman
@ 2022-09-02 12:59 ` Peter Zijlstra
1 sibling, 0 replies; 5+ messages in thread
From: Peter Zijlstra @ 2022-09-02 12:59 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-kernel, Major Chen, stable, Kuyo Chang, Ingo Molnar,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Daniel Bristot de Oliveira,
Valentin Schneider, Matthias Brugger
On Fri, Sep 02, 2022 at 02:31:07PM +0200, Greg Kroah-Hartman wrote:
> Kuyo reports that the pattern of using debugfs_remove(debugfs_lookup())
> leaks a dentry and with a hotplug stress test, the machine eventually
> runs out of memory.
>
> Fix this up by using the newly created debugfs_lookup_and_remove() call
> instead which properly handles the dentry reference counting logic.
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> kernel/sched/debug.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
> index bb3d63bdf4ae..667876da8382 100644
> --- a/kernel/sched/debug.c
> +++ b/kernel/sched/debug.c
> @@ -416,7 +416,7 @@ void update_sched_domain_debugfs(void)
> char buf[32];
>
> snprintf(buf, sizeof(buf), "cpu%d", cpu);
> - debugfs_remove(debugfs_lookup(buf, sd_dentry));
> + debugfs_lookup_and_remove(buf, sd_dentry);
> d_cpu = debugfs_create_dir(buf, sd_dentry);
>
> i = 0;
> --
> 2.37.3
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2 v2] debugfs: add debugfs_lookup_and_remove()
2022-09-02 12:31 [PATCH 1/2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
2022-09-02 12:31 ` [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs Greg Kroah-Hartman
@ 2022-09-02 14:59 ` Greg Kroah-Hartman
1 sibling, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-02 14:59 UTC (permalink / raw)
To: linux-kernel; +Cc: Kuyo Chang, stable, Al Viro
There is a very common pattern of using
debugfs_remove(debufs_lookup(..)) which results in a dentry leak of the
dentry that was looked up. Instead of having to open-code the correct
pattern of calling dput() on the dentry, create
debugfs_lookup_and_remove() to handle this pattern automatically and
properly without any memory leaks.
Reported-by: Kuyo Chang <kuyo.chang@mediatek.com>
Tested-by: Kuyo Chang <kuyo.chang@mediatek.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
v2: fix up debugfs_lookup() return value check as pointed out by Al.
fs/debugfs/inode.c | 22 ++++++++++++++++++++++
include/linux/debugfs.h | 6 ++++++
2 files changed, 28 insertions(+)
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 3dcf0b8b4e93..232cfdf095ae 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -744,6 +744,28 @@ void debugfs_remove(struct dentry *dentry)
}
EXPORT_SYMBOL_GPL(debugfs_remove);
+/**
+ * debugfs_lookup_and_remove - lookup a directory or file and recursively remove it
+ * @name: a pointer to a string containing the name of the item to look up.
+ * @parent: a pointer to the parent dentry of the item.
+ *
+ * This is the equlivant of doing something like
+ * debugfs_remove(debugfs_lookup(..)) but with the proper reference counting
+ * handled for the directory being looked up.
+ */
+void debugfs_lookup_and_remove(const char *name, struct dentry *parent)
+{
+ struct dentry *dentry;
+
+ dentry = debugfs_lookup(name, parent);
+ if (!dentry)
+ return;
+
+ debugfs_remove(dentry);
+ dput(dentry);
+}
+EXPORT_SYMBOL_GPL(debugfs_lookup_and_remove);
+
/**
* debugfs_rename - rename a file/directory in the debugfs filesystem
* @old_dir: a pointer to the parent dentry for the renamed object. This
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index c869f1e73d75..f60674692d36 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -91,6 +91,8 @@ struct dentry *debugfs_create_automount(const char *name,
void debugfs_remove(struct dentry *dentry);
#define debugfs_remove_recursive debugfs_remove
+void debugfs_lookup_and_remove(const char *name, struct dentry *parent);
+
const struct file_operations *debugfs_real_fops(const struct file *filp);
int debugfs_file_get(struct dentry *dentry);
@@ -225,6 +227,10 @@ static inline void debugfs_remove(struct dentry *dentry)
static inline void debugfs_remove_recursive(struct dentry *dentry)
{ }
+static inline void debugfs_lookup_and_remove(const char *name,
+ struct dentry *parent)
+{ }
+
const struct file_operations *debugfs_real_fops(const struct file *filp);
static inline int debugfs_file_get(struct dentry *dentry)
--
2.37.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-09-02 15:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-02 12:31 [PATCH 1/2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
2022-09-02 12:31 ` [PATCH 2/2] sched/debug: fix dentry leak in update_sched_domain_debugfs Greg Kroah-Hartman
2022-09-02 12:46 ` Greg Kroah-Hartman
2022-09-02 12:59 ` Peter Zijlstra
2022-09-02 14:59 ` [PATCH 1/2 v2] debugfs: add debugfs_lookup_and_remove() Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox