mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: npiggin@suse.de
To: linux-fsdevel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [patch 25/33] fs: icache protect inode state
Date: Fri, 04 Sep 2009 16:52:06 +1000	[thread overview]
Message-ID: <20090904065537.906625456@nick.local0.net> (raw)
In-Reply-To: <20090904065142.114706411@nick.local0.net>

[-- Attachment #1: fs-inode_lock-scale-6b.patch --]
[-- Type: text/plain, Size: 6744 bytes --]

Protect i_hash, i_sb_list etc members with i_lock.
---
 fs/hugetlbfs/inode.c |   14 +++++++++-----
 fs/inode.c           |   29 ++++++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 8 deletions(-)

Index: linux-2.6/fs/inode.c
===================================================================
--- linux-2.6.orig/fs/inode.c
+++ linux-2.6/fs/inode.c
@@ -363,12 +363,14 @@ static void dispose_list(struct list_hea
 		clear_inode(inode);
 
 		spin_lock(&inode_lock);
+		spin_lock(&sb_inode_list_lock);
+		spin_lock(&inode->i_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);
+		spin_unlock(&inode->i_lock);
 		spin_unlock(&inode_lock);
 
 		wake_up_inode(inode);
@@ -670,7 +672,6 @@ __inode_add_to_lists(struct super_block
 			struct inode *inode)
 {
 	atomic_inc(&inodes_stat.nr_inodes);
-	spin_lock(&sb_inode_list_lock);
 	list_add(&inode->i_sb_list, &sb->s_inodes);
 	spin_unlock(&sb_inode_list_lock);
 	spin_lock(&wb_inode_list_lock);
@@ -700,7 +701,10 @@ void inode_add_to_lists(struct super_blo
 	struct hlist_head *head = inode_hashtable + hash(sb, inode->i_ino);
 
 	spin_lock(&inode_lock);
+	spin_lock(&sb_inode_list_lock);
+	spin_lock(&inode->i_lock);
 	__inode_add_to_lists(sb, head, inode);
+	spin_unlock(&inode->i_lock);
 	spin_unlock(&inode_lock);
 }
 EXPORT_SYMBOL_GPL(inode_add_to_lists);
@@ -732,9 +736,12 @@ struct inode *new_inode(struct super_blo
 	inode = alloc_inode(sb);
 	if (inode) {
 		spin_lock(&inode_lock);
+		spin_lock(&sb_inode_list_lock);
+		spin_lock(&inode->i_lock);
 		inode->i_ino = ++last_ino;
 		inode->i_state = 0;
 		__inode_add_to_lists(sb, NULL, inode);
+		spin_unlock(&inode->i_lock);
 		spin_unlock(&inode_lock);
 	}
 	return inode;
@@ -796,11 +803,14 @@ static struct inode *get_new_inode(struc
 		/* We released the lock, so.. */
 		old = find_inode(sb, head, test, data);
 		if (!old) {
+			spin_lock(&sb_inode_list_lock);
+			spin_lock(&inode->i_lock);
 			if (set(inode, data))
 				goto set_failed;
 
 			inode->i_state = I_LOCK|I_NEW;
 			__inode_add_to_lists(sb, head, inode);
+			spin_unlock(&inode->i_lock);
 			spin_unlock(&inode_lock);
 
 			/* Return the locked inode with I_NEW set, the
@@ -825,6 +835,7 @@ static struct inode *get_new_inode(struc
 
 set_failed:
 	spin_unlock(&inode->i_lock);
+	spin_unlock(&sb_inode_list_lock);
 	spin_unlock(&inode_lock);
 	destroy_inode(inode);
 	return NULL;
@@ -847,9 +858,12 @@ static struct inode *get_new_inode_fast(
 		/* We released the lock, so.. */
 		old = find_inode_fast(sb, head, ino);
 		if (!old) {
+			spin_lock(&sb_inode_list_lock);
+			spin_lock(&inode->i_lock);
 			inode->i_ino = ino;
 			inode->i_state = I_LOCK|I_NEW;
 			__inode_add_to_lists(sb, head, inode);
+			spin_unlock(&inode->i_lock);
 			spin_unlock(&inode_lock);
 
 			/* Return the locked inode with I_NEW set, the
@@ -1185,6 +1199,7 @@ repeat:
 			break;
 		}
 		if (likely(!node)) {
+			/* XXX: initialize inode->i_lock to locked? */
 			hlist_add_head(&inode->i_hash, head);
 			spin_unlock(&inode_hash_lock);
 			spin_unlock(&inode_lock);
@@ -1233,6 +1248,7 @@ repeat:
 			break;
 		}
 		if (likely(!node)) {
+			/* XXX: initialize inode->i_lock to locked? */
 			hlist_add_head(&inode->i_hash, head);
 			spin_unlock(&inode_hash_lock);
 			spin_unlock(&inode_lock);
@@ -1263,10 +1279,13 @@ EXPORT_SYMBOL(insert_inode_locked4);
 void __insert_inode_hash(struct inode *inode, unsigned long hashval)
 {
 	struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
+
 	spin_lock(&inode_lock);
+	spin_lock(&inode->i_lock);
 	spin_lock(&inode_hash_lock);
 	hlist_add_head(&inode->i_hash, head);
 	spin_unlock(&inode_hash_lock);
+	spin_unlock(&inode->i_lock);
 	spin_unlock(&inode_lock);
 }
 EXPORT_SYMBOL(__insert_inode_hash);
@@ -1280,9 +1299,11 @@ EXPORT_SYMBOL(__insert_inode_hash);
 void remove_inode_hash(struct inode *inode)
 {
 	spin_lock(&inode_lock);
+	spin_lock(&inode->i_lock);
 	spin_lock(&inode_hash_lock);
 	hlist_del_init(&inode->i_hash);
 	spin_unlock(&inode_hash_lock);
+	spin_unlock(&inode->i_lock);
 	spin_unlock(&inode_lock);
 }
 EXPORT_SYMBOL(remove_inode_hash);
@@ -1330,9 +1351,11 @@ void generic_delete_inode(struct inode *
 		clear_inode(inode);
 	}
 	spin_lock(&inode_lock);
+	spin_lock(&inode->i_lock);
 	spin_lock(&inode_hash_lock);
 	hlist_del_init(&inode->i_hash);
 	spin_unlock(&inode_hash_lock);
+	spin_unlock(&inode->i_lock);
 	spin_unlock(&inode_lock);
 	wake_up_inode(inode);
 	BUG_ON(inode->i_state != I_CLEAR);
@@ -1368,10 +1391,10 @@ static void generic_forget_inode(struct
 		spin_lock(&inode->i_lock);
 		WARN_ON(inode->i_state & I_NEW);
 		inode->i_state &= ~I_WILL_FREE;
-		atomic_dec(&inodes_stat.nr_unused);
 		spin_lock(&inode_hash_lock);
 		hlist_del_init(&inode->i_hash);
 		spin_unlock(&inode_hash_lock);
+		atomic_dec(&inodes_stat.nr_unused);
 	}
 	spin_lock(&wb_inode_list_lock);
 	list_del_init(&inode->i_list);
Index: linux-2.6/fs/hugetlbfs/inode.c
===================================================================
--- linux-2.6.orig/fs/hugetlbfs/inode.c
+++ linux-2.6/fs/hugetlbfs/inode.c
@@ -391,12 +391,15 @@ static void hugetlbfs_forget_inode(struc
 		}
 		atomic_inc(&inodes_stat.nr_unused);
 		if (!sb || (sb->s_flags & MS_ACTIVE)) {
+			spin_unlock(&inode->i_lock);
+			spin_unlock(&sb_inode_list_lock);
 			spin_unlock(&inode_lock);
 			return;
 		}
-		spin_lock(&inode->i_lock);
+		WARN_ON(inode->i_state & I_NEW);
 		inode->i_state |= I_WILL_FREE;
 		spin_unlock(&inode->i_lock);
+		spin_unlock(&sb_inode_list_lock);
 		spin_unlock(&inode_lock);
 		/*
 		 * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK
@@ -404,27 +407,28 @@ static void hugetlbfs_forget_inode(struc
 		 */
 		write_inode_now(inode, 1);
 		spin_lock(&inode_lock);
+		spin_lock(&sb_inode_list_lock);
 		spin_lock(&inode->i_lock);
+		WARN_ON(inode->i_state & I_NEW);
 		inode->i_state &= ~I_WILL_FREE;
 		spin_lock(&inode_hash_lock);
 		hlist_del_init(&inode->i_hash);
 		spin_unlock(&inode_hash_lock);
-		spin_unlock(&inode->i_lock);
 		atomic_dec(&inodes_stat.nr_unused);
 	}
 	spin_lock(&wb_inode_list_lock);
 	list_del_init(&inode->i_list);
 	spin_unlock(&wb_inode_list_lock);
-	spin_lock(&sb_inode_list_lock);
 	list_del_init(&inode->i_sb_list);
 	spin_unlock(&sb_inode_list_lock);
-	spin_lock(&inode->i_lock);
+	WARN_ON(inode->i_state & I_NEW);
 	inode->i_state |= I_FREEING;
 	spin_unlock(&inode->i_lock);
-	atomic_dec(&inodes_stat.nr_unused);
 	spin_unlock(&inode_lock);
+	atomic_dec(&inodes_stat.nr_unused);
 	truncate_hugepages(inode, 0);
 	clear_inode(inode);
+	/* XXX: why no wake_up_inode? */
 	destroy_inode(inode);
 }
 



  parent reply	other threads:[~2009-09-04  7:01 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-04  6:51 [patch 00/33] my current vfs scalability patch queue npiggin
2009-09-04  6:51 ` [patch 01/33] fs: no games with DCACHE_UNHASHED npiggin
2009-09-04  6:51 ` [patch 02/33] fs: cleanup files_lock npiggin
2009-09-04  6:51 ` [patch 03/33] fs: scale files_lock npiggin
2009-09-28 13:22   ` Peter Zijlstra
2009-09-28 13:24   ` Peter Zijlstra
2009-10-01  2:16     ` Nick Piggin
2009-09-04  6:51 ` [patch 04/33] fs: brlock vfsmount_lock npiggin
2009-09-04 15:19   ` Jens Axboe
2009-09-07  7:39     ` Nick Piggin
2009-09-22 15:17   ` Al Viro
2009-09-27 19:56     ` Nick Piggin
2009-09-28 13:21       ` Peter Zijlstra
2009-10-01  2:10         ` Nick Piggin
2009-09-04  6:51 ` [patch 05/33] fs: scale mntget/mntput npiggin
2009-09-07  9:41   ` Nick Piggin
2009-09-04  6:51 ` [patch 06/33] fs: dcache scale hash npiggin
2009-09-04  6:51 ` [patch 07/33] fs: dcache scale lru npiggin
2009-09-04  6:51 ` [patch 08/33] fs: dcache scale nr_dentry npiggin
2009-09-04 14:41   ` Daniel Walker
2009-09-07  7:36     ` Nick Piggin
2009-09-04  6:51 ` [patch 09/33] fs: dcache scale dentry refcount npiggin
2009-09-06 18:01   ` Eric Paris
2009-09-07  7:44     ` Nick Piggin
2009-09-07 11:21       ` Eric Paris
2009-09-07 11:35         ` Nick Piggin
2009-09-04  6:51 ` [patch 10/33] fs: dcache scale d_unhashed npiggin
2009-09-04  6:51 ` [patch 11/33] fs: dcache scale subdirs npiggin
2010-06-17 15:13   ` Peter Zijlstra
2010-06-17 16:53     ` Nick Piggin
2010-06-21 13:35       ` Peter Zijlstra
2010-06-21 14:48         ` Nick Piggin
2010-06-21 14:55           ` Peter Zijlstra
2010-06-22  6:02             ` john stultz
2010-06-22  6:06               ` Nick Piggin
2010-06-22  7:27               ` Peter Zijlstra
2010-06-23  2:03                 ` john stultz
2010-06-23  7:23                   ` Peter Zijlstra
2009-09-04  6:51 ` [patch 12/33] fs: scale inode alias list npiggin
2009-09-04  6:51 ` [patch 13/33] fs: use RCU / seqlock logic for reverse and multi-step operaitons npiggin
2009-09-04  6:51 ` [patch 14/33] fs: dcache remove dcache_lock npiggin
2009-09-04  6:51 ` [patch 15/33] fs: dcache reduce dput locking npiggin
2009-09-04  6:51 ` [patch 16/33] fs: dcache per-bucket dcache hash locking npiggin
2009-09-04 14:51   ` Daniel Walker
2009-09-07  7:38     ` Nick Piggin
2009-09-04  6:51 ` [patch 17/33] fs: dcache reduce dcache_inode_lock npiggin
2009-09-04  6:51 ` [patch 18/33] fs: dcache per-inode inode alias locking npiggin
2009-09-04  6:52 ` [patch 19/33] fs: icache lock s_inodes list npiggin
2009-09-04  6:52 ` [patch 20/33] fs: icache lock inode hash npiggin
2009-09-04  6:52 ` [patch 21/33] fs: icache lock i_state npiggin
2009-09-04  6:52 ` [patch 22/33] fs: icache lock i_count npiggin
2009-09-04  6:52 ` [patch 23/33] fs: icache atomic inodes_stat npiggin
2009-09-04  6:52 ` [patch 24/33] fs: icache lock lru/writeback lists npiggin
2009-09-04  6:52 ` npiggin [this message]
2009-09-04  6:52 ` [patch 26/33] fs: inode atomic last_ino, iunique lock npiggin
2009-09-04  6:52 ` [patch 27/33] fs: icache remove inode_lock npiggin
2009-09-04  6:52 ` [patch 28/33] fs: inode factor hash lock into functions npiggin
2009-09-04  6:52 ` [patch 29/33] Remove the global inode_hash_lock and replace it with per-hash-bucket locks. fs: inode per-bucket inode hash locks npiggin
2009-09-04  7:05   ` Nick Piggin
2009-09-04  6:52 ` [patch 30/33] fs: inode lazy lru npiggin
2009-09-04  6:52 ` [patch 31/33] fs: RCU free inodes npiggin
2009-09-04  6:52 ` [patch 32/33] fs: rcu walk for i_sb_list npiggin
2009-09-04  6:52 ` [patch 33/33] fs: improve scalability of pseudo filesystems npiggin
2009-09-04  7:05 ` [patch 00/33] my current vfs scalability patch queue Nick Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090904065537.906625456@nick.local0.net \
    --to=npiggin@suse.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®