[PATCH v3 7/7] fs: MS_NOREFCOUNT
From: Eric Dumazet <hidden>
Date: 2008-12-11 22:41:03
Also in:
linux-fsdevel, lkml
Subsystem:
filesystems (vfs and infrastructure), networking [general], networking [sockets], the rest · Maintainers:
Alexander Viro, Christian Brauner, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Linus Torvalds
Some fs are hardwired into kernel, and mntput()/mntget() hit a contended
cache line. We define a new superblock flag, MS_NOREFCOUNT, that is set
on socket, pipes and anonymous fd superblocks. mntput()/mntget() become
null ops on these fs.
("socketallocbench -n 8" result : from 2.20s to 1.64s)
Signed-off-by: Eric Dumazet <redacted>
---
fs/anon_inodes.c | 1 +
fs/pipe.c | 3 ++-
include/linux/fs.h | 2 ++
include/linux/mount.h | 8 +++-----
net/socket.c | 1 +
5 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 89fd36d..de0ec3b 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c@@ -158,6 +158,7 @@ static int __init anon_inode_init(void) error = PTR_ERR(anon_inode_mnt); goto err_unregister_filesystem; } + anon_inode_mnt->mnt_sb->s_flags |= MS_NOREFCOUNT; anon_inode_inode = anon_inode_mkinode(); if (IS_ERR(anon_inode_inode)) { error = PTR_ERR(anon_inode_inode);
diff --git a/fs/pipe.c b/fs/pipe.c
index 8c51a0d..f547432 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c@@ -1078,7 +1078,8 @@ static int __init init_pipe_fs(void) if (IS_ERR(pipe_mnt)) { err = PTR_ERR(pipe_mnt); unregister_filesystem(&pipe_fs_type); - } + } else + pipe_mnt->mnt_sb->s_flags |= MS_NOREFCOUNT; } return err; }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a1f56d4..11b0452 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h@@ -137,6 +137,8 @@ extern int dir_notify_enable; #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ #define MS_I_VERSION (1<<23) /* Update inode I_version field */ + +#define MS_NOREFCOUNT (1<<29) /* kernel static mnt : no refcounting needed */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31)
diff --git a/include/linux/mount.h b/include/linux/mount.h
index cab2a85..51418b5 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h@@ -14,10 +14,8 @@ #include <linux/nodemask.h> #include <linux/spinlock.h> #include <asm/atomic.h> +#include <linux/fs.h> -struct super_block; -struct vfsmount; -struct dentry; struct mnt_namespace; #define MNT_NOSUID 0x01
@@ -73,7 +71,7 @@ struct vfsmount { static inline struct vfsmount *mntget(struct vfsmount *mnt) { - if (mnt) + if (mnt && !(mnt->mnt_sb->s_flags & MS_NOREFCOUNT)) atomic_inc(&mnt->mnt_count); return mnt; }
@@ -87,7 +85,7 @@ extern int __mnt_is_readonly(struct vfsmount *mnt); static inline void mntput(struct vfsmount *mnt) { - if (mnt) { + if (mnt && !(mnt->mnt_sb->s_flags & MS_NOREFCOUNT)) { mnt->mnt_expiry_mark = 0; mntput_no_expire(mnt); }
diff --git a/net/socket.c b/net/socket.c
index 4017409..2534dbc 100644
--- a/net/socket.c
+++ b/net/socket.c@@ -2206,6 +2206,7 @@ static int __init sock_init(void) init_inodecache(); register_filesystem(&sock_fs_type); sock_mnt = kern_mount(&sock_fs_type); + sock_mnt->mnt_sb->s_flags |= MS_NOREFCOUNT; /* The real protocol initialization is performed in later initcalls. */