diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-09-09 03:08:54 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-09-11 03:20:25 -0400 |
commit | 03ba3782e8dcc5b0e1efe440d33084f066e38cae (patch) | |
tree | e5a6513b411de16a46199530ec98ef9b7f1efc50 /include/linux/writeback.h | |
parent | 66f3b8e2e103a0b93b945764d98e9ba46cb926dd (diff) |
writeback: switch to per-bdi threads for flushing data
This gets rid of pdflush for bdi writeout and kupdated style cleaning.
pdflush writeout suffers from lack of locality and also requires more
threads to handle the same workload, since it has to work in a
non-blocking fashion against each queue. This also introduces lumpy
behaviour and potential request starvation, since pdflush can be starved
for queue access if others are accessing it. A sample ffsb workload that
does random writes to files is about 8% faster here on a simple SATA drive
during the benchmark phase. File layout also seems a LOT more smooth in
vmstat:
r b swpd free buff cache si so bi bo in cs us sy id wa
0 1 0 608848 2652 375372 0 0 0 71024 604 24 1 10 48 42
0 1 0 549644 2712 433736 0 0 0 60692 505 27 1 8 48 44
1 0 0 476928 2784 505192 0 0 4 29540 553 24 0 9 53 37
0 1 0 457972 2808 524008 0 0 0 54876 331 16 0 4 38 58
0 1 0 366128 2928 614284 0 0 4 92168 710 58 0 13 53 34
0 1 0 295092 3000 684140 0 0 0 62924 572 23 0 9 53 37
0 1 0 236592 3064 741704 0 0 4 58256 523 17 0 8 48 44
0 1 0 165608 3132 811464 0 0 0 57460 560 21 0 8 54 38
0 1 0 102952 3200 873164 0 0 4 74748 540 29 1 10 48 41
0 1 0 48604 3252 926472 0 0 0 53248 469 29 0 7 47 45
where vanilla tends to fluctuate a lot in the creation phase:
r b swpd free buff cache si so bi bo in cs us sy id wa
1 1 0 678716 5792 303380 0 0 0 74064 565 50 1 11 52 36
1 0 0 662488 5864 319396 0 0 4 352 302 329 0 2 47 51
0 1 0 599312 5924 381468 0 0 0 78164 516 55 0 9 51 40
0 1 0 519952 6008 459516 0 0 4 78156 622 56 1 11 52 37
1 1 0 436640 6092 541632 0 0 0 82244 622 54 0 11 48 41
0 1 0 436640 6092 541660 0 0 0 8 152 39 0 0 51 49
0 1 0 332224 6200 644252 0 0 4 102800 728 46 1 13 49 36
1 0 0 274492 6260 701056 0 0 4 12328 459 49 0 7 50 43
0 1 0 211220 6324 763356 0 0 0 106940 515 37 1 10 51 39
1 0 0 160412 6376 813468 0 0 0 8224 415 43 0 6 49 45
1 1 0 85980 6452 886556 0 0 4 113516 575 39 1 11 54 34
0 2 0 85968 6452 886620 0 0 0 1640 158 211 0 0 46 54
A 10 disk test with btrfs performs 26% faster with per-bdi flushing. A
SSD based writeback test on XFS performs over 20% better as well, with
the throughput being very stable around 1GB/sec, where pdflush only
manages 750MB/sec and fluctuates wildly while doing so. Random buffered
writes to many files behave a lot better as well, as does random mmap'ed
writes.
A separate thread is added to sync the super blocks. In the long term,
adding sync_supers_bdi() functionality could get rid of this thread again.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include/linux/writeback.h')
-rw-r--r-- | include/linux/writeback.h | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 07039299603d..cef75527a14c 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -40,6 +40,8 @@ enum writeback_sync_modes { | |||
40 | struct writeback_control { | 40 | struct writeback_control { |
41 | struct backing_dev_info *bdi; /* If !NULL, only write back this | 41 | struct backing_dev_info *bdi; /* If !NULL, only write back this |
42 | queue */ | 42 | queue */ |
43 | struct super_block *sb; /* if !NULL, only write inodes from | ||
44 | this super_block */ | ||
43 | enum writeback_sync_modes sync_mode; | 45 | enum writeback_sync_modes sync_mode; |
44 | unsigned long *older_than_this; /* If !NULL, only write back inodes | 46 | unsigned long *older_than_this; /* If !NULL, only write back inodes |
45 | older than this */ | 47 | older than this */ |
@@ -76,10 +78,13 @@ struct writeback_control { | |||
76 | /* | 78 | /* |
77 | * fs/fs-writeback.c | 79 | * fs/fs-writeback.c |
78 | */ | 80 | */ |
79 | void writeback_inodes(struct writeback_control *wbc); | 81 | struct bdi_writeback; |
80 | int inode_wait(void *); | 82 | int inode_wait(void *); |
81 | long writeback_inodes_sb(struct super_block *); | 83 | long writeback_inodes_sb(struct super_block *); |
82 | long sync_inodes_sb(struct super_block *); | 84 | long sync_inodes_sb(struct super_block *); |
85 | void writeback_inodes_wbc(struct writeback_control *wbc); | ||
86 | long wb_do_writeback(struct bdi_writeback *wb, int force_wait); | ||
87 | void wakeup_flusher_threads(long nr_pages); | ||
83 | 88 | ||
84 | /* writeback.h requires fs.h; it, too, is not included from here. */ | 89 | /* writeback.h requires fs.h; it, too, is not included from here. */ |
85 | static inline void wait_on_inode(struct inode *inode) | 90 | static inline void wait_on_inode(struct inode *inode) |
@@ -99,7 +104,6 @@ static inline void inode_sync_wait(struct inode *inode) | |||
99 | /* | 104 | /* |
100 | * mm/page-writeback.c | 105 | * mm/page-writeback.c |
101 | */ | 106 | */ |
102 | int wakeup_pdflush(long nr_pages); | ||
103 | void laptop_io_completion(void); | 107 | void laptop_io_completion(void); |
104 | void laptop_sync_completion(void); | 108 | void laptop_sync_completion(void); |
105 | void throttle_vm_writeout(gfp_t gfp_mask); | 109 | void throttle_vm_writeout(gfp_t gfp_mask); |