Converting writeback linked lists to a tree based data structure
Subsystems (4)
PATCH 1/1 Converting writeback linked lists to a tree based data structure
For those of you who have waited so long. This is the third submission of the first attempt at this patch. It is a trilogy.
Two changes are in this patch. They are dependant on each other.
In addition we get an unintended performance improvement. Syncing 1,000,000 inodes each with 4KB of dirty data takes the original kernel 83 seconds and with the change it take 77 seconds.
1) Adding a datastructure to guarantee fairness when writing inodes to disk and simplify the code base.
When inodes are parked for writeback they are parked in the flush_tree. The flush tree is a data structure based on an rb tree.
Duplicate keys are handled by making a list in the tree for each key value. The order of how we choose the next inode to flush is decided by two fields. First the earliest dirtied_when value. If there are duplicate dirtied_when values then the earliest i_flush_gen value determines who gets flushed next.
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_flush_gen. When both the dirtied_when and the i_flush_gen are identical the order in the linked list determines the order we flush the inodes.
2) Added an inode flag to allow inodes to be marked so that they are never written back to disk.
The motivation behind this change is several fold. The first is to insure fairness in the writeback algorithm. The second is to deal with a bug where the writing to large files concurrently to smaller ones creates a situation where writeback cannot keep up with traffic and memory baloons until the we hit the threshold watermark. This can result in surprising long latency with respect to disk traffic. This latency can take minutes. The flush tree fixes this issue and fixes several other minor issues with fairness also.
---
fs/anon_inodes.c +1 -7
@@ -154,13 +154,7 @@ static struct inode *anon_inode_mkinode( inode->i_fop = &anon_inode_fops; -/* -* Mark the inode dirty from the very beginning, -* that way it will never be moved to the dirty -* list because mark_inode_dirty() will think -* that it already _is_ on the dirty list. -*/ - inode->i_state =I_DIRTY ; + inode->i_state =I_WRITEBACK_NEVER ; inode->i_mode =S_IRUSR |S_IWUSR ; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid;
fs/fs-writeback.c +300 -193
702 lines not on this page · raw message
fs/hugetlbfs/inode.c +1 -1
@@ -383,7 +383,7 @@ static void hugetlbfs_forget_inode(strucstruct super_block *sb = inode->i_sb;if (!hlist_unhashed (&inode->i_hash)) { -if (!(inode->i_state & (I_DIRTY |I_SYNC ))) +if (!(inode->i_state & (I_DIRTY |I_SYNC |I_WRITEBACK_NEVER )))list_move (&inode->i_list, &inode_unused); inodes_stat.nr_unused++;if (!sb || (sb->s_flags &MS_ACTIVE )) {
fs/inode.c +10 -2
@@ -143,6 +143,7 @@ static struct inode *alloc_inode(struct inode->i_cdev =NULL ; inode->i_rdev =0 ; inode->dirtied_when =0 ; +memset (&inode->i_flush_node,0 ,sizeof (inode->i_flush_node));if (security_inode_alloc (inode)) {if (inode->i_sb->s_op->destroy_inode) inode->i_sb->s_op->destroy_inode (inode);
@@ -337,6 +338,10 @@ static int invalidate_list(struct list_h inode = list_entry(tmp, struct inode, i_sb_list);invalidate_inode_buffers (inode);if (!atomic_read (&inode->i_count)) { +if (inode->i_state &I_DIRTY ) { +flush_tree_remove (inode->i_sb, inode); + inode->i_state &= ~I_DIRTY ; + }list_move (&inode->i_list, dispose); inode->i_state |=I_FREEING ; count++;
@@ -1043,7 +1048,10 @@ EXPORT_SYMBOL(remove_inode_hash);void generic_delete_inode (struct inode *inode) {const struct super_operations *op = inode->i_sb->s_op; - +if ((inode->i_state &I_DIRTY )) { +flush_tree_remove (inode->i_sb, inode); + inode->i_state &= ~I_DIRTY ; + }list_del_init (&inode->i_list);list_del_init (&inode->i_sb_list); inode->i_state |=I_FREEING ;
@@ -1080,7 +1088,7 @@ static void generic_forget_inode(structstruct super_block *sb = inode->i_sb;if (!hlist_unhashed (&inode->i_hash)) { -if (!(inode->i_state & (I_DIRTY |I_SYNC ))) +if (!(inode->i_state & (I_DIRTY |I_SYNC |I_WRITEBACK_NEVER )))list_move (&inode->i_list, &inode_unused); inodes_stat.nr_unused++;if (sb->s_flags &MS_ACTIVE ) {
fs/pipe.c +1 -7
@@ -930,13 +930,7 @@ static struct inode * get_pipe_inode(voi pipe->readers = pipe->writers =1 ; inode->i_fop = &rdwr_pipe_fops; -/* -* Mark the inode dirty from the very beginning, -* that way it will never be moved to the dirty -* list because "mark_inode_dirty()" will think -* that it already _is_ on the dirty list. -*/ - inode->i_state =I_DIRTY ; + inode->i_state =I_WRITEBACK_NEVER ; inode->i_mode =S_IFIFO |S_IRUSR |S_IWUSR ; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid;
fs/super.c +2 -3
@@ -61,9 +61,7 @@ static struct super_block *alloc_super(s s =NULL ; goto out; } -INIT_LIST_HEAD (&s->s_dirty); -INIT_LIST_HEAD (&s->s_io); -INIT_LIST_HEAD (&s->s_more_io); + s->s_flush_root =RB_ROOT ;INIT_LIST_HEAD (&s->s_files);INIT_LIST_HEAD (&s->s_instances);INIT_HLIST_HEAD (&s->s_anon);
@@ -103,6 +101,7 @@ out:*/ static inline void destroy_super (struct super_block *s) { +mutex_destroy (&s->s_flush_lock);security_sb_free (s);kfree (s->s_subtype);kfree (s);
include/linux/fs.h +10 -3
@@ -280,6 +280,7 @@ extern int dir_notify_enable;#include <linux/kobject.h> #include <linux/list.h> #include <linux/radix-tree.h> +#include <linux/rbtree.h> #include <linux/prio_tree.h> #include <linux/init.h> #include <linux/pid.h>
@@ -592,6 +593,8 @@ struct inode {struct hlist_node i_hash;struct list_head i_list;struct list_head i_sb_list; +struct rb_node i_flush_node; +unsigned long long i_flush_gen;struct list_head i_dentry;unsigned long i_ino;atomic_t i_count;
@@ -1003,9 +1006,10 @@ struct super_block {struct xattr_handler **s_xattr;struct list_head s_inodes;/* all inodes */ -struct list_head s_dirty;/* dirty inodes */ -struct list_head s_io;/* parked for writeback */ -struct list_head s_more_io;/* parked for more writeback */ +struct rb_root s_flush_root; +unsigned long s_flush_count; +unsigned long long s_flush_gen; +struct hlist_head s_anon;/* anonymous dentries for (nfs) exporting */ struct list_head s_files;
@@ -1308,6 +1312,8 @@ struct super_operations {* of inode dirty data. Having a seperate lock for this * purpose reduces latency and prevents some filesystem- * specific deadlocks. +*I_WRITEBACK_NEVER For inodes that we may dirty data to but never +* want written back. * * Q: Why does I_DIRTY_DATASYNC exist? It appears as if it could be replaced * by (I_DIRTY_SYNC|I_DIRTY_PAGES).
@@ -1326,6 +1332,7 @@ struct super_operations {#define I_LOCK (1 << __I_LOCK)#define __I_SYNC 8#define I_SYNC (1 << __I_SYNC) +#define I_WRITEBACK_NEVER 512#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
include/linux/rbtree.h +3 -0
@@ -135,6 +135,9 @@ static inline void rb_set_color(struct r#define RB_EMPTY_ROOT (root) ((root)->rb_node == NULL)#define RB_EMPTY_NODE (node) (rb_parent(node) == node)#define RB_CLEAR_NODE (node) (rb_set_parent(node, node)) +#define RB_LINKED_NODE (node) ((node)->rb_parent_color || \ + (node)->rb_left || (node)->rb_right) +extern void rb_insert_color (struct rb_node *,struct rb_root *);extern void rb_erase (struct rb_node *,struct rb_root *);
include/linux/writeback.h +2 -1
@@ -30,7 +30,6 @@ static inline int task_is_pdflush(structenum writeback_sync_modes {WB_SYNC_NONE ,/* Don't wait on anything */ WB_SYNC_ALL ,/* Wait on every mapping */ -WB_SYNC_HOLD ,/* Hold the inode on sb_dirty for sys_sync() */ };/*
@@ -72,6 +71,8 @@ void writeback_inodes(struct writeback_cint inode_wait (void *);void sync_inodes_sb (struct super_block *,int wait);void sync_inodes (int wait); +void flush_tree_remove (struct super_block *sb,struct inode *inode); +/* writeback.h requires fs.h; it, too, is not included from here. */ static inline void wait_on_inode (struct inode *inode)
--
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>
Quoted 4 lines · Michael Rubin
From: Michael Rubin <[email protected]>
For those of you who have waited so long. This is the third submission of the first attempt at this patch. It is a trilogy.
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
--
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>
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
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>
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new list(s_more_io_wait).
Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But s_dirty would be enough for that. Plus, s_more_io provides fair queuing between small/large files, and s_more_io_wait provides waiting mechanism for blocked inodes.
The time ordered rbtree may delay io for a blocked inode simply by modifying its dirtied_when and reinsert it. But it would no longer be that easy if it is to be ordered by location.
If we are going to do location based ordering in the future, the lists will continue to be useful. It would simply be a matter of switching from the s_dirty(order by time) to some rbtree or radix tree(order by location).
We can even provide both ordering at the same time to different fs/inodes which is configurable by the user. Because the s_dirty and/or rbtree would provide _only_ ordering(not faireness or waiting) and hence is interchangeable.
This patchset could be a good reference. It does location based ordering with radix tree:
[RFC][PATCH] clustered writeback <http://lkml.org/lkml/2007/8/27/45>
Thank you,
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>
Andrew Morton
maintainerQuoted 15 lines · On Wed, 16 Jan 2008 11:01:08 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new
list(s_more_io_wait).
Quoted 8 lines
Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.The time ordered rbtree may delay io for a blocked inode simply by modifying its
dirtied_whenand reinsert it. But it would no longer be that easy if it is to be ordered by location.
What does the term "ordered by location" mean? Attemting to sort inodes by physical disk address? By using their i_ino as a key?
That sounds optimistic.
Quoted 10 lines
If we are going to do location based ordering in the future, the lists will continue to be useful. It would simply be a matter of switching from the
s_dirty(order by time)to some rbtree or radix tree(order by location).We can even provide both ordering at the same time to different fs/inodes which is configurable by the user. Because the
s_dirtyand/or rbtree would provide _only_ ordering(not faireness or waiting) and hence is interchangeable.
Quoted 4 lines
This patchset could be a good reference. It does location based ordering with radix tree:
[RFC][PATCH] clustered writeback <http://lkml.org/lkml/2007/8/27/45>
list_heads are just the wrong data structure for this function. Especially list_heads which are protected by a non-sleeping lock.
--
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>
Quoted 22 lines · Andrew Morton
Quoted 20 lines · On Wed, 16 Jan 2008 11:01:08 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new
list(s_more_io_wait).Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.
Quoted 8 lines
Quoted 3 lines
The time ordered rbtree may delay io for a blocked inode simply by modifying its
dirtied_whenand reinsert it. But it would no longer be that easy if it is to be ordered by location.What does the term "ordered by location" mean? Attemting to sort inodes by physical disk address? By using their
i_inoas a key?That sounds optimistic.
Yes, exactly. Think about email servers with lots of dirty files.
Quoted 10 lines
Quoted 10 lines
If we are going to do location based ordering in the future, the lists will continue to be useful. It would simply be a matter of switching from the
s_dirty(order by time)to some rbtree or radix tree(order by location).We can even provide both ordering at the same time to different fs/inodes which is configurable by the user. Because the
s_dirtyand/or rbtree would provide _only_ ordering(not faireness or waiting) and hence is interchangeable.
Quoted 7 lines
Quoted 4 lines
This patchset could be a good reference. It does location based ordering with radix tree:
[RFC][PATCH] clustered writeback <http://lkml.org/lkml/2007/8/27/45>
list_headsare just the wrong data structure for this function. Especiallylist_headswhich are protected by a non-sleeping lock.
list_heads are OK if we use them for one and only function. We have been trying to jam too much into s_dirty in the past. Grabbing a refcount could be better than locking - anyway if we split the functions today, it would be easy to replace the list_heads one by one in the future.
--
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>
Andrew Morton
maintainerQuoted 1 line · On Wed, 16 Jan 2008 12:25:53 +0800 Fengguang Wu <[email protected]> wrote:
list_headsare OK if we use them for one and only function.
Not really. They're inappropriate when you wish to remember your position in the list while you dropped the lock (as we must do in writeback).
A data structure which permits us to interate across the search key rather than across the actual storage locations is more appropriate.
--
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>
Quoted 10 lines · Andrew Morton
Quoted 1 line · On Wed, 16 Jan 2008 12:25:53 +0800 Fengguang Wu <[email protected]> wrote:
list_headsare OK if we use them for one and only function.Not really. They're inappropriate when you wish to remember your position in the list while you dropped the lock (as we must do in writeback).
A data structure which permits us to interate across the search key rather than across the actual storage locations is more appropriate.
I totally agree with you. What I mean is to first do the split of functions - into three: ordering, starvation prevention, and blockade waiting. Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough), and lastly get rid of the list_heads to avoid locking. Does it sound like a good path?
--
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>
Andrew Morton
maintainerQuoted 9 lines · On Wed, 16 Jan 2008 12:55:07 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 8 lines · Andrew Morton
Quoted 1 line · On Wed, 16 Jan 2008 12:25:53 +0800 Fengguang Wu <[email protected]> wrote:
list_headsare OK if we use them for one and only function.Not really. They're inappropriate when you wish to remember your position in the list while you dropped the lock (as we must do in writeback).
Quoted 6 lines
Quoted 2 lines
A data structure which permits us to interate across the search key rather than across the actual storage locations is more appropriate.
I totally agree with you. What I mean is to first do the split of functions - into three: ordering, starvation prevention, and blockade waiting.
Does "ordering" here refer to ordering bt time-of-first-dirty?
What is "blockade waiting"?
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Quoted 2 lines
and lastly get rid of the
list_headsto
avoid locking. Does it sound like a good path?
I'd have thaought that replacing list_heads with another data structure would be a simgle commit.
--
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>
Quoted 11 lines · Andrew Morton
Quoted 9 lines · On Wed, 16 Jan 2008 12:55:07 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 8 lines · Andrew Morton
Quoted 1 line · On Wed, 16 Jan 2008 12:25:53 +0800 Fengguang Wu <[email protected]> wrote:
list_headsare OK if we use them for one and only function.Not really. They're inappropriate when you wish to remember your position in the list while you dropped the lock (as we must do in writeback).
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
A data structure which permits us to interate across the search key rather than across the actual storage locations is more appropriate.
I totally agree with you. What I mean is to first do the split of functions - into three: ordering, starvation prevention, and blockade waiting.
Does "ordering" here refer to ordering bt time-of-first-dirty?
Ordering by dirtied_when or i_ino, either is OK.
Quoted 1 line
What is "blockade waiting"?
Some inodes/pages cannot be synced now for some reason and should be retried after a while.
Quoted 4 lines
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Switch from time to location.
Quoted 5 lines
Quoted 2 lines
and lastly get rid of the
list_headsto
avoid locking. Does it sound like a good path?I'd have thaought that replacing
list_headswith another data structure would be a simgle commit.
That would be easy. s_more_io and s_more_io_wait can all be converted to radix trees.
--
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>
Quoted 22 lines · Fengguang Wu
Quoted 10 lines · Andrew Morton
Quoted 8 lines · On Wed, 16 Jan 2008 12:55:07 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Wed, 16 Jan 2008 12:25:53 +0800 Fengguang Wu <[email protected]> wrote:
list_headsare OK if we use them for one and only function.Not really. They're inappropriate when you wish to remember your position in the list while you dropped the lock (as we must do in writeback).
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines
A data structure which permits us to interate across the search key rather than across the actual storage locations is more appropriate.
I totally agree with you. What I mean is to first do the split of functions - into three: ordering, starvation prevention, and blockade waiting.
Does "ordering" here refer to ordering bt time-of-first-dirty?
Ordering by
dirtied_whenori_ino, either is OK.Quoted 1 line
What is "blockade waiting"?
Quoted 9 lines
Some inodes/pages cannot be synced now for some reason and should be retried after a while.
Quoted 3 lines
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Switch from time to location.
Given the way LBAs are located on disk and the fact that rotational latency is a large factor in changing locations of a drive head, any attempts to do a C-SCAN pass are pretty much useless. Further complicating this is any volume management that sits between the fs and the actual storage.
A nice feature to have longer term is to have the write_inodes paths for background flushing understand storage congestion _through_ any volume management. This would allow us to back off background flushing on a per spindle basis (when using drives of course) and avoid write congestion in both the io scheduler and in the drive's writecaches, which I believe, but don't have hard evidence, get congested today, knocking the drive into a fifo fashion in firmware.
A data structure that allows us to keep a dirtied_when values consistent across back-offs and blocking allows us to further develop the background writeout paths to get to this point (though exposing this congestion information will require more work deeper in the stack).
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
and lastly get rid of the
list_headsto
avoid locking. Does it sound like a good path?I'd have thaought that replacing
list_headswith another data structure would be a simgle commit.
Quoted 9 lines
That would be easy.
s_more_ioands_more_io_waitcan all be converted to radix trees.--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · Fengguang Wu
Quoted 4 lines · Andrew Morton
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Switch from time to location.
Note that data writeback may be adversely affected by location based writeback rather than time based writeback - think of the effect of location based data writeback on an app that creates lots of short term (<30s) temp files and then removes them before they are written back.
Also, data writeback locatio cannot be easily derived from the inode number in pretty much all cases. "near" in terms of XFS means the same AG which means the data could be up to a TB away from the inode, and if you have >1TB filesystems usingthe default inode32 allocator, file data is *never* placed near the inode - the inodes are in the first TB of the filesystem, the data is rotored around the rest of the filesystem.
And with delayed allocation, you don't know where the data is even going to be written ahead of the filesystem ->writepage call, so you can't do optimal location ordering for data in this case.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
and lastly get rid of the
list_headsto
avoid locking. Does it sound like a good path?I'd have thaought that replacing
list_headswith another data structure would be a simgle commit.That would be easy.
s_more_ioands_more_io_waitcan all be converted to radix trees.
Makes sense for location based writeback of the inodes themselves, but not for data.
Hmmmm - I'm wondering if we'd do better to split data writeback from inode writeback. i.e. we do two passes. The first pass writes all the data back in time order, the second pass writes all the inodes back in location order.
Right now we interleave data and inode writeback, (i.e. we do data, inode, data, inode, data, inode, ....). I'd much prefer to see all data written out first, then the inodes. ->writepage often dirties the inode and hence if we need to do multiple do_writepages() calls on an inode to flush all the data (e.g. congestion, large amounts of data to be written, etc), we really shouldn't be calling write_inode() after every do_writepages() call. The inode should not be written until all the data is written....
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>
Quoted 7 lines · David Chinner
Quoted 6 lines · Fengguang Wu
Quoted 4 lines · Andrew Morton
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Quoted 7 lines
Quoted 1 line
Switch from time to location.
Note that data writeback may be adversely affected by location based writeback rather than time based writeback - think of the effect of location based data writeback on an app that creates lots of short term (<30s) temp files and then removes them before they are written back.
A small(e.g. 5s) time window can still be enforced, but...
Quoted 9 lines
Also, data writeback locatio cannot be easily derived from the inode number in pretty much all cases. "near" in terms of XFS means the same AG which means the data could be up to a TB away from the inode, and if you have >1TB filesystems usingthe default inode32 allocator, file data is *never* placed near the inode - the inodes are in the first TB of the filesystem, the data is rotored around the rest of the filesystem.
Quoted 3 lines
And with delayed allocation, you don't know where the data is even going to be written ahead of the filesystem ->writepage call, so you can't do optimal location ordering for data in this case.
Agreed.
Quoted 5 lines
Hmmmm - I'm wondering if we'd do better to split data writeback from inode writeback. i.e. we do two passes. The first pass writes all the data back in time order, the second pass writes all the inodes back in location order.
Quoted 8 lines
Right now we interleave data and inode writeback, (i.e. we do data, inode, data, inode, data, inode, ....). I'd much prefer to see all data written out first, then the inodes. ->writepage often dirties the inode and hence if we need to do multiple
do_writepages()calls on an inode to flush all the data (e.g. congestion, large amounts of data to be written, etc), we really shouldn't be callingwrite_inode()after everydo_writepages()call. The inode should not be written until all the data is written....
That may do good to XFS. Another case is documented as follows:
"the write_inode() function of a typical fs will perform no I/O, but will mark buffers in the blockdev mapping as dirty."
--
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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 10 lines · Fengguang Wu
Quoted 9 lines · David Chinner
Quoted 7 lines · Fengguang Wu
Quoted 4 lines · Andrew Morton
Quoted 2 lines
Then to do better ordering by adopting radix tree(or rbtree if radix tree is not enough),
ordering of what?
Switch from time to location.
Quoted 7 lines
Quoted 5 lines
Note that data writeback may be adversely affected by location based writeback rather than time based writeback - think of the effect of location based data writeback on an app that creates lots of short term (<30s) temp files and then removes them before they are written back.
A small(e.g. 5s) time window can still be enforced, but...
Yes, you could, but that will then result in non-deterministic performance for repeated workloads because the order of file writeback will not be consistent.
e.g. the first run is fast because the output file is at lower offset than the temp file meaning the temp file gets deleted without being written.
The second run is slow because the location of the files is reversed and the temp file is written to disk before the final output file and hence the run is much slower because it writes much more.
The third run is also slow, but the files are like the first fast run. However, pdflush tries to write the temp file back within 5s of it being dirtied so it skips it and writes the output file first.
The difference between the first+second case can be found by knowing that inode number determines writeback order, but there is no obvious clue as to why the first+third runs are different.
This is exactly the sort of non-deterministic behaviour we want to avoid in a writeback algorithm.
Quoted 14 lines
Quoted 5 lines
Hmmmm - I'm wondering if we'd do better to split data writeback from inode writeback. i.e. we do two passes. The first pass writes all the data back in time order, the second pass writes all the inodes back in location order.
Quoted 8 lines
Right now we interleave data and inode writeback, (i.e. we do data, inode, data, inode, data, inode, ....). I'd much prefer to see all data written out first, then the inodes. ->writepage often dirties the inode and hence if we need to do multiple
do_writepages()calls on an inode to flush all the data (e.g. congestion, large amounts of data to be written, etc), we really shouldn't be callingwrite_inode()after everydo_writepages()call. The inode should not be written until all the data is written....
Quoted 3 lines
That may do good to XFS. Another case is documented as follows:
"thewrite_inode()function of a typical fs will perform no I/O, but will mark buffers in the blockdev mapping as dirty."
Yup, but in that situation ->write_inode() does not do any I/O, so it will work with any high level inode writeback ordering or timing scheme equally well. As a result, that's not the case we need to optimise at all.
FWIW, the NFS client is likely to work better with split data/ inode writeback as it also has to mark the inode dirty on async write completion (to get ->write_inode called to issue a commit RPC). Hence delaying the inode write until after all the data is written makes sense there as well....
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>
Quoted 22 lines · Andrew Morton
Quoted 20 lines · On Wed, 16 Jan 2008 11:01:08 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new
list(s_more_io_wait).Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.
Quoted 8 lines
Quoted 3 lines
The time ordered rbtree may delay io for a blocked inode simply by modifying its
dirtied_whenand reinsert it. But it would no longer be that easy if it is to be ordered by location.What does the term "ordered by location" mean? Attemting to sort inodes by physical disk address? By using their
i_inoas a key?That sounds optimistic.
In XFS, inode number is an encoding of it's location on disk, so ordering inode writeback by inode number *does* make sense.
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>
Andrew Morton
maintainerQuoted 27 lines · On Wed, 16 Jan 2008 18:55:38 +1100 David Chinner <[email protected]> wrote:
Quoted 26 lines · Andrew Morton
Quoted 23 lines · On Wed, 16 Jan 2008 11:01:08 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new
list(s_more_io_wait).Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.The time ordered rbtree may delay io for a blocked inode simply by modifying its
dirtied_whenand reinsert it. But it would no longer be that easy if it is to be ordered by location.
Quoted 7 lines
Quoted 4 lines
What does the term "ordered by location" mean? Attemting to sort inodes by physical disk address? By using their
i_inoas a key?That sounds optimistic.
In XFS, inode number is an encoding of it's location on disk, so ordering inode writeback by inode number *does* make sense.
This code is mainly concerned with writing pagecache data, not inodes.
--
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>
Quoted 32 lines · Andrew Morton
Quoted 30 lines · On Wed, 16 Jan 2008 18:55:38 +1100 David Chinner <[email protected]> wrote:
Quoted 29 lines · Andrew Morton
Quoted 15 lines · On Wed, 16 Jan 2008 11:01:08 +0800 Fengguang Wu <[email protected]> wrote:
Quoted 9 lines · Michael Rubin
Quoted 2 lines · Peter Zijlstra
Just a quick question, how does this interact/depend-uppon etc.. with Fengguangs patches I still have in my mailbox? (Those from Dec 28th)
They don't. They apply to a 2.6.24rc7 tree. This is a candidte for 2.6.25.
This work was done before Fengguang's patches. I am trying to test Fengguang's for comparison but am having problems with getting mm1 to boot on my systems.
Yeah, they are independent ones. The initial motivation is to fix the bug "sluggish writeback on small+large files". Michael introduced a new rbtree, and me introduced a new
list(s_more_io_wait).Quoted 8 lines
Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.The time ordered rbtree may delay io for a blocked inode simply by modifying its
dirtied_whenand reinsert it. But it would no longer be that easy if it is to be ordered by location.What does the term "ordered by location" mean? Attemting to sort inodes by physical disk address? By using their
i_inoas a key?
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
That sounds optimistic.
In XFS, inode number is an encoding of it's location on disk, so ordering inode writeback by inode number *does* make sense.
This code is mainly concerned with writing pagecache data, not inodes.
Now I tend to agree with you. It is not easy to sort writeback pages by disk location. There are three main obstacles:
- there can be multiple filesystems on the same disk
- ext3/reiserfs/... make use of blockdev inode, which spans the whole partition;
- xfs may store inode metadata/data separately;
--
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>
Quoted 4 lines · Fengguang Wu
Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.
I think the flush_tree (which is a little more than just an rbtree) provides the same queuing mechanisms that the three or four lists heads do and manages to do it in one structure. The i_flushed_when provides the ability to have blocked inodes wait their turn so to speak.
Another motivation behind the rbtree patch is to unify the data structure that handles the priority and mechanism of how we write out the pages of the inodes. There are some ideas about introducing priority schemes for QOS and such in the future. I am not saying this patch is about making that happen, but the idea is to if possible unify the four stages of lists into a single structure to facilitate efforts like that.
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>
Quoted 12 lines · Michael Rubin
Quoted 4 lines · Fengguang Wu
Basically I think rbtree is an overkill to do time based ordering. Sorry, Michael. But
s_dirtywould be enough for that. Plus,s_more_ioprovides fair queuing between small/large files, ands_more_io_waitprovides waiting mechanism for blocked inodes.I think the
flush_tree(which is a little more than just an rbtree) provides the same queuing mechanisms that the three or four lists heads do and manages to do it in one structure. Thei_flushed_whenprovides the ability to have blocked inodes wait their turn so to speak.
Quoted 7 lines
Another motivation behind the rbtree patch is to unify the data structure that handles the priority and mechanism of how we write out the pages of the inodes. There are some ideas about introducing priority schemes for QOS and such in the future. I am not saying this patch is about making that happen, but the idea is to if possible unify the four stages of lists into a single structure to facilitate efforts like that.
Yeah, rbtree is better than list_heads after all. Let's make it happen.
--
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>
Quoted 5 lines · Michael Rubin
1) Adding a datastructure to guarantee fairness when writing inodes to disk and simplify the code base.
When inodes are parked for writeback they are parked in the
flush_tree. The flush tree is a data structure based on an rb tree.
The main benefit of rbtree is possibly better support of future policies. Can you demonstrate an example?
(grumble:
Apart from the benefit of flexibility, I don't think it makes things simpler, nor does the introduction of rbtree automatically fixes bugs. Bugs can only be avoided by good understanding of all possible cases.)
The most tricky writeback issues could be starvation prevention between
- small/large files
- new/old files
- superblocks
Some kind of limit should be applied for each. They used to be:
- requeue to s_more_io whenever MAX_WRITEBACK_PAGES is reached this preempts big files
- refill s_io iif it is drained
this prevents promotion of big/old files
- return from sync_sb_inodes() after one go of s_io
(todo: don't restart from the first superblock in writeback_inodes()) this prevents busy superblock from starving others
and ensures fairness between superblocks
Michael, could you sort out and document the new starvation prevention schemes?
Quoted 11 lines
Duplicate keys are handled by making a list in the tree for each key value. The order of how we choose the next inode to flush is decided by two fields. First the earliest
dirtied_whenvalue. If there are duplicatedirtied_whenvalues then the earliesti_flush_genvalue determines who gets flushed next.The flush tree organizes the
dirtied_whenkeys with therb_tree. Any inodes with a duplicatedirtied_whenvalue are link listed together. This link list is sorted by the inode'si_flush_gen. When both thedirtied_whenand thei_flush_genare identical the order in the linked list determines the order we flush the inodes.
Introduce i_flush_gen to help restarting from the last inode? Well, it's not as simple as list_heads.
Quoted 5 lines
2) Added an inode flag to allow inodes to be marked so that they are never written back to disk.
The motivation behind this change is several fold. The first is to insure fairness in the writeback algorithm. The second is to
What do you mean by fairness? Why cannot I_WRITEBACK_NEVER be in a decoupled standalone patch?
Quoted 8 lines
deal with a bug where the writing to large files concurrently to smaller ones creates a situation where writeback cannot keep up with traffic and memory baloons until the we hit the threshold watermark. This can result in surprising long latency with respect to disk traffic. This latency can take minutes. The
flush tree fixes this issue and fixes several other minor issues with fairness also.
More details about the fixings, please?
--
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>
Quoted 3 lines · Fengguang Wu
On Tue, Jan 15, 2008 at 12:09:21AM -0800, Michael Rubin wrote:
The main benefit of rbtree is possibly better support of future policies. Can you demonstrate an example?
These are ill-formed thoughts as of now on my end but the idea was that keeping one tree sorted via a scheme might be simpler than multiple list_heads.
Quoted 1 line
Bugs can only be avoided by good understanding of all possible cases.)
I take the above statement as a tautology. And am trying my best to do so. :-)
Quoted 7 lines
The most tricky writeback issues could be starvation prevention between
- small/large files
- new/old files
- superblocks
So I have written tests and believe I have covered these issues. If you are concerned in specific on any and have a test case please let me know.
Quoted 3 lines
Some kind of limit should be applied for each. They used to be:
- requeue tos_more_iowheneverMAX_WRITEBACK_PAGESis reached this preempts big files
The patch uses th same limit.
Quoted 2 lines
- refill
s_ioiif it is drained this prevents promotion of big/old files
Once a big file gets its first do_writepages it is moved behind the other smaller files via i_flushed_when. And the same in reverse for big vs old.
Quoted 1 line
- return from
sync_sb_inodes()after one go ofs_io
I am not sure how this limit helps things out. Is this for superblock starvation? Can you elaborate?
Quoted 1 line
Michael, could you sort out and document the new starvation prevention schemes?
The basic idea behind the writeback algorithm to handle starvation. The over arching idea is that we want to preserve order of writeback based on when an inode was dirtied and also preserve the dirtied_when contents until the inode has been written back (partially or fully)
Every sync_sb_inodes we find the least recent inodes dirtied. To deal with large or small starvation we have a s_flush_gen for each iteration of sync_sb_inodes every time we issue a writeback we mark that the inode cannot be processed until the next s_flush_gen. This way we don't process one get to the rest since we keep pushing them into subsequent s_fush_gen's.
Let me know if you want more detail or structured responses.
Quoted 10 lines
Introduce
i_flush_gento help restarting from the last inode? Well, it's not as simple aslist_heads.Quoted 5 lines
2) Added an inode flag to allow inodes to be marked so that they are never written back to disk.
The motivation behind this change is several fold. The first is to insure fairness in the writeback algorithm. The second is to
What do you mean by fairness?
So originally this comment was written when I was trying to fix a bug in 2.6.23. The one where we were starving large files from being flushed. There was a fairness issue where small files were being flushed but the large ones were just ballooning in memory.
Quoted 1 line
Why cannot
I_WRITEBACK_NEVERbe in a decoupled standalone patch?
The WRITEBACK_NEVER could be in a previous patch to the rbtree. But not a subsequent patch to the rbtree. The rbtree depends on the WRITEBACK_NEVER patch otherwise we run in to problems in generic_delete_inode. Now that you point it out I think I can split this patch into two patches and make the WRITEBACK_NEVER in the first one.
Quoted 1 line
More details about the fixings, please?
So again this comment was written against 2.6.23. The biggest fix is the starving of big files. I remember there were other smaller issues, but there have been so many changes in the patch sets that I need to go back to quantify.
--
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>
Quoted 8 lines · Michael Rubin
Quoted 3 lines · Fengguang Wu
On Tue, Jan 15, 2008 at 12:09:21AM -0800, Michael Rubin wrote:
The main benefit of rbtree is possibly better support of future policies. Can you demonstrate an example?These are ill-formed thoughts as of now on my end but the idea was that keeping one tree sorted via a scheme might be simpler than multiple
list_heads.
Suppose we want to grant longer expiration window for temp files, adding a new list named s_dirty_tmpfile would be a handy solution.
So the question is: should we need more than 3 QoS classes?
Quoted 11 lines
Quoted 7 lines
The most tricky writeback issues could be starvation prevention between
- small/large files
- new/old files
- superblocksSo I have written tests and believe I have covered these issues. If you are concerned in specific on any and have a test case please let me know.
OK.
Quoted 4 lines
Quoted 3 lines
Some kind of limit should be applied for each. They used to be:
- requeue tos_more_iowheneverMAX_WRITEBACK_PAGESis reached this preempts big files
Quoted 8 lines
The patch uses th same limit.
Quoted 2 lines
- refill
s_ioiif it is drained this prevents promotion of big/old filesOnce a big file gets its first
do_writepagesit is moved behind the other smaller files viai_flushed_when. And the same in reverse for big vs old.
You mean i_flush_gen? No, sync_sb_inodes() will abort on every MAX_WRITEBACK_PAGES, and s_flush_gen will be updated accordingly. Hence the sync will restart from big/old files.
Quoted 5 lines
Quoted 2 lines
- return from
sync_sb_inodes()after one go ofs_ioI am not sure how this limit helps things out. Is this for superblock starvation? Can you elaborate?
We should have a way to go to next superblock even if new dirty inodes or pages are emerging fast in this superblock. Fill and drain s_io only once and then abort helps.
s_io is a stable and bounded working set in one go of superblock.
Quoted 7 lines
Quoted 1 line
Michael, could you sort out and document the new starvation prevention schemes?
The basic idea behind the writeback algorithm to handle starvation. The over arching idea is that we want to preserve order of writeback based on when an inode was dirtied and also preserve the
dirtied_whencontents until the inode has been written back (partially or fully)
Quoted 11 lines
Every
sync_sb_inodeswe find the least recent inodes dirtied. To deal with large or small starvation we have as_flush_genfor each iteration ofsync_sb_inodesevery time we issue a writeback we mark that the inode cannot be processed until the nexts_flush_gen. This way we don't process one get to the rest since we keep pushing them into subsequent s_fush_gen's.Let me know if you want more detail or structured responses.
Quoted 2 lines
Introduce
i_flush_gento help restarting from the last inode? Well, it's not as simple aslist_heads.
Basically you make one list_head in each rbtree node.
That list_head is recycled cyclic, and is an analog to the old fashioned s_dirty. We need to know 'where we are' and 'where it ends'. So an extra indicator must be introduced - i_flush_gen. It's awkward.
We are simply repeating the aged list_heads' problem.
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
2) Added an inode flag to allow inodes to be marked so that they are never written back to disk.
The motivation behind this change is several fold. The first is to insure fairness in the writeback algorithm. The second is to
Quoted 6 lines
Quoted 1 line
What do you mean by fairness?
So originally this comment was written when I was trying to fix a bug in 2.6.23. The one where we were starving large files from being flushed. There was a fairness issue where small files were being flushed but the large ones were just ballooning in memory.
In fact the bug is turned-around rather than fixed - now the small files could be starved.
Quoted 8 lines
Quoted 1 line
Why cannot
I_WRITEBACK_NEVERbe in a decoupled standalone patch?The
WRITEBACK_NEVERcould be in a previous patch to the rbtree. But not a subsequent patch to the rbtree. The rbtree depends on theWRITEBACK_NEVERpatch otherwise we run in to problems ingeneric_delete_inode. Now that you point it out I think I can split this patch into two patches and make theWRITEBACK_NEVERin the first one.
OK.
--
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>
Quoted 3 lines · Fengguang Wu
Suppose we want to grant longer expiration window for temp files, adding a new list named
s_dirty_tmpfilewould be a handy solution.
How would the kernel know that a file is a tmp file?
Quoted 1 line
So the question is: should we need more than 3 QoS classes?
[just a random idea; i have not worked out all the implications]
Would it be possible to derive a writeback apriority from the ionice level of the process originating the IO? e.g. we have long standing problems that background jobs even when niced and can cause significant slow downs to foreground processes by starving IO and pushing out pages. ionice was supposed to help with that but in practice it does not seem to have helped too much and I suspect it needs more prioritization higher up the VM food chain. Adding such priorities to writeback would seem like a step in the right direction, although it would of course not solve the problem completely.
-Andi
--
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>
Quoted 6 lines · Andi Kleen
Quoted 3 lines · Fengguang Wu
Suppose we want to grant longer expiration window for temp files, adding a new list named
s_dirty_tmpfilewould be a handy solution.How would the kernel know that a file is a tmp file?
No idea - but it makes a good example ;-)
But for those making different filesystems for /tmp, /var, /data etc, per-superblock expiration parameters may help.
Quoted 4 lines
Quoted 1 line
So the question is: should we need more than 3 QoS classes?
[just a random idea; i have not worked out all the implications]
Quoted 10 lines
Would it be possible to derive a writeback apriority from the ionice level of the process originating the IO? e.g. we have long standing problems that background jobs even when niced and can cause significant slow downs to foreground processes by starving IO and pushing out pages. ionice was supposed to help with that but in practice it does not seem to have helped too much and I suspect it needs more prioritization higher up the VM food chain. Adding such priorities to writeback would seem like a step in the right direction, although it would of course not solve the problem completely.
Good idea. Michael may well be considering similar interfaces :-)
--
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>
We have some code internally that does just this, though it slightly abuses struct page by tagging pages with the highest priority that dirties them.
I'm not sure what a better solution is, though there has been talk about rewritting it to use a per mapping radix tree to keep mem_map small.
The idea is to mark current->ioprio into each page as they are dirtied, higher priority overrides lower priority. Buffer_heads are done in the same way.
Come IO submission, bio's get the highest IO priority associated with the submitted pages/buffer_heads and these are passed into the the struct request's into the scheduler.
Similar changes are underway for making sure all AIO get the right ioprios.
It will take some cleaning to get it ready for lkml submission, though I'm still a bit unsure of what we should do to avoid struct page growth.
Mike Waychison
Quoted 20 lines · Andi Kleen
Quoted 2 lines · Fengguang Wu
Suppose we want to grant longer expiration window for temp files, adding a new list named
s_dirty_tmpfilewould be a handy solution.How would the kernel know that a file is a tmp file?
Quoted 1 line
So the question is: should we need more than 3 QoS classes?
[just a random idea; i have not worked out all the implications]
Would it be possible to derive a writeback apriority from the ionice
level of the process originating the IO? e.g. we have long standing
problems that background jobs even when niced and can cause
significant slow downs to foreground processes by starving IO and pushing out pages. ionice was supposed to help with that but in practice it does not seem to have helped too much and I suspect
it needs more prioritization higher up the VM food chain. Adding
such priorities to writeback would seem like a step in the right
direction, although it would of course not solve the problem
completely.
Quoted 7 lines
-Andi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
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>
On Jan 17, 2008 8:56 PM, Fengguang Wu <[email protected]> wrote:
Once again thanks for the speedy replies. :-)
Quoted 3 lines · Michael Rubin
Suppose we want to grant longer expiration window for temp files, adding a new list named
s_dirty_tmpfilewould be a handy solution.
When you mean tmp do you mean files that eventually get written to disk? If not I would just use the WRITEBACK_NEVER. If so I am not sure if that feature is worth making a special case. It seems like the location based ideas may be more useful.
Quoted 22 lines
So the question is: should we need more than 3 QoS classes?
Quoted 11 lines
Quoted 7 lines
The most tricky writeback issues could be starvation prevention between
- small/large files
- new/old files
- superblocksSo I have written tests and believe I have covered these issues. If you are concerned in specific on any and have a test case please let me know.
OK.
Quoted 6 lines
Quoted 3 lines
Some kind of limit should be applied for each. They used to be:
- requeue tos_more_iowheneverMAX_WRITEBACK_PAGESis reached this preempts big filesThe patch uses th same limit.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
- refill
s_ioiif it is drained this prevents promotion of big/old filesOnce a big file gets its first
do_writepagesit is moved behind the other smaller files viai_flushed_when. And the same in reverse for big vs old.You mean
i_flush_gen?
Yeah sorry. It was once called i_flush_when. (sheepish)
Quoted 3 lines
No,
sync_sb_inodes()will abort on everyMAX_WRITEBACK_PAGES, ands_flush_genwill be updated accordingly. Hence the sync will restart from big/old files.
If I understand you correctly I am not sure I agree. Here is what I think happens in the patch:
1) pull big inode off of flush tree
2) sync big inode
3) Hit MAX_WRITEBACK_PAGES
4) Re-insert big inode (without modifying the dirtied_when)
5) update the i_flush_gen on big inode and re-insert behind small inodes we have not synced yet.
In a subsequent sync_sb_inode we end up retrieving the small inode we had not serviced yet.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
- return from
sync_sb_inodes()after one go ofs_ioI am not sure how this limit helps things out. Is this for superblock starvation? Can you elaborate?
We should have a way to go to next superblock even if new dirty inodes or pages are emerging fast in this superblock. Fill and drain
s_ioonly once and then abort helps.
Got it.
Quoted 1 line
s_iois a stable and bounded working set in one go of superblock.
Is this necessary with MAX_WRITEBACK_PAGES? It feels like a double limit.
Quoted 5 lines
Basically you make one
list_headin each rbtree node.
Thatlist_headis recycled cyclic, and is an analog to the old fashioneds_dirty. We need to know 'where we are' and 'where it ends'. So an extra indicator must be introduced -i_flush_gen. It's awkward. We are simply repeating the agedlist_heads' problem.
To me they both feel a little awkward. I feel like the original problem in 2.6.23 led to a lot of examination which is bringing new possibilities to light.
BTW the issue that started me on this whole path (starving large files) was still present in 2.6.23-rc8 but now looks fixed in 2.6.24-rc3.
Still no idea about your changes in 2.6.24-rc6-mm1. I have given up trying to get that thing to boot.
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>
Quoted 6 lines · Michael Rubin
Quoted 3 lines · Fengguang Wu
On Thu, Jan 17, 2008 at 01:07:05PM -0800, Michael Rubin wrote:
Suppose we want to grant longer expiration window for temp files, adding a new list nameds_dirty_tmpfilewould be a handy solution.When you mean tmp do you mean files that eventually get written to
Yes, they are disk based and can be synced on.
Quoted 3 lines
disk? If not I would just use the
WRITEBACK_NEVER. If so I am not sure if that feature is worth making a special case. It seems like the location based ideas may be more useful.
I'm not interested in WRITEBACK_NEVER or location based writeback for now :-)
Quoted 25 lines
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
- refill
s_ioiif it is drained this prevents promotion of big/old filesOnce a big file gets its first
do_writepagesit is moved behind the other smaller files viai_flushed_when. And the same in reverse for big vs old.You mean
i_flush_gen?Yeah sorry. It was once called
i_flush_when. (sheepish)Quoted 3 lines
No,
sync_sb_inodes()will abort on everyMAX_WRITEBACK_PAGES, ands_flush_genwill be updated accordingly. Hence the sync will restart from big/old files.If I understand you correctly I am not sure I agree. Here is what I think happens in the patch:
1) pull big inode off of flush tree
2) sync big inode
3) HitMAX_WRITEBACK_PAGES
4) Re-insert big inode (without modifying thedirtied_when)
5) update thei_flush_genon big inode and re-insert behind small inodes we have not synced yet.
Quoted 2 lines
In a subsequent
sync_sb_inodewe end up retrieving the small inode we had not serviced yet.
Yes, exactly. And then it will continue to sync the big one again. It will never be able to move forward to the next dirtied_when before exhausting the inodes in the current list(with the oldest dirtied_when).
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
- return from
sync_sb_inodes()after one go ofs_ioI am not sure how this limit helps things out. Is this for superblock starvation? Can you elaborate?
We should have a way to go to next superblock even if new dirty inodes or pages are emerging fast in this superblock. Fill and drain
s_ioonly once and then abort helps.
Quoted 5 lines
Got it.
Quoted 1 line
s_iois a stable and bounded working set in one go of superblock.Is this necessary with
MAX_WRITEBACK_PAGES? It feels like a double limit.
We need a limit and continuing scheme at each level. It was so hard to sort them out, that I'm really reluctant to restart all the fuss again.
Quoted 10 lines
Quoted 5 lines
Basically you make one
list_headin each rbtree node.
Thatlist_headis recycled cyclic, and is an analog to the old fashioneds_dirty. We need to know 'where we are' and 'where it ends'. So an extra indicator must be introduced -i_flush_gen. It's awkward. We are simply repeating the agedlist_heads' problem.To me they both feel a little awkward. I feel like the original problem in 2.6.23 led to a lot of examination which is bringing new possibilities to light.
Quoted 5 lines
BTW the issue that started me on this whole path (starving large files) was still present in 2.6.23-rc8 but now looks fixed in 2.6.24-rc3.
Still no idea about your changes in 2.6.24-rc6-mm1. I have given up trying to get that thing to boot.
Hehe, I guess the bug is still there in 2.6.24-rc3. But should be gone in the latest patchset.
--
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>
Quoted 7 lines · Michael Rubin
Quoted 1 line
Michael, could you sort out and document the new starvation prevention schemes?
The basic idea behind the writeback algorithm to handle starvation. The over arching idea is that we want to preserve order of writeback based on when an inode was dirtied and also preserve the
dirtied_whencontents until the inode has been written back (partially or fully)
Quoted 6 lines
Every
sync_sb_inodeswe find the least recent inodes dirtied. To deal with large or small starvation we have as_flush_genfor each iteration ofsync_sb_inodesevery time we issue a writeback we mark that the inode cannot be processed until the nexts_flush_gen. This way we don't process one get to the rest since we keep pushing them into subsequent s_fush_gen's.
This seems suboptimal for large files. If you keep feeding in new least recently dirtied files, the large files will never get an unimpeded go at the disk and hence we'll struggle to get decent bandwidth under anything but pure large file write loads.
Fairness is a tradeoff between seeks and bandwidth. Ideally, we want to spend 50% of the *disk* time servicing sequential writes and 50% of the time servicing seeky writes - that way neither get penalised unfairly by the other type of workload.
Switching inodes during writeback implies a seek to the new write location, while continuing to write the same inode has no seek penalty because the writeback is sequential. It follows from this that allowing larges file a disproportionate amount of data writeback is desirable.
Also, cycling rapidly through all the large files to write 4MB to each is going to cause us to spend time seeking rather than writing compared to cycling slower and writing 40MB from each large file at a time.
i.e. servicing one large file for 100ms is going to result in higher writeback throughput than servicing 10 large files for 10ms each because there's going to be less seeking and more writing done by the disks.
That is, think of large file writes like process scheduler batch jobs - bulk throughput is what matters, so the larger the time slice you give them the higher the throughput.
IMO, the sort of result we should be looking at is a writeback design that results in cycling somewhat like:
slice 1: iterate over small files
slice 2: flush large file 1
slice 3: iterate over small files
slice 4: flush large file 2
......
slice n-1: flush large file N
slice n: iterate over small files
slice n+1: flush large file N+1
So that we keep the disk busy with a relatively fair mix of small and large I/Os while both are necessary.
Furthermore, as disk bandwidth goes up, the relationship between large file and small file writes changes if we want to maintain writeback at a significant percentage of the maximum bandwidth of the drive (which is extremely desirable). So if we take a 4k page machine and a 1024page writeback slice, for different disks, we get a bandwidth slice in terms of disk seeks like:
slow disk: 20MB/s, 10ms seek (say a laptop drive)
- 4MB write takes 200ms, or equivalent of 10 seeks
normal disk: 60MB/s, 8ms seek (desktop)
- 4MB write takes 66ms, or equivalent of 8 seeks
fast disk: 120MB/s, 5ms seek (15krpm SAS)
- 4MB write takes 33ms, or equivalent of 6 seeks
small RAID5 lun: 200MB/s, 4ms seek
- 4MB write takes 20ms, or equivalent of 5 seeks
Large RAID5 lun: 1GB/s, 2ms seek
- 4MB write takes 4ms, or equivalent of 2 seeks
Put simply:
The higher the bandwidth of the device, the more frequently we need to be servicing the inodes with large amounts of dirty data to be written to maintain write throughput at a significant percentage of the device capability.
The writeback algorithm needs to take this into account for it to be able to scale effectively for high throughput devices.
BTW, it needs to be recognised that if we are under memory pressure we can clean much more memory in a short period of time by writing out all the large files first. This would clearly benefit the system as a whole as we'd get the most pages available for reclaim as possible in a short a time as possible. The writeback algorithm should really have a mode that allows this sort of flush ordering to occur....
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>
On Jan 17, 2008 9:01 PM, David Chinner <[email protected]> wrote:
First off thank you for the very detailed reply. This rocks and gives me much to think about.
Quoted 6 lines · Michael Rubin
This seems suboptimal for large files. If you keep feeding in new least recently dirtied files, the large files will never get an unimpeded go at the disk and hence we'll struggle to get decent bandwidth under anything but pure large file write loads.
You're right. I understand now. I just changed a dial on my tests, ran it and found pdflush not keeping up like it should. I need to address this.
Quoted 31 lines
Switching inodes during writeback implies a seek to the new write location, while continuing to write the same inode has no seek penalty because the writeback is sequential. It follows from this that allowing larges file a disproportionate amount of data writeback is desirable.
Also, cycling rapidly through all the large files to write 4MB to each is going to cause us to spend time seeking rather than writing compared to cycling slower and writing 40MB from each large file at a time.
i.e. servicing one large file for 100ms is going to result in higher writeback throughput than servicing 10 large files for 10ms each because there's going to be less seeking and more writing done by the disks.
That is, think of large file writes like process scheduler batch jobs - bulk throughput is what matters, so the larger the time slice you give them the higher the throughput.
IMO, the sort of result we should be looking at is a writeback design that results in cycling somewhat like:
slice 1: iterate over small files
slice 2: flush large file 1
slice 3: iterate over small files
slice 4: flush large file 2
......
slice n-1: flush large file N
slice n: iterate over small files
slice n+1: flush large file N+1
Quoted 2 lines
So that we keep the disk busy with a relatively fair mix of small and large I/Os while both are necessary.
I am getting where you are coming from. But if we are going to make changes to optimize for seeks maybe we need to be more aggressive in write back in how we organize both time and location. Right now AFAIK there is no attention to location in the writeback path.
Quoted 5 lines
The higher the bandwidth of the device, the more frequently we need to be servicing the inodes with large amounts of dirty data to be written to maintain write throughput at a significant percentage of the device capability.
Could you expand that to say it's not the inodes of large files but the ones with data that we can exploit locality? Often large files are fragmented. Would it make more sense to pursue cracking the inodes and grouping their blocks's locations? Or is this all overkill and should be handled at a lower level like the elevator?
Quoted 7 lines
BTW, it needs to be recognised that if we are under memory pressure we can clean much more memory in a short period of time by writing out all the large files first. This would clearly benefit the system as a whole as we'd get the most pages available for reclaim as possible in a short a time as possible. The writeback algorithm should really have a mode that allows this sort of flush ordering to occur....
I completely agree.
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>
Quoted 47 lines · Michael Rubin
On Jan 17, 2008 9:01 PM, David Chinner <[email protected]> wrote:
First off thank you for the very detailed reply. This rocks and gives me much to think about.
Quoted 6 lines · Michael Rubin
This seems suboptimal for large files. If you keep feeding in new least recently dirtied files, the large files will never get an unimpeded go at the disk and hence we'll struggle to get decent bandwidth under anything but pure large file write loads.
You're right. I understand now. I just changed a dial on my tests, ran it and found pdflush not keeping up like it should. I need to address this.
Quoted 31 lines
Switching inodes during writeback implies a seek to the new write location, while continuing to write the same inode has no seek penalty because the writeback is sequential. It follows from this that allowing larges file a disproportionate amount of data writeback is desirable.
Also, cycling rapidly through all the large files to write 4MB to each is going to cause us to spend time seeking rather than writing compared to cycling slower and writing 40MB from each large file at a time.
i.e. servicing one large file for 100ms is going to result in higher writeback throughput than servicing 10 large files for 10ms each because there's going to be less seeking and more writing done by the disks.
That is, think of large file writes like process scheduler batch jobs - bulk throughput is what matters, so the larger the time slice you give them the higher the throughput.
IMO, the sort of result we should be looking at is a writeback design that results in cycling somewhat like:
slice 1: iterate over small files
slice 2: flush large file 1
slice 3: iterate over small files
slice 4: flush large file 2
......
slice n-1: flush large file N
slice n: iterate over small files
slice n+1: flush large file N+1
Quoted 7 lines
Quoted 2 lines
So that we keep the disk busy with a relatively fair mix of small and large I/Os while both are necessary.
I am getting where you are coming from. But if we are going to make changes to optimize for seeks maybe we need to be more aggressive in write back in how we organize both time and location. Right now AFAIK there is no attention to location in the writeback path.
True. But IMO, locality ordering really only impacts the small file data writes and the inodes themselves because there is typically lots of seeks in doing that.
For large sequential writes to a file, writing a significant chunk of data gives that bit of writeback it's own locality because it does not cause seeks. Hence simply writing large enough chunks avoids any need to order the writeback by locality.
Hence I writeback ordering by locality more a function of optimising the "iterate over small files" aspect of the writeback.
Quoted 8 lines
Quoted 5 lines
The higher the bandwidth of the device, the more frequently we need to be servicing the inodes with large amounts of dirty data to be written to maintain write throughput at a significant percentage of the device capability.
Could you expand that to say it's not the inodes of large files but the ones with data that we can exploit locality?
Not sure I understand what you mean. Can you rephrase that?
Quoted 1 line
Often large files are fragmented.
Then the filesystem is not doing it's job. Fragmentation does not happen very frequently in XFS for large files - that is one of the reasons it is extremely good for large files and high throughput applications...
Quoted 3 lines
Would it make more sense to pursue cracking the inodes and grouping their blocks's locations? Or is this all overkill and should be handled at a lower level like the elevator?
For large files it is overkill. For filesystems that do delayed allocation, it is often impossible (no block mapping until the writeback is executed unless it's an overwrite).
At this point, I'd say it is best to leave it to the filesystem and the elevator to do their jobs properly.
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>
Quoted 2 lines · David Chinner
At this point, I'd say it is best to leave it to the filesystem and the elevator to do their jobs properly.
Amen.
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>
Quoted 36 lines
Fairness is a tradeoff between seeks and bandwidth. Ideally, we want to spend 50% of the *disk* time servicing sequential writes and 50% of the time servicing seeky writes - that way neither get penalised unfairly by the other type of workload.
Switching inodes during writeback implies a seek to the new write location, while continuing to write the same inode has no seek penalty because the writeback is sequential. It follows from this that allowing larges file a disproportionate amount of data writeback is desirable.
Also, cycling rapidly through all the large files to write 4MB to each is going to cause us to spend time seeking rather than writing compared to cycling slower and writing 40MB from each large file at a time.
i.e. servicing one large file for 100ms is going to result in higher writeback throughput than servicing 10 large files for 10ms each because there's going to be less seeking and more writing done by the disks.
That is, think of large file writes like process scheduler batch jobs - bulk throughput is what matters, so the larger the time slice you give them the higher the throughput.
IMO, the sort of result we should be looking at is a writeback design that results in cycling somewhat like:
slice 1: iterate over small files
slice 2: flush large file 1
slice 3: iterate over small files
slice 4: flush large file 2
......
slice n-1: flush large file N
slice n: iterate over small files
slice n+1: flush large file N+1
Quoted 2 lines
So that we keep the disk busy with a relatively fair mix of small and large I/Os while both are necessary.
If we can sync fast enough, the lower layer would be able to merge those 4MB requests. Whatever the slice size is, we end up sending the same set of pages to disk: the writable pages of expired inodes. We only have to worry about choosing the right set of pages being written in one single batch(in every pdflush wakeup time). That set is currently defined by the 5s/30s dirty expiration rules.
Quoted 25 lines
Furthermore, as disk bandwidth goes up, the relationship between large file and small file writes changes if we want to maintain writeback at a significant percentage of the maximum bandwidth of the drive (which is extremely desirable). So if we take a 4k page machine and a 1024page writeback slice, for different disks, we get a bandwidth slice in terms of disk seeks like:
slow disk: 20MB/s, 10ms seek (say a laptop drive)
- 4MB write takes 200ms, or equivalent of 10 seeksnormal disk: 60MB/s, 8ms seek (desktop)
- 4MB write takes 66ms, or equivalent of 8 seeksfast disk: 120MB/s, 5ms seek (15krpm SAS)
- 4MB write takes 33ms, or equivalent of 6 seekssmall RAID5 lun: 200MB/s, 4ms seek
- 4MB write takes 20ms, or equivalent of 5 seeksLarge RAID5 lun: 1GB/s, 2ms seek
- 4MB write takes 4ms, or equivalent of 2 seeksPut simply:
Quoted 7 lines
The higher the bandwidth of the device, the more frequently we need to be servicing the inodes with large amounts of dirty data to be written to maintain write throughput at a significant percentage of the device capability.
The writeback algorithm needs to take this into account for it to be able to scale effectively for high throughput devices.
Slow queues go full first. Currently the writeback code will skip _and_ congestion_wait() for congested filesystems. The better policy is to congestion_wait() _after_ all other writable pages have been synced. The same have been done for blocked inodes/pages in my patchset.
Quoted 7 lines
BTW, it needs to be recognised that if we are under memory pressure we can clean much more memory in a short period of time by writing out all the large files first. This would clearly benefit the system as a whole as we'd get the most pages available for reclaim as possible in a short a time as possible. The writeback algorithm should really have a mode that allows this sort of flush ordering to occur....
We might do write-behind for large files :-)
--
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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 16 lines · Fengguang Wu
Quoted 16 lines
That is, think of large file writes like process scheduler batch jobs - bulk throughput is what matters, so the larger the time slice you give them the higher the throughput.
IMO, the sort of result we should be looking at is a writeback design that results in cycling somewhat like:
slice 1: iterate over small files
slice 2: flush large file 1
slice 3: iterate over small files
slice 4: flush large file 2
......
slice n-1: flush large file N
slice n: iterate over small files
slice n+1: flush large file N+1
Quoted 5 lines
Quoted 2 lines
So that we keep the disk busy with a relatively fair mix of small and large I/Os while both are necessary.
If we can sync fast enough, the lower layer would be able to merge those 4MB requests.
No, not necessarily - think of a stripe with a chunk size of 512k. That 4MB will be split into 8x512k chunks and sent to different devices (and hence elevator queues). The only way you get elevator merging in this sort of config is that if you send multiple stripe *width* sized amounts to the device in a very short time period. I see quite a few filesystems with stripe widths in the tens of MB range.....
Quoted 7 lines
Quoted 7 lines
Put simply:
The higher the bandwidth of the device, the more frequently we need to be servicing the inodes with large amounts of dirty data to be written to maintain write throughput at a significant percentage of the device capability.
Quoted 7 lines
Quoted 2 lines
The writeback algorithm needs to take this into account for it to be able to scale effectively for high throughput devices.
Slow queues go full first. Currently the writeback code will skip _and_
congestion_wait()for congested filesystems. The better policy is tocongestion_wait()_after_ all other writable pages have been synced.
Agreed.
The comments I've made are mainly concerned with getting efficient flushing of a single device occuring. Interactions between multiple devices are a separable issue....
Cheers,
Dave.
Signature · 9 lines
Dave Chinner Principal Engineer SGI Australian Software Group -- 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>