Skip to contentSkip to conversation

Writeback fix for concurrent large and small file writes

PATCH In review Michael Rubin 3 participants 8 messages Nov 28, 2007 – Dec 4, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Writeback fix for concurrent large and small file writes

#1 lore raw
Quoted 11 lines · Michael Rubin
Quoted 1 line

From [email protected] Wed Nov 28 11:10:06 2007

Message-Id: <[email protected]>
Date: Wed, 28 Nov 2007 11:01:21 -0800
From: [email protected]
To: [email protected]
Subject: [patch 1/1] Writeback fix for concurrent large and small file writes.

From: Michael Rubin <[email protected]>

Fixing a bug where writing to large files while concurrently writing to smaller ones creates a situation where writeback cannot keep up with the

Could you demonstrate the situation? Or if I guess it right, could it be fixed by the following patch? (not a nack: If so, your patch could also be considered as a general purpose improvement, instead of a bug fix.)

fs/fs-writeback.c +1 -1
index 0fca820..62e62e2 100644
@@ -301,7 +301,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
 			 * Someone redirtied the inode while were writing back
 			 * the pages.
 			 */
-			redirty_tail(inode);
+			requeue_io(inode);
 		} else if (atomic_read(&inode->i_count)) {
 			/*
 			 * The inode is clean, inuse

Thank you,
Fengguang

Quoted 17 lines

traffic and memory baloons until the we hit the threshold watermark. This can result in surprising latency spikes when syncing. This latency can take minutes on large memory systems. Upon request I can provide a test to reproduce this situation. The flush tree fixes this issue and fixes several other minor issues with fairness also.

1) Adding a data structure to guarantee fairness when writing inodes to disk. The flush_tree is based on an rbtree. The only difference is how duplicate keys are chained off the same rb_node.

2) Added a FS flag to mark file systems that are not disk backed so we don't have to flush them. Not sure I marked all of them. But just marking these improves writeback performance.

3) Added an inode flag to allow inodes to be marked so that they are never written back to disk. See get_pipe_inode.

Quoted 6 lines

Under autotest this patch has passed: fsx, bonnie, and iozone. I am currently writing more writeback focused tests (which so far have been passed) to add into autotest.

---

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw

So Feng's one line change fixes the problem at hand. I will do some more testing with it and then submit his patch credited with him for 2.6.24. If that's cool with Feng.

Also I will take the comment changes and re-submit my patch for 2.6.25 for general purpose improvement and see what happens.

mrubin

Quoted 32 lines · Fengguang Wu
Quoted 11 lines · Michael Rubin
Quoted 1 line

From [email protected] Wed Nov 28 11:10:06 2007

Message-Id: <[email protected]>
Date: Wed, 28 Nov 2007 11:01:21 -0800
From: [email protected]
To: [email protected]
Subject: [patch 1/1] Writeback fix for concurrent large and small file writes.

From: Michael Rubin <[email protected]>

Fixing a bug where writing to large files while concurrently writing to smaller ones creates a situation where writeback cannot keep up with the

Could you demonstrate the situation? Or if I guess it right, could it be fixed by the following patch? (not a nack: If so, your patch could also be considered as a general purpose improvement, instead of a bug fix.)

fs/fs-writeback.c +1 -1
index 0fca820..62e62e2 100644
@@ -301,7 +301,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                         * Someone redirtied the inode while were writing back
                         * the pages.
                         */
-                       redirty_tail(inode);
+                       requeue_io(inode);
                } else if (atomic_read(&inode->i_count)) {
                        /*
                         * The inode is clean, inuse
Quoted 29 lines

Thank you,
Fengguang

Quoted 23 lines

traffic and memory baloons until the we hit the threshold watermark. This can result in surprising latency spikes when syncing. This latency can take minutes on large memory systems. Upon request I can provide a test to reproduce this situation. The flush tree fixes this issue and fixes several other minor issues with fairness also.

1) Adding a data structure to guarantee fairness when writing inodes to disk. The flush_tree is based on an rbtree. The only difference is how duplicate keys are chained off the same rb_node.

2) Added a FS flag to mark file systems that are not disk backed so we don't have to flush them. Not sure I marked all of them. But just marking these improves writeback performance.

3) Added an inode flag to allow inodes to be marked so that they are never written back to disk. See get_pipe_inode.

Under autotest this patch has passed: fsx, bonnie, and iozone. I am currently writing more writeback focused tests (which so far have been passed) to add into autotest.

---

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
In reply to Fengguang Wu

Due to my faux pas of top posting (see
http://www.zip.com.au/~akpm/linux/patches/stuff/top-posting.txt) I am resending this email.

Quoted 11 lines · Fengguang Wu

Could you demonstrate the situation? Or if I guess it right, could it be fixed by the following patch? (not a nack: If so, your patch could also be considered as a general purpose improvement, instead of a bug fix.)

fs/fs-writeback.c +0 -0
index 0fca820..62e62e2 100644

fs/fs-writeback.c __sync_single_inode(struct inode *inode, struct writeback_control *wbc) · line 307

Quoted 8 lines
fs/fs-writeback.c +1 -1
@@ -301,7 +301,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                         * Someone redirtied the inode while were writing back
                         * the pages.
                         */
-                       redirty_tail(inode);
+                       requeue_io(inode);
                } else if (atomic_read(&inode->i_count)) {
                        /*
                         * The inode is clean, inuse

By testing the situation I can confirm that the one line patch above fixes the problem.

I will continue testing some other cases to see if it cause any other issues but I don't expect it to.
I will post this change for 2.6.24 and list Feng as author. If that's ok with Feng.

As for the original patch I will resubmit it for 2.6.25 as a general purpose improvement.

mrubin

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw
Quoted 28 lines · Michael Rubin

Due to my faux pas of top posting (see
http://www.zip.com.au/~akpm/linux/patches/stuff/top-posting.txt) I am resending this email.

Quoted 11 lines · Fengguang Wu

Could you demonstrate the situation? Or if I guess it right, could it be fixed by the following patch? (not a nack: If so, your patch could also be considered as a general purpose improvement, instead of a bug fix.)

fs/fs-writeback.c +0 -0
index 0fca820..62e62e2 100644

fs/fs-writeback.c __sync_single_inode(struct inode *inode, struct writeback_control *wbc) · line 307

Quoted 8 lines
fs/fs-writeback.c +1 -1
@@ -301,7 +301,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                         * Someone redirtied the inode while were writing back
                         * the pages.
                         */
-                       redirty_tail(inode);
+                       requeue_io(inode);
                } else if (atomic_read(&inode->i_count)) {
                        /*
                         * The inode is clean, inuse

By testing the situation I can confirm that the one line patch above fixes the problem.

Quoted 2 lines

I will continue testing some other cases to see if it cause any other issues but I don't expect it to.

One major concern could be whether a continuous writer dirting pages at the 'right' pace will generate a steady flow of write I/Os which are _tiny_hence_inefficient_.

I have gathered some timing info about writeback speed in
http://lkml.org/lkml/2007/10/4/468. For ext3, it takes wb_kupdate() ~15ms to submit 4MB. Whereas one disk I/O typically takes ~5ms. So if there are too many tiny write I/Os, they will simply get delayed and merged into bigger ones.

So it's not a problem in *theory* :-)

Quoted 2 lines

I will post this change for 2.6.24 and list Feng as author. If that's ok with Feng.

Thank you.

Quoted 2 lines

As for the original patch I will resubmit it for 2.6.25 as a general purpose improvement.

There are some discussions and patches on inode number based writeback clustering which you may want to reference/compare with:

                http://lkml.org/lkml/2007/8/21/396
                http://lkml.org/lkml/2007/8/27/45

Cheers,
Fengguang

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
Quoted 3 lines · On Nov 29, 2007 5:32 PM, Fengguang Wu <[email protected]:
Quoted 3 lines · Fengguang Wu
Quoted 2 lines

Could you demonstrate the situation? Or if I guess it right, could it be fixed by the following patch?

Feng I am sorry to have been mistaken but I reran my tests and I am now finding that the patch you gave me is NOT fixing the problem. The patch I refer to is the one you posted on this thread that adds a requeue_io in __sync_single_inode.

I tarred up my test code. It is still in very rough shape but it can reproduce the issue. You can find it here:

http://neverthere.org/mhr/wb/wb-test.tar.bz2

Just make the test and run it with the args "-duration 0:5:0 -starvation". You must be root so it can set some sysctl values.

Quoted 8 lines

One major concern could be whether a continuous writer dirting pages at the 'right' pace will generate a steady flow of write I/Os which are _tiny_hence_inefficient_.

So it's not a problem in *theory* :-)

Quoted 2 lines

I will post this change for 2.6.24 and list Feng as author. If that's ok with Feng.

I am going to try to track down what is up in 2.6.24 and see if I can find a less dramatic fix than my tree patch for the short term. If you get a chance to reproduce the problem with my test on your patch that would rock.

I still would like to see my full patch accepted into 2.6.25. A patch should be arriving shortly that will incorporate my larger patch and Qi Yong's fix for skip-writing-data-pages-when-inode-is-under-i_sync.
http://www.gossamer-threads.com/lists/linux/kernel/849493

As always thanks for your patience,

mrubin

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#6 lore raw
In reply to Michael Rubin

Two typos in comments.

Cheers,
FJP

Quoted 5 lines · Michael Rubin

+ * The flush tree organizes the dirtied_when keys with the rb_tree. Any
+ * inodes with a duplicate dirtied_when value are link listed together. This + * link list is sorted by the inode's i_flushed_when. When both the
+ * dirited_when and the i_flushed_when are indentical the order in the
+ * linked list determines the order we flush the inodes.

s/dirited_when/dirtied_when/

Quoted 4 lines

+ * Here is where we interate to find the next inode to process. The
+ * strategy is to first look for any other inodes with the same dirtied_when + * value. If we have already processed that node then we need to find + * the next highest dirtied_when value in the tree.

s/interate/iterate/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw

Thank you. Integrated the fixes in my patch.

Quoted 12 lines · Frans Pop

Two typos in comments.

Cheers,
FJP

Quoted 5 lines · Michael Rubin

+ * The flush tree organizes the dirtied_when keys with the rb_tree. Any
+ * inodes with a duplicate dirtied_when value are link listed together. This + * link list is sorted by the inode's i_flushed_when. When both the
+ * dirited_when and the i_flushed_when are indentical the order in the
+ * linked list determines the order we flush the inodes.

Quoted 10 lines

s/dirited_when/dirtied_when/

Quoted 4 lines

+ * Here is where we interate to find the next inode to process. The
+ * strategy is to first look for any other inodes with the same dirtied_when + * value. If we have already processed that node then we need to find + * the next highest dirtied_when value in the tree.

s/interate/iterate/

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>