aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-03-12 08:19:11 -0400
committerJosef Bacik <jbacik@fb.com>2015-08-17 18:39:45 -0400
commitcbedaac63481dea52327127a9f1c60f092bd6b07 (patch)
tree81c37c05fe0de630170100a8d358d27813d57994
parentwriteback: plug writeback at a high level (diff)
downloadwireguard-linux-cbedaac63481dea52327127a9f1c60f092bd6b07.tar.xz
wireguard-linux-cbedaac63481dea52327127a9f1c60f092bd6b07.zip
inode: add hlist_fake to avoid the inode hash lock in evict
Some filesystems don't use the VFS inode hash and fake the fact they are hashed so that all the writeback code works correctly. However, this means the evict() path still tries to remove the inode from the hash, meaning that the inode_hash_lock() needs to be taken unnecessarily. Hence under certain workloads the inode_hash_lock can be contended even if the inode is never actually hashed. To avoid this add hlist_fake to test if the inode isn't actually hashed to avoid taking the hash lock on inodes that have never been hashed. Based on Dave Chinner's inode: add IOP_NOTHASHED to avoid inode hash lock in evict basd on Al's suggestions. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/list.h5
2 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 84b783f277f7..4a40fa843040 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2608,7 +2608,7 @@ static inline void insert_inode_hash(struct inode *inode)
extern void __remove_inode_hash(struct inode *);
static inline void remove_inode_hash(struct inode *inode)
{
- if (!inode_unhashed(inode))
+ if (!inode_unhashed(inode) && !hlist_fake(&inode->i_hash))
__remove_inode_hash(inode);
}
diff --git a/include/linux/list.h b/include/linux/list.h
index feb773c76ee0..3e3e64a61002 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -672,6 +672,11 @@ static inline void hlist_add_fake(struct hlist_node *n)
n->pprev = &n->next;
}
+static inline bool hlist_fake(struct hlist_node *h)
+{
+ return h->pprev == &h->next;
+}
+
/*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.