Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a209dfc7 authored by Eric Dumazet's avatar Eric Dumazet Committed by Al Viro
Browse files

vfs: dont chain pipe/anon/socket on superblock s_inodes list



Workloads using pipes and sockets hit inode_sb_list_lock contention.

superblock s_inodes list is needed for quota, dirty, pagecache and
fsnotify management. pipe/anon/socket fs are clearly not candidates for
these.

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 5b9f4567
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ EXPORT_SYMBOL_GPL(anon_inode_getfd);
 */
static struct inode *anon_inode_mkinode(void)
{
	struct inode *inode = new_inode(anon_inode_mnt->mnt_sb);
	struct inode *inode = new_inode_pseudo(anon_inode_mnt->mnt_sb);

	if (!inode)
		return ERR_PTR(-ENOMEM);
+30 −9
Original line number Diff line number Diff line
@@ -362,10 +362,12 @@ EXPORT_SYMBOL_GPL(inode_sb_list_add);

static inline void inode_sb_list_del(struct inode *inode)
{
	if (!list_empty(&inode->i_sb_list)) {
		spin_lock(&inode_sb_list_lock);
		list_del_init(&inode->i_sb_list);
		spin_unlock(&inode_sb_list_lock);
	}
}

static unsigned long hash(struct super_block *sb, unsigned long hashval)
{
@@ -796,6 +798,29 @@ unsigned int get_next_ino(void)
}
EXPORT_SYMBOL(get_next_ino);

/**
 *	new_inode_pseudo 	- obtain an inode
 *	@sb: superblock
 *
 *	Allocates a new inode for given superblock.
 *	Inode wont be chained in superblock s_inodes list
 *	This means :
 *	- fs can't be unmount
 *	- quotas, fsnotify, writeback can't work
 */
struct inode *new_inode_pseudo(struct super_block *sb)
{
	struct inode *inode = alloc_inode(sb);

	if (inode) {
		spin_lock(&inode->i_lock);
		inode->i_state = 0;
		spin_unlock(&inode->i_lock);
		INIT_LIST_HEAD(&inode->i_sb_list);
	}
	return inode;
}

/**
 *	new_inode 	- obtain an inode
 *	@sb: superblock
@@ -814,13 +839,9 @@ struct inode *new_inode(struct super_block *sb)

	spin_lock_prefetch(&inode_sb_list_lock);

	inode = alloc_inode(sb);
	if (inode) {
		spin_lock(&inode->i_lock);
		inode->i_state = 0;
		spin_unlock(&inode->i_lock);
	inode = new_inode_pseudo(sb);
	if (inode)
		inode_sb_list_add(inode);
	}
	return inode;
}
EXPORT_SYMBOL(new_inode);
+1 −1
Original line number Diff line number Diff line
@@ -948,7 +948,7 @@ static const struct dentry_operations pipefs_dentry_operations = {

static struct inode * get_pipe_inode(void)
{
	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
	struct pipe_inode_info *pipe;

	if (!inode)
+2 −1
Original line number Diff line number Diff line
@@ -2310,7 +2310,8 @@ extern void __iget(struct inode * inode);
extern void iget_failed(struct inode *);
extern void end_writeback(struct inode *);
extern void __destroy_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
extern struct inode *new_inode_pseudo(struct super_block *sb);
extern struct inode *new_inode(struct super_block *sb);
extern void free_inode_nonrcu(struct inode *inode);
extern int should_remove_suid(struct dentry *);
extern int file_remove_suid(struct file *);
+1 −1
Original line number Diff line number Diff line
@@ -467,7 +467,7 @@ static struct socket *sock_alloc(void)
	struct inode *inode;
	struct socket *sock;

	inode = new_inode(sock_mnt->mnt_sb);
	inode = new_inode_pseudo(sock_mnt->mnt_sb);
	if (!inode)
		return NULL;