[patch 27/52] fs: icache lock inode hash

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: npiggin
Date: Wednesday, June 23, 2010 - 8:02 pm

Add a new lock, inode_hash_lock, to protect the inode hash table lists.

Signed-off-by: Nick Piggin <npiggin@suse.de>
---
 fs/inode.c                |   29 ++++++++++++++++++++++++++++-
 include/linux/writeback.h |    1 +
 2 files changed, 29 insertions(+), 1 deletion(-)

Index: linux-2.6/fs/inode.c
===================================================================
--- linux-2.6.orig/fs/inode.c
+++ linux-2.6/fs/inode.c
@@ -30,10 +30,14 @@
  * Usage:
  * sb_inode_list_lock protects:
  *   s_inodes, i_sb_list
+ * inode_hash_lock protects:
+ *   inode hash table, i_hash
  *
  * Ordering:
  * inode_lock
  *   sb_inode_list_lock
+ * inode_lock
+ *   inode_hash_lock
  */
 /*
  * This is needed for the following functions:
@@ -94,6 +98,7 @@ static struct hlist_head *inode_hashtabl
  */
 DEFINE_SPINLOCK(inode_lock);
 DEFINE_SPINLOCK(sb_inode_list_lock);
+DEFINE_SPINLOCK(inode_hash_lock);
 
 /*
  * iprune_sem provides exclusion between the kswapd or try_to_free_pages
@@ -353,7 +358,9 @@ static void dispose_list(struct list_hea
 		clear_inode(inode);
 
 		spin_lock(&inode_lock);
+		spin_lock(&inode_hash_lock);
 		hlist_del_init(&inode->i_hash);
+		spin_unlock(&inode_hash_lock);
 		spin_lock(&sb_inode_list_lock);
 		list_del_init(&inode->i_sb_list);
 		spin_unlock(&sb_inode_list_lock);
@@ -563,17 +570,20 @@ static struct inode *find_inode(struct s
 	struct inode *inode = NULL;
 
 repeat:
+	spin_lock(&inode_hash_lock);
 	hlist_for_each_entry(inode, node, head, i_hash) {
 		if (inode->i_sb != sb)
 			continue;
 		if (!test(inode, data))
 			continue;
 		if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+			spin_unlock(&inode_hash_lock);
 			__wait_on_freeing_inode(inode);
 			goto repeat;
 		}
 		break;
 	}
+	spin_unlock(&inode_hash_lock);
 	return node ? inode : NULL;
 }
 
@@ -588,17 +598,20 @@ static struct inode *find_inode_fast(str
 	struct inode *inode = NULL;
 
 repeat:
+	spin_lock(&inode_hash_lock);
 	hlist_for_each_entry(inode, node, head, i_hash) {
 		if (inode->i_ino != ino)
 			continue;
 		if (inode->i_sb != sb)
 			continue;
 		if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+			spin_unlock(&inode_hash_lock);
 			__wait_on_freeing_inode(inode);
 			goto repeat;
 		}
 		break;
 	}
+	spin_unlock(&inode_hash_lock);
 	return node ? inode : NULL;
 }
 
@@ -621,8 +634,11 @@ __inode_add_to_lists(struct super_block
 	spin_lock(&sb_inode_list_lock);
 	list_add(&inode->i_sb_list, &sb->s_inodes);
 	spin_unlock(&sb_inode_list_lock);
-	if (head)
+	if (head) {
+		spin_lock(&inode_hash_lock);
 		hlist_add_head(&inode->i_hash, head);
+		spin_unlock(&inode_hash_lock);
+	}
 }
 
 /**
@@ -1100,7 +1116,9 @@ int insert_inode_locked(struct inode *in
 	while (1) {
 		struct hlist_node *node;
 		struct inode *old = NULL;
+
 		spin_lock(&inode_lock);
+		spin_lock(&inode_hash_lock);
 		hlist_for_each_entry(old, node, head, i_hash) {
 			if (old->i_ino != ino)
 				continue;
@@ -1112,9 +1130,11 @@ int insert_inode_locked(struct inode *in
 		}
 		if (likely(!node)) {
 			hlist_add_head(&inode->i_hash, head);
+			spin_unlock(&inode_hash_lock);
 			spin_unlock(&inode_lock);
 			return 0;
 		}
+		spin_unlock(&inode_hash_lock);
 		__iget(old);
 		spin_unlock(&inode_lock);
 		wait_on_inode(old);
@@ -1140,6 +1160,7 @@ int insert_inode_locked4(struct inode *i
 		struct inode *old = NULL;
 
 		spin_lock(&inode_lock);
+		spin_lock(&inode_hash_lock);
 		hlist_for_each_entry(old, node, head, i_hash) {
 			if (old->i_sb != sb)
 				continue;
@@ -1151,9 +1172,11 @@ int insert_inode_locked4(struct inode *i
 		}
 		if (likely(!node)) {
 			hlist_add_head(&inode->i_hash, head);
+			spin_unlock(&inode_hash_lock);
 			spin_unlock(&inode_lock);
 			return 0;
 		}
+		spin_unlock(&inode_hash_lock);
 		__iget(old);
 		spin_unlock(&inode_lock);
 		wait_on_inode(old);
@@ -1178,7 +1201,9 @@ void __insert_inode_hash(struct inode *i
 {
 	struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
 	spin_lock(&inode_lock);
+	spin_lock(&inode_hash_lock);
 	hlist_add_head(&inode->i_hash, head);
+	spin_unlock(&inode_hash_lock);
 	spin_unlock(&inode_lock);
 }
 EXPORT_SYMBOL(__insert_inode_hash);
@@ -1192,7 +1217,9 @@ EXPORT_SYMBOL(__insert_inode_hash);
 void remove_inode_hash(struct inode *inode)
 {
 	spin_lock(&inode_lock);
+	spin_lock(&inode_hash_lock);
 	hlist_del_init(&inode->i_hash);
+	spin_unlock(&inode_hash_lock);
 	spin_unlock(&inode_lock);
 }
 EXPORT_SYMBOL(remove_inode_hash);
@@ -1234,7 +1261,9 @@ void generic_delete_inode(struct inode *
 		clear_inode(inode);
 	}
 	spin_lock(&inode_lock);
+	spin_lock(&inode_hash_lock);
 	hlist_del_init(&inode->i_hash);
+	spin_unlock(&inode_hash_lock);
 	spin_unlock(&inode_lock);
 	wake_up_inode(inode);
 	BUG_ON(inode->i_state != I_CLEAR);
@@ -1271,7 +1300,9 @@ int generic_detach_inode(struct inode *i
 		WARN_ON(inode->i_state & I_NEW);
 		inode->i_state &= ~I_WILL_FREE;
 		inodes_stat.nr_unused--;
+		spin_lock(&inode_hash_lock);
 		hlist_del_init(&inode->i_hash);
+		spin_unlock(&inode_hash_lock);
 	}
 	list_del_init(&inode->i_list);
 	spin_lock(&sb_inode_list_lock);
Index: linux-2.6/include/linux/writeback.h
===================================================================
--- linux-2.6.orig/include/linux/writeback.h
+++ linux-2.6/include/linux/writeback.h
@@ -11,6 +11,7 @@ struct backing_dev_info;
 
 extern spinlock_t inode_lock;
 extern spinlock_t sb_inode_list_lock;
+extern spinlock_t inode_hash_lock;
 extern struct list_head inode_in_use;
 extern struct list_head inode_unused;
 


--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 00/52] vfs scalability patches updated, npiggin, (Wed Jun 23, 8:02 pm)
[patch 01/52] kernel: add bl_list, npiggin, (Wed Jun 23, 8:02 pm)
[patch 02/52] fs: fix superblock iteration race, npiggin, (Wed Jun 23, 8:02 pm)
[patch 03/52] fs: fs_struct rwlock to spinlock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 04/52] fs: cleanup files_lock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 06/52] fs: scale files_lock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 07/52] fs: brlock vfsmount_lock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 08/52] fs: scale mntget/mntput, npiggin, (Wed Jun 23, 8:02 pm)
[patch 09/52] fs: dcache scale hash, npiggin, (Wed Jun 23, 8:02 pm)
[patch 10/52] fs: dcache scale lru, npiggin, (Wed Jun 23, 8:02 pm)
[patch 11/52] fs: dcache scale nr_dentry, npiggin, (Wed Jun 23, 8:02 pm)
[patch 12/52] fs: dcache scale dentry refcount, npiggin, (Wed Jun 23, 8:02 pm)
[patch 13/52] fs: dcache scale d_unhashed, npiggin, (Wed Jun 23, 8:02 pm)
[patch 14/52] fs: dcache scale subdirs, npiggin, (Wed Jun 23, 8:02 pm)
[patch 15/52] fs: dcache scale inode alias list, npiggin, (Wed Jun 23, 8:02 pm)
[patch 17/52] fs: dcache remove dcache_lock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 18/52] fs: dcache reduce dput locking, npiggin, (Wed Jun 23, 8:02 pm)
[patch 23/52] fs: dcache percpu nr_dentry, npiggin, (Wed Jun 23, 8:02 pm)
[patch 24/52] fs: dcache reduce d_parent locking, npiggin, (Wed Jun 23, 8:02 pm)
[patch 26/52] fs: icache lock s_inodes list, npiggin, (Wed Jun 23, 8:02 pm)
[patch 27/52] fs: icache lock inode hash, npiggin, (Wed Jun 23, 8:02 pm)
[patch 28/52] fs: icache lock i_state, npiggin, (Wed Jun 23, 8:02 pm)
[patch 29/52] fs: icache lock i_count, npiggin, (Wed Jun 23, 8:02 pm)
[patch 31/52] fs: icache atomic inodes_stat, npiggin, (Wed Jun 23, 8:02 pm)
[patch 32/52] fs: icache protect inode state, npiggin, (Wed Jun 23, 8:02 pm)
[patch 34/52] fs: icache remove inode_lock, npiggin, (Wed Jun 23, 8:02 pm)
[patch 37/52] fs: icache lazy lru, npiggin, (Wed Jun 23, 8:02 pm)
[patch 38/52] fs: icache RCU free inodes, npiggin, (Wed Jun 23, 8:02 pm)
[patch 39/52] fs: icache rcu walk for i_sb_list, npiggin, (Wed Jun 23, 8:02 pm)
[patch 41/52] fs: icache reduce atomics, npiggin, (Wed Jun 23, 8:02 pm)
[patch 45/52] fs: icache RCU hash lookups, npiggin, (Wed Jun 23, 8:02 pm)
[patch 46/52] fs: icache reduce locking, npiggin, (Wed Jun 23, 8:02 pm)
[patch 47/52] fs: keep inode with backing-dev, npiggin, (Wed Jun 23, 8:02 pm)
[patch 48/52] fs: icache split IO and LRU lists, npiggin, (Wed Jun 23, 8:03 pm)
[patch 50/52] mm: implement per-zone shrinker, npiggin, (Wed Jun 23, 8:03 pm)
[patch 51/52] fs: per-zone dentry and inode LRU, npiggin, (Wed Jun 23, 8:03 pm)
[patch 52/52] fs: icache less I_FREEING time, npiggin, (Wed Jun 23, 8:03 pm)
Re: [patch 01/52] kernel: add bl_list, Eric Dumazet, (Wed Jun 23, 11:04 pm)
Re: [patch 06/52] fs: scale files_lock, Peter Zijlstra, (Thu Jun 24, 12:52 am)
Re: [patch 14/52] fs: dcache scale subdirs, Peter Zijlstra, (Thu Jun 24, 12:56 am)
Re: [patch 16/52] fs: dcache RCU for multi-step operaitons, Peter Zijlstra, (Thu Jun 24, 12:58 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Peter Zijlstra, (Thu Jun 24, 1:44 am)
Re: [patch 30/52] fs: icache lock lru/writeback lists, Peter Zijlstra, (Thu Jun 24, 1:58 am)
Re: [patch 14/52] fs: dcache scale subdirs, Andi Kleen, (Thu Jun 24, 2:50 am)
Re: [patch 37/52] fs: icache lazy lru, Andi Kleen, (Thu Jun 24, 2:52 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Andi Kleen, (Thu Jun 24, 3:06 am)
Re: [patch 01/52] kernel: add bl_list, Nick Piggin, (Thu Jun 24, 7:42 am)
Re: [patch 06/52] fs: scale files_lock, Nick Piggin, (Thu Jun 24, 8:00 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Nick Piggin, (Thu Jun 24, 8:07 am)
Re: [patch 30/52] fs: icache lock lru/writeback lists, Nick Piggin, (Thu Jun 24, 8:09 am)
Re: [patch 30/52] fs: icache lock lru/writeback lists, Peter Zijlstra, (Thu Jun 24, 8:13 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Paul E. McKenney, (Thu Jun 24, 8:32 am)
Re: [patch 14/52] fs: dcache scale subdirs, Nick Piggin, (Thu Jun 24, 8:53 am)
Re: [patch 37/52] fs: icache lazy lru, Nick Piggin, (Thu Jun 24, 8:59 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Nick Piggin, (Thu Jun 24, 9:00 am)
Re: [patch 01/52] kernel: add bl_list, Eric Dumazet, (Thu Jun 24, 9:01 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Nick Piggin, (Thu Jun 24, 9:05 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Andi Kleen, (Thu Jun 24, 9:27 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Andi Kleen, (Thu Jun 24, 9:32 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Andi Kleen, (Thu Jun 24, 9:37 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Paul E. McKenney, (Thu Jun 24, 9:41 am)
Re: [patch 00/52] vfs scalability patches updated, Christoph Hellwig, (Fri Jun 25, 12:12 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Fri Jun 25, 1:05 am)
Re: [patch 01/52] kernel: add bl_list, Paul E. McKenney, (Mon Jun 28, 2:37 pm)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Paul E. McKenney, (Mon Jun 28, 2:50 pm)
Re: [patch 01/52] kernel: add bl_list, Nick Piggin, (Mon Jun 28, 11:30 pm)
Re: [patch 02/52] fs: fix superblock iteration race, Christoph Hellwig, (Tue Jun 29, 6:02 am)
Re: [patch 02/52] fs: fix superblock iteration race, Nick Piggin, (Tue Jun 29, 7:56 am)
Re: [patch 02/52] fs: fix superblock iteration race, Linus Torvalds, (Tue Jun 29, 10:35 am)
Re: [patch 02/52] fs: fix superblock iteration race, Nick Piggin, (Tue Jun 29, 10:41 am)
Re: [patch 02/52] fs: fix superblock iteration race, Linus Torvalds, (Tue Jun 29, 10:52 am)
Re: [patch 02/52] fs: fix superblock iteration race, Linus Torvalds, (Tue Jun 29, 10:58 am)
Re: [patch 02/52] fs: fix superblock iteration race, Nick Piggin, (Tue Jun 29, 1:14 pm)
Re: [patch 02/52] fs: fix superblock iteration race, Chris Clayton, (Tue Jun 29, 1:38 pm)
Re: [patch 50/52] mm: implement per-zone shrinker, Dave Chinner, (Tue Jun 29, 11:28 pm)
Re: [patch 02/52] fs: fix superblock iteration race, Chris Clayton, (Wed Jun 30, 12:13 am)
Re: [patch 29/52] fs: icache lock i_count, Dave Chinner, (Wed Jun 30, 12:27 am)
Re: [patch 37/52] fs: icache lazy lru, Dave Chinner, (Wed Jun 30, 1:38 am)
Re: [patch 38/52] fs: icache RCU free inodes, Dave Chinner, (Wed Jun 30, 1:57 am)
Re: [patch 52/52] fs: icache less I_FREEING time, Dave Chinner, (Wed Jun 30, 3:13 am)
Re: [patch 00/52] vfs scalability patches updated, Dave Chinner, (Wed Jun 30, 4:30 am)
Re: [patch 50/52] mm: implement per-zone shrinker, Nick Piggin, (Wed Jun 30, 5:03 am)
Re: [patch 37/52] fs: icache lazy lru, Nick Piggin, (Wed Jun 30, 5:06 am)
Re: [patch 38/52] fs: icache RCU free inodes, Nick Piggin, (Wed Jun 30, 5:07 am)
Re: [patch 51/52] fs: per-zone dentry and inode LRU, Nick Piggin, (Wed Jun 30, 5:13 am)
Re: [patch 52/52] fs: icache less I_FREEING time, Nick Piggin, (Wed Jun 30, 5:14 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Wed Jun 30, 5:40 am)
Re: [patch 00/52] vfs scalability patches updated, Frank Mayhar, (Wed Jun 30, 10:08 am)
Re: [patch 29/52] fs: icache lock i_count, Dave Chinner, (Wed Jun 30, 7:36 pm)
Re: [patch 37/52] fs: icache lazy lru, Dave Chinner, (Wed Jun 30, 7:46 pm)
Re: [patch 52/52] fs: icache less I_FREEING time, Dave Chinner, (Wed Jun 30, 8:33 pm)
Re: [patch 00/52] vfs scalability patches updated, Dave Chinner, (Wed Jun 30, 8:56 pm)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Thu Jul 1, 12:54 am)
Re: [patch 37/52] fs: icache lazy lru, Nick Piggin, (Thu Jul 1, 12:57 am)
Re: [patch 52/52] fs: icache less I_FREEING time, Nick Piggin, (Thu Jul 1, 1:06 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Thu Jul 1, 1:20 am)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Thu Jul 1, 2:36 am)
Re: [patch 29/52] fs: icache lock i_count, Frank Mayhar, (Thu Jul 1, 9:21 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Thu Jul 1, 10:23 am)
Re: [patch 00/52] vfs scalability patches updated, Andi Kleen, (Thu Jul 1, 10:28 am)
Re: [patch 00/52] vfs scalability patches updated, Linus Torvalds, (Thu Jul 1, 10:35 am)
Re: [patch 00/52] vfs scalability patches updated, Andi Kleen, (Thu Jul 1, 10:36 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Thu Jul 1, 10:52 am)
Re: [patch 00/52] vfs scalability patches updated, Paul E. McKenney, (Thu Jul 1, 9:01 pm)
Re: [patch 29/52] fs: icache lock i_count, Andrew Morton, (Fri Jul 2, 7:03 pm)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Fri Jul 2, 8:41 pm)
Re: [patch 29/52] fs: icache lock i_count, Andrew Morton, (Fri Jul 2, 9:31 pm)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Fri Jul 2, 10:06 pm)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Fri Jul 2, 10:18 pm)
Re: [patch 29/52] fs: icache lock i_count, Dave Chinner, (Mon Jul 5, 3:41 pm)
Re: [patch 29/52] fs: icache lock i_count, Theodore Tso, (Tue Jul 6, 3:38 am)
Re: [patch 29/52] fs: icache lock i_count, Nick Piggin, (Tue Jul 6, 6:04 am)
Re: [patch 00/52] vfs scalability patches updated, Nick Piggin, (Tue Jul 6, 10:49 am)
Re: [patch 24/52] fs: dcache reduce d_parent locking, Nick Piggin, (Wed Jul 7, 7:35 am)
Re: [patch 29/52] fs: icache lock i_count, Frank Mayhar, (Wed Jul 7, 10:00 am)