linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] kernfs: release kernfs_mutex before the inode allocation
@ 2021-11-16 19:43 Minchan Kim
  2021-11-16 19:49 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 12+ messages in thread
From: Minchan Kim @ 2021-11-16 19:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo; +Cc: LKML, Minchan Kim

The kernfs implementation has big lock granularity(kernfs_rwsem) so
every kernfs-based(e.g., sysfs, cgroup, dmabuf) fs are able to compete
the lock. Thus, if one of userspace goes the sleep under holding
the lock for a long time, rest of them should wait it. A example is
the holder goes direct reclaim with the lock since it needs memory
allocation. Let's fix it at common technique that release the lock
and then allocate the memory. Fortunately, kernfs looks like have
an refcount so I hope it's fine.

Signed-off-by: Minchan Kim <minchan@kernel.org>
---
 fs/kernfs/dir.c             | 14 +++++++++++---
 fs/kernfs/inode.c           |  2 +-
 fs/kernfs/kernfs-internal.h |  1 +
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 8e0a1378a4b1..ecdb2975060d 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1119,9 +1119,17 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
 			up_read(&kernfs_rwsem);
 			return NULL;
 		}
-		inode = kernfs_get_inode(dir->i_sb, kn);
-		if (!inode)
-			inode = ERR_PTR(-ENOMEM);
+		kernfs_get(kn);
+		up_read(&kernfs_rwsem);
+		inode = iget_locked(dir->i_sb, kernfs_ino(kn));
+		if (!inode) {
+			kernfs_put(kn);
+			return ERR_PTR(-ENOMEM);
+		}
+		down_read(&kernfs_rwsem);
+		if (inode->i_state & I_NEW)
+			kernfs_init_inode(kn, inode);
+		kernfs_put(kn);
 	}
 	/*
 	 * Needed for negative dentry validation.
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index c0eae1725435..6e2004010435 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -195,7 +195,7 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns,
 	return 0;
 }
 
-static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode)
+void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode)
 {
 	kernfs_get(kn);
 	inode->i_private = kn;
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index f9cc912c31e1..eef7656f7cd8 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -118,6 +118,7 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns,
 		       u32 request_mask, unsigned int query_flags);
 ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size);
 int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
+void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode);
 
 /*
  * dir.c
-- 
2.34.0.rc1.387.gb447b232ab-goog


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

end of thread, other threads:[~2021-11-18 16:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-16 19:43 [RFC PATCH] kernfs: release kernfs_mutex before the inode allocation Minchan Kim
2021-11-16 19:49 ` Greg Kroah-Hartman
2021-11-16 21:36   ` Minchan Kim
2021-11-17  6:44     ` Greg Kroah-Hartman
2021-11-17  7:27       ` Minchan Kim
2021-11-17  7:39         ` Greg Kroah-Hartman
2021-11-17 21:43           ` Minchan Kim
2021-11-17 21:45         ` Tejun Heo
2021-11-17 22:13           ` Minchan Kim
2021-11-17 22:23             ` Tejun Heo
2021-11-18  1:55               ` Minchan Kim
2021-11-18 16:35                 ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).