From: Ingo Molnar <mingo@elte.hu>
To: Andrew Morton <akpm@osdl.org>
Cc: Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk>,
linux-kernel@vger.kernel.org
Subject: [patch] inode-lock-break.patch, 2.6.8-rc3-mm2
Date: Mon, 9 Aug 2004 12:21:25 +0200 [thread overview]
Message-ID: <20040809102125.GA12391@elte.hu> (raw)
[-- Attachment #1: Type: text/plain, Size: 932 bytes --]
the attached patch does a scheduling-latency lock-break of two functions
within the VFS: prune_icache() [typically triggered by VM load] and
invalidate_inodes() [triggered by e.g. CDROM auto-umounts - reported by
Florian Schmidt].
prune_icache() was easy - it works off a global list head so adding
voluntary_resched_lock() solves the latency.
invalidate_inodes() was trickier - we scan a list filtering for specific
inodes - simple lock-break is incorrect because the list might change at
the cursor, and retrying opens up the potential for livelocks.
The solution i found was to insert a private marker into the list and to
start off that point - the inodes of the superblock in question wont get
reordered within the list because the filesystem is quiet already at
this point. (other inodes of other filesystems might get reordered but
that doesnt matter.)
tested on x86, the patch solves these particular latencies.
Ingo
[-- Attachment #2: inode-lock-break.patch --]
[-- Type: text/plain, Size: 2776 bytes --]
the attached patch does a scheduling-latency lock-break of two functions
within the VFS: prune_icache() [typically triggered by VM load] and
invalidate_inodes() [triggered by e.g. CDROM auto-umounts - reported by
Florian Schmidt].
prune_icache() was easy - it works off a global list head so adding
voluntary_resched_lock() solves the latency.
invalidate_inodes() was trickier - we scan a list filtering for specific
inodes - simple lock-break is incorrect because the list might change at
the cursor, and retrying opens up the potential for livelocks.
The solution i found was to insert a private marker into the list and to
start off that point - the inodes of the superblock in question wont get
reordered within the list because the filesystem is quiet already at
this point. (other inodes of other filesystems might get reordered but
that doesnt matter.)
tested on x86, the patch solves these particular latencies.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
--- linux/fs/inode.c.orig
+++ linux/fs/inode.c
@@ -296,7 +296,7 @@ static void dispose_list(struct list_hea
/*
* Invalidate all inodes for a device.
*/
-static int invalidate_list(struct list_head *head, struct list_head *dispose)
+static int invalidate_list(struct list_head *head, struct list_head *dispose, struct list_head *mark)
{
struct list_head *next;
int busy = 0, count = 0;
@@ -306,6 +306,21 @@ static int invalidate_list(struct list_h
struct list_head * tmp = next;
struct inode * inode;
+ /*
+ * Preempt if necessary. To make this safe we use a dummy
+ * inode as a marker - we can continue off that point.
+ * We rely on this sb's inodes (including the marker) not
+ * getting reordered within the list during umount. Other
+ * inodes might get reordered.
+ */
+ if (need_resched()) {
+ list_add_tail(mark, next);
+ spin_unlock(&inode_lock);
+ cond_resched();
+ spin_lock(&inode_lock);
+ tmp = next = mark->next;
+ list_del(mark);
+ }
next = next->next;
if (tmp == head)
break;
@@ -346,15 +361,21 @@ int invalidate_inodes(struct super_block
{
int busy;
LIST_HEAD(throw_away);
+ struct inode *marker;
+
+ marker = kmalloc(sizeof(*marker), GFP_KERNEL|__GFP_REPEAT);
+ memset(marker, 0, sizeof(*marker));
down(&iprune_sem);
spin_lock(&inode_lock);
- busy = invalidate_list(&sb->s_inodes, &throw_away);
+ busy = invalidate_list(&sb->s_inodes, &throw_away, &marker->i_list);
spin_unlock(&inode_lock);
dispose_list(&throw_away);
up(&iprune_sem);
+ kfree(marker);
+
return busy;
}
@@ -425,6 +446,8 @@ static void prune_icache(int nr_to_scan)
for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
struct inode *inode;
+ cond_resched_lock(&inode_lock);
+
if (list_empty(&inode_unused))
break;
next reply other threads:[~2004-08-09 10:23 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-09 10:21 Ingo Molnar [this message]
2004-08-09 10:25 ` [patch] inode-lock-break.patch, 2.6.8-rc3-mm2 Andrew Morton
2004-08-09 10:45 ` Ingo Molnar
2004-08-09 14:01 ` [patch] preempt-smp.patch, 2.6.8-rc3-mm2 Ingo Molnar
2004-08-11 16:14 ` Peter Zijlstra
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=20040809102125.GA12391@elte.hu \
--to=mingo@elte.hu \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@parcelfarce.linux.theplanet.co.uk \
/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