writeback: cgroup writeback support
Subsystems (35)
Tejun Heo
maintainerPATCH 46/51 writeback: restructure try_writeback_inodes_sb[_nr]()
In reply to Tejun Heotry_writeback_inodes_sb_nr() wraps writeback_inodes_sb_nr() so that it handles s_umount locking and skips if writeback is already in progress. The in progress test is performed on the root wb (bdi_writeback) which isn't sufficient for cgroup writeback support. The test must be done per-wb.
To prepare for the change, this patch factors out __writeback_inodes_sb_nr() from writeback_inodes_sb_nr() and adds @skip_if_busy and moves the in progress test right before queueing the wb_writeback_work. try_writeback_inodes_sb_nr() now just grabs s_umount and invokes __writeback_inodes_sb_nr() with asserted @skip_if_busy. This way, later addition of multiple wb handling can skip only the wb's which already have writeback in progress.
This swaps the order between in progress test and s_umount test which can flip the return value when writeback is in progress and s_umount is being held by someone else but this shouldn't cause any meaningful difference. It's a fringe condition and the return value is an unsynchronized hint anyway.
--- fs/fs-writeback.c | 52 ++++++++++++++++++++++++++--------------------- include/linux/writeback.h | 6 +++--- 2 files changed, 32 insertions(+), 26 deletions(-)
fs/fs-writeback.c +29 -23
@@ -1581,19 +1581,8 @@ static void wait_sb_inodes(struct super_block *sb)iput (old_inode); } -/** -* writeback_inodes_sb_nr - writeback dirty inodes from given super_block -* @sb: the superblock -* @nr: the number of pages to write -* @reason: reason why some writeback work initiated -* -* Start writeback on some inodes on this super_block. No guarantees are made -* on how many (if any) will be written, and this function does not wait -* for IO completion of submitted IO. -*/ -void writeback_inodes_sb_nr (struct super_block *sb, -unsigned long nr, -enum wb_reason reason) +static void __writeback_inodes_sb_nr (struct super_block *sb,unsigned long nr, +enum wb_reason reason,bool skip_if_busy) {DEFINE_WB_COMPLETION_ONSTACK (done);struct wb_writeback_work work = {
@@ -1609,9 +1598,30 @@ void writeback_inodes_sb_nr(struct super_block *sb,if (!bdi_has_dirty_io (bdi) || bdi == &noop_backing_dev_info)return ;WARN_ON (!rwsem_is_locked (&sb->s_umount)); + +if (skip_if_busy &&writeback_in_progress (&bdi->wb)) +return ; +wb_queue_work (&bdi->wb, &work);wb_wait_for_completion (bdi, &done); } + +/** +* writeback_inodes_sb_nr - writeback dirty inodes from given super_block +* @sb: the superblock +* @nr: the number of pages to write +* @reason: reason why some writeback work initiated +* +* Start writeback on some inodes on this super_block. No guarantees are made +* on how many (if any) will be written, and this function does not wait +* for IO completion of submitted IO. +*/ +void writeback_inodes_sb_nr (struct super_block *sb, +unsigned long nr, +enum wb_reason reason) +{ +__writeback_inodes_sb_nr (sb, nr, reason, false); +}EXPORT_SYMBOL (writeback_inodes_sb_nr);/**
@@ -1638,19 +1648,15 @@ EXPORT_SYMBOL(writeback_inodes_sb);* Invoke writeback_inodes_sb_nr if no writeback is currently underway. * Returns 1 if writeback was started, 0 if not. */ -int try_to_writeback_inodes_sb_nr (struct super_block *sb, -unsigned long nr, -enum wb_reason reason) +bool try_to_writeback_inodes_sb_nr (struct super_block *sb,unsigned long nr, +enum wb_reason reason) { -if (writeback_in_progress (&sb->s_bdi->wb)) -return 1 ; -if (!down_read_trylock (&sb->s_umount)) -return 0 ; +return false; -writeback_inodes_sb_nr (sb, nr, reason); +__writeback_inodes_sb_nr (sb, nr, reason, true);up_read (&sb->s_umount); -return 1 ; +return true; }EXPORT_SYMBOL (try_to_writeback_inodes_sb_nr);
@@ -1662,7 +1668,7 @@ EXPORT_SYMBOL(try_to_writeback_inodes_sb_nr);* Implement by try_to_writeback_inodes_sb_nr() * Returns 1 if writeback was started, 0 if not. */ -int try_to_writeback_inodes_sb (struct super_block *sb,enum wb_reason reason) +bool try_to_writeback_inodes_sb (struct super_block *sb,enum wb_reason reason) {return try_to_writeback_inodes_sb_nr (sb,get_nr_dirty_pages (), reason); }
include/linux/writeback.h +3 -3
@@ -93,9 +93,9 @@ struct bdi_writeback;void writeback_inodes_sb (struct super_block *,enum wb_reason reason);void writeback_inodes_sb_nr (struct super_block *,unsigned long nr,enum wb_reason reason); -int try_to_writeback_inodes_sb (struct super_block *,enum wb_reason reason); -int try_to_writeback_inodes_sb_nr (struct super_block *,unsigned long nr, -enum wb_reason reason); +bool try_to_writeback_inodes_sb (struct super_block *,enum wb_reason reason); +bool try_to_writeback_inodes_sb_nr (struct super_block *,unsigned long nr, +enum wb_reason reason);void sync_inodes_sb (struct super_block *);void wakeup_flusher_threads (long nr_pages,enum wb_reason reason);void inode_wait_for_writeback (struct inode *inode);
Signature · 7 lines
2.4.0 -- 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>
Tejun Heo
maintainerPATCH 47/51 writeback: make writeback initiation functions handle multiple bdi_writeback's
In reply to Tejun Heo[try_]writeback_inodes_sb[_nr]() and sync_inodes_sb() currently only handle dirty inodes on the root wb (bdi_writeback) of the target bdi. This patch implements bdi_split_work_to_wbs() and use it to make these functions handle multiple wb's.
bdi_split_work_to_wbs() takes a base wb_writeback_work and create clones of it and issue them to the wb's of the target bdi. The base work's nr_pages is distributed using wb_split_bdi_pages() - ie. according to each wb's write bandwidth's proportion in the bdi.
Cloning a bdi involves memory allocation which may fail. In such cases, bdi_split_work_to_wbs() issues the base work directly and waits for its completion before proceeding to the next wb to guarantee forward progress and correctness under memory pressure.
--- fs/fs-writeback.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-)
fs/fs-writeback.c +91 -5
@@ -292,6 +292,80 @@ static long wb_split_bdi_pages(struct bdi_writeback *wb, long nr_pages) return DIV_ROUND_UP_ULL((u64)nr_pages * this_bw, tot_bw); } +/** +* wb_clone_and_queue_work - clone a wb_writeback_work and issue it to a wb +* @wb: target bdi_writeback +* @base_work: source wb_writeback_work +* +* Try to make a clone of @base_work and issue it to @wb. If cloning +* succeeds, %true is returned; otherwise, @base_work is issued directly +* and %false is returned. In the latter case, the caller is required to +* wait for @base_work's completion using wb_wait_for_single_work(). +* +* A clone is auto-freed on completion. @base_work never is. +*/ +static bool wb_clone_and_queue_work (struct bdi_writeback *wb, +struct wb_writeback_work *base_work) +{ +struct wb_writeback_work *work; + + work =kmalloc (sizeof (*work),GFP_ATOMIC ); +if (work) { + *work = *base_work; + work->auto_free =1 ; + work->single_wait =0 ; + }else { + work = base_work; + work->auto_free =0 ; + work->single_wait =1 ; + } + work->single_done =0 ; +wb_queue_work (wb, work); +return work != base_work; +} + +/** +* bdi_split_work_to_wbs - split a wb_writeback_work to all wb's of a bdi +* @bdi: target backing_dev_info +* @base_work: wb_writeback_work to issue +* @skip_if_busy: skip wb's which already have writeback in progress +* +* Split and issue @base_work to all wb's (bdi_writeback's) of @bdi which +* have dirty inodes. If @base_work->nr_page isn't %LONG_MAX, it's +* distributed to the busy wbs according to each wb's proportion in the +* total active write bandwidth of @bdi. +*/ +static void bdi_split_work_to_wbs (struct backing_dev_info *bdi, +struct wb_writeback_work *base_work, +bool skip_if_busy) +{ +long nr_pages = base_work->nr_pages; +int next_blkcg_id =0 ; +struct bdi_writeback *wb; +struct wb_iter iter; + +might_sleep (); + +if (!bdi_has_dirty_io (bdi)) +return ; +restart: +rcu_read_lock (); +bdi_for_each_wb (wb, bdi, &iter, next_blkcg_id) { +if (!wb_has_dirty_io (wb) || + (skip_if_busy &&writeback_in_progress (wb))) +continue ; + + base_work->nr_pages =wb_split_bdi_pages (wb, nr_pages); +if (!wb_clone_and_queue_work (wb, base_work)) { + next_blkcg_id = wb->blkcg_css->id +1 ; +rcu_read_unlock (); +wb_wait_for_single_work (bdi, base_work); + goto restart; + } + } +rcu_read_unlock (); +} +#else /* CONFIG_CGROUP_WRITEBACK */ static long wb_split_bdi_pages (struct bdi_writeback *wb,long nr_pages)
@@ -299,6 +373,21 @@ static long wb_split_bdi_pages(struct bdi_writeback *wb, long nr_pages)return nr_pages; } +static void bdi_split_work_to_wbs (struct backing_dev_info *bdi, +struct wb_writeback_work *base_work, +bool skip_if_busy) +{ +might_sleep (); + +if (bdi_has_dirty_io (bdi) && + (!skip_if_busy || !writeback_in_progress (&bdi->wb))) { + base_work->auto_free =0 ; + base_work->single_wait =0 ; + base_work->single_done =0 ; +wb_queue_work (&bdi->wb, base_work); + } +} +#endif /* CONFIG_CGROUP_WRITEBACK */ void wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
@@ -1599,10 +1688,7 @@ static void __writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr,return ;WARN_ON (!rwsem_is_locked (&sb->s_umount)); -if (skip_if_busy &&writeback_in_progress (&bdi->wb)) -return ; - -wb_queue_work (&bdi->wb, &work); +bdi_split_work_to_wbs (sb->s_bdi, &work, skip_if_busy);wb_wait_for_completion (bdi, &done); }
@@ -1700,7 +1786,7 @@ void sync_inodes_sb(struct super_block *sb)return ;WARN_ON (!rwsem_is_locked (&sb->s_umount)); -wb_queue_work (&bdi->wb, &work); +bdi_split_work_to_wbs (bdi, &work, false);wb_wait_for_completion (bdi, &done);wait_sb_inodes (sb);
Signature · 1 line
2.4.0
Tejun Heo
maintainerPATCH 48/51 writeback: dirty inodes against their matching cgroup bdi_writeback's
In reply to Tejun Heo__mark_inode_dirty() always dirtied the inode against the root wb (bdi_writeback). The previous patches added all the infrastructure necessary to attribute an inode against the wb of the dirtying cgroup.
This patch updates __mark_inode_dirty() so that it uses the wb associated with the inode instead of unconditionally using the root one.
Currently, none of the filesystems has FS_CGROUP_WRITEBACK and all pages will keep being dirtied against the root wb.
v2: Updated for per-inode wb association.
--- fs/fs-writeback.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
fs/fs-writeback.c +11 -12
@@ -1504,7 +1504,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)void __mark_inode_dirty (struct inode *inode,int flags) {struct super_block *sb = inode->i_sb; -struct backing_dev_info *bdi =NULL ;int dirtytime;trace_writeback_mark_inode_dirty (inode, flags);
@@ -1574,30 +1573,30 @@ void __mark_inode_dirty(struct inode *inode, int flags)* reposition it (that would break b_dirty time-ordering). */ if (!was_dirty) { +struct bdi_writeback *wb =inode_to_wb (inode);struct list_head *dirty_list;bool wakeup_bdi = false; - bdi =inode_to_bdi (inode);spin_unlock (&inode->i_lock); -spin_lock (&bdi->wb.list_lock); +spin_lock (&wb->list_lock); -WARN (bdi_cap_writeback_dirty (bdi) && - !test_bit (WB_registered, &bdi->wb.state), -"bdi-%s not registered\n" , bdi->name); +WARN (bdi_cap_writeback_dirty (wb->bdi) && + !test_bit (WB_registered, &wb->state), +"bdi-%s not registered\n" , wb->bdi->name); inode->dirtied_when = jiffies;if (dirtytime) inode->dirtied_time_when = jiffies;if (inode->i_state & (I_DIRTY_INODE |I_DIRTY_PAGES )) - dirty_list = &bdi->wb.b_dirty; + dirty_list = &wb->b_dirty;else - dirty_list = &bdi->wb.b_dirty_time; + dirty_list = &wb->b_dirty_time; - wakeup_bdi =inode_wb_list_move_locked (inode, &bdi->wb, + wakeup_bdi =inode_wb_list_move_locked (inode, wb, dirty_list); -spin_unlock (&bdi->wb.list_lock); +spin_unlock (&wb->list_lock);trace_writeback_dirty_inode_enqueue (inode);/*
@@ -1606,8 +1605,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)* to make sure background write-back happens * later. */ -if (bdi_cap_writeback_dirty (bdi) && wakeup_bdi) -wb_wakeup_delayed (&bdi->wb); +if (bdi_cap_writeback_dirty (wb->bdi) && wakeup_bdi) +wb_wakeup_delayed (wb);return ; } }
Signature · 1 line
2.4.0
Re: [PATCH 48/51] writeback: dirty inodes against their matching cgroup bdi_writeback's
Quoted 8 lines · Tejun Heo
__mark_inode_dirty()always dirtied the inode against the root wb (bdi_writeback). The previous patches added all the infrastructure necessary to attribute an inode against the wb of the dirtying cgroup.This patch updates
__mark_inode_dirty()so that it uses the wb associated with the inode instead of unconditionally using the root one.
Quoted 8 lines
Currently, none of the filesystems has
FS_CGROUP_WRITEBACKand all pages will keep being dirtied against the root wb.v2: Updated for per-inode wb association.
Signed-off-by Tejun Heo <[email protected]>Cc Jens Axboe <axboe-tSWWG44O7X1aa/[email protected]>Cc Jan Kara <[email protected]>
Looks good. You can add:
Honza
Quoted 70 lines
--- fs/fs-writeback.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)fs/fs-writeback.c +11
-12@@ -1504,7 +1504,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)void __mark_inode_dirty (struct inode *inode,int flags) {struct super_block *sb = inode->i_sb; -struct backing_dev_info *bdi =NULL ;int dirtytime;trace_writeback_mark_inode_dirty (inode, flags);@@ -1574,30 +1573,30 @@ void __mark_inode_dirty(struct inode *inode, int flags)* reposition it (that would break b_dirty time-ordering). */ if (!was_dirty) { +struct bdi_writeback *wb =inode_to_wb (inode);struct list_head *dirty_list;bool wakeup_bdi = false; - bdi =inode_to_bdi (inode);spin_unlock (&inode->i_lock); -spin_lock (&bdi->wb.list_lock); +spin_lock (&wb->list_lock); -WARN (bdi_cap_writeback_dirty (bdi) && - !test_bit (WB_registered, &bdi->wb.state), -"bdi-%s not registered\n" , bdi->name); +WARN (bdi_cap_writeback_dirty (wb->bdi) && + !test_bit (WB_registered, &wb->state), +"bdi-%s not registered\n" , wb->bdi->name); inode->dirtied_when = jiffies;if (dirtytime) inode->dirtied_time_when = jiffies;if (inode->i_state & (I_DIRTY_INODE |I_DIRTY_PAGES )) - dirty_list = &bdi->wb.b_dirty; + dirty_list = &wb->b_dirty;else - dirty_list = &bdi->wb.b_dirty_time; + dirty_list = &wb->b_dirty_time; - wakeup_bdi =inode_wb_list_move_locked (inode, &bdi->wb, + wakeup_bdi =inode_wb_list_move_locked (inode, wb, dirty_list); -spin_unlock (&bdi->wb.list_lock); +spin_unlock (&wb->list_lock);trace_writeback_dirty_inode_enqueue (inode);/* @@ -1606,8 +1605,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)* to make sure background write-back happens * later. */ -if (bdi_cap_writeback_dirty (bdi) && wakeup_bdi) -wb_wakeup_delayed (&bdi->wb); +if (bdi_cap_writeback_dirty (wb->bdi) && wakeup_bdi) +wb_wakeup_delayed (wb);return ; } }Signature · 1 line
2.4.0
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 49/51 buffer, writeback: make __block_write_full_page() honor cgroup writeback
In reply to Tejun Heo[__]block_write_full_page() is used to implement ->writepage in various filesystems. All writeback logic is now updated to handle cgroup writeback and the block cgroup to issue IOs for is encoded in writeback_control and can be retrieved from the inode; however, [__]block_write_full_page() currently ignores the blkcg indicated by inode and issues all bio's without explicit blkcg association.
This patch adds submit_bh_blkcg() which associates the bio with the specified blkio cgroup before issuing and uses it in __block_write_full_page() so that the issued bio's are associated with inode_to_wb_blkcg_css(inode).
v2: Updated for per-inode wb association.
--- fs/buffer.c | 26 ++++++++++++++++++++------ include/linux/backing-dev.h | 12 ++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-)
fs/buffer.c +20 -6
@@ -30,6 +30,7 @@#include <linux/quotaops.h> #include <linux/highmem.h> #include <linux/export.h> +#include <linux/backing-dev.h> #include <linux/writeback.h> #include <linux/hash.h> #include <linux/suspend.h>
@@ -44,6 +45,9 @@#include <trace/events/block.h> static int fsync_buffers_list (spinlock_t *lock,struct list_head *list); +static int submit_bh_blkcg (int rw,struct buffer_head *bh, +unsigned long bio_flags, +struct cgroup_subsys_state *blkcg_css);#define BH_ENTRY (list) list_entry((list), struct buffer_head, b_assoc_buffers)
@@ -1704,8 +1708,8 @@ static int __block_write_full_page(struct inode *inode, struct page *page,struct buffer_head *bh, *head;unsigned int blocksize, bbits;int nr_underway =0 ; -int write_op = (wbc->sync_mode ==WB_SYNC_ALL ? -WRITE_SYNC :WRITE ); +int write_op = (wbc->sync_mode ==WB_SYNC_ALL ?WRITE_SYNC :WRITE ); +struct cgroup_subsys_state *blkcg_css =inode_to_wb_blkcg_css (inode); head =create_page_buffers (page, inode, (1 << BH_Dirty)|(1 << BH_Uptodate));
@@ -1794,7 +1798,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page, do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { - submit_bh(write_op, bh); + submit_bh_blkcg(write_op, bh, 0, blkcg_css); nr_underway++; } bh = next;
@@ -1848,7 +1852,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,struct buffer_head *next = bh->b_this_page;if (buffer_async_write (bh)) {clear_buffer_dirty (bh); -submit_bh (write_op, bh); +submit_bh_blkcg (write_op, bh,0 , blkcg_css); nr_underway++; } bh = next;
@@ -3013,7 +3017,9 @@ void guard_bio_eod(int rw, struct bio *bio) } } -int _submit_bh (int rw,struct buffer_head *bh,unsigned long bio_flags) +static int submit_bh_blkcg (int rw,struct buffer_head *bh, +unsigned long bio_flags, +struct cgroup_subsys_state *blkcg_css) {struct bio *bio;int ret =0 ;
@@ -3036,6 +3042,9 @@ int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)*/ bio =bio_alloc (GFP_NOIO ,1 ); +if (blkcg_css) +bio_associate_blkcg (bio, blkcg_css); + bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >>9 ); bio->bi_bdev = bh->b_bdev; bio->bi_io_vec[0 ].bv_page = bh->b_page;
@@ -3060,11 +3069,16 @@ int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)submit_bio (rw, bio);return ret; } + +int _submit_bh (int rw,struct buffer_head *bh,unsigned long bio_flags) +{ +return submit_bh_blkcg (rw, bh, bio_flags,NULL ); +}EXPORT_SYMBOL_GPL (_submit_bh);int submit_bh (int rw,struct buffer_head *bh) { -return _submit_bh (rw, bh,0 ); +return submit_bh_blkcg (rw, bh,0 ,NULL ); }EXPORT_SYMBOL (submit_bh);
include/linux/backing-dev.h +12 -0
@@ -393,6 +393,12 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode)return inode->i_wb; } +static inline struct cgroup_subsys_state * +inode_to_wb_blkcg_css (struct inode *inode) +{ +return inode_to_wb (inode)->blkcg_css; +} +struct wb_iter {int start_blkcg_id;struct radix_tree_iter tree_iter;
@@ -510,6 +516,12 @@ static inline void wb_blkcg_offline(struct blkcg *blkcg) { } +static inline struct cgroup_subsys_state * +inode_to_wb_blkcg_css (struct inode *inode) +{ +return blkcg_root_css; +} +struct wb_iter {int next_id; };
Signature · 1 line
2.4.0
Jan Kara
maintainerRe: [PATCH 49/51] buffer, writeback: make __block_write_full_page() honor cgroup writeback
Quoted 11 lines · Tejun Heo
[__]block_write_full_page() is used to implement ->writepage in various filesystems. All writeback logic is now updated to handle cgroup writeback and the block cgroup to issue IOs for is encoded in
writeback_controland can be retrieved from the inode; however, [__]block_write_full_page() currently ignores the blkcg indicated by inode and issues all bio's without explicit blkcg association.This patch adds
submit_bh_blkcg()which associates the bio with the specified blkio cgroup before issuing and uses it in__block_write_full_page()so that the issued bio's are associated withinode_to_wb_blkcg_css(inode).
One comment below...
fs/buffer.c line 49
Quoted 6 lines
fs/buffer.c +2
-0@@ -44,6 +45,9 @@#include <trace/events/block.h> static int fsync_buffers_list (spinlock_t *lock,struct list_head *list); +static int submit_bh_blkcg(int rw, struct buffer_head *bh, + unsigned long bio_flags,
The argument bio_flags is unused. What is is good for?
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Re: [PATCH 49/51] buffer, writeback: make __block_write_full_page() honor cgroup writeback
Quoted 15 lines · Jan Kara
Quoted 11 lines · Tejun Heo
[__]block_write_full_page() is used to implement ->writepage in various filesystems. All writeback logic is now updated to handle cgroup writeback and the block cgroup to issue IOs for is encoded in
writeback_controland can be retrieved from the inode; however, [__]block_write_full_page() currently ignores the blkcg indicated by inode and issues all bio's without explicit blkcg association.This patch adds
submit_bh_blkcg()which associates the bio with the specified blkio cgroup before issuing and uses it in__block_write_full_page()so that the issued bio's are associated withinode_to_wb_blkcg_css(inode).One comment below...
Quoted 8 lines
fs/buffer.c line 49
Quoted 6 lines
fs/buffer.c +2
-0@@ -44,6 +45,9 @@#include <trace/events/block.h> static int fsync_buffers_list (spinlock_t *lock,struct list_head *list); +static int submit_bh_blkcg(int rw, struct buffer_head *bh, + unsigned long bio_flags,The argument
bio_flagsis unused. What is is good for?
Ah, sorry, I guess I'm too tired. I now see how bio_flags are used. The patch looks good. You can add:
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 50/51 mpage: make __mpage_writepage() honor cgroup writeback
In reply to Tejun Heo__mpage_writepage() is used to implement mpage_writepages() which in turn is used for ->writepages() of various filesystems. All writeback logic is now updated to handle cgroup writeback and the block cgroup to issue IOs for is encoded in writeback_control and can be retrieved from the inode; however, __mpage_writepage() currently ignores the blkcg indicated by the inode and issues all bio's without explicit blkcg association.
This patch updates __mpage_writepage() so that the issued bio's are associated with inode_to_writeback_blkcg_css(inode).
v2: Updated for per-inode wb association.
--- fs/mpage.c | 2 ++ 1 file changed, 2 insertions(+)
fs/mpage.c +2 -0
@@ -605,6 +605,8 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc, bio_get_nr_vecs(bdev), GFP_NOFS|__GFP_HIGH);if (bio ==NULL ) goto confused; + +bio_associate_blkcg (bio,inode_to_wb_blkcg_css (inode)); }/*
Signature · 1 line
2.4.0
Re: [PATCH 50/51] mpage: make __mpage_writepage() honor cgroup writeback
Quoted 8 lines · Tejun Heo
__mpage_writepage()is used to implementmpage_writepages()which in turn is used for ->writepages() of various filesystems. All writeback logic is now updated to handle cgroup writeback and the block cgroup to issue IOs for is encoded inwriteback_controland can be retrieved from the inode; however,__mpage_writepage()currently ignores the blkcg indicated by the inode and issues all bio's without explicit blkcg association.
Quoted 4 lines
This patch updates
__mpage_writepage()so that the issued bio's are associated withinode_to_writeback_blkcg_css(inode).v2: Updated for per-inode wb association.
Looks good. You can add:
Honza
Quoted 26 lines
Signed-off-by Tejun Heo <[email protected]>Cc Jens Axboe <[email protected]>Cc Jan Kara <[email protected]>Cc Andrew Morton <[email protected]>Cc Alexander Viro <[email protected]>--- fs/mpage.c | 2 ++ 1 file changed, 2 insertions(+)fs/mpage.c +2
-0@@ -605,6 +605,8 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc, bio_get_nr_vecs(bdev), GFP_NOFS|__GFP_HIGH);if (bio ==NULL ) goto confused; + +bio_associate_blkcg (bio,inode_to_wb_blkcg_css (inode)); }/* Signature · 1 line
2.4.0
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 51/51 ext2: enable cgroup writeback support
In reply to Tejun HeoWriteback now supports cgroup writeback and the generic writeback, buffer, libfs, and mpage helpers that ext2 uses are all updated to work with cgroup writeback.
This patch enables cgroup writeback for ext2 by adding FS_CGROUP_WRITEBACK to its ->fs_flags.
--- fs/ext2/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext2/super.c +1 -1
@@ -1543,7 +1543,7 @@ static struct file_system_type ext2_fs_type = { .name = "ext2", .mount = ext2_mount, .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, + .fs_flags = FS_REQUIRES_DEV | FS_CGROUP_WRITEBACK, };MODULE_ALIAS_FS ("ext2" );
Signature · 1 line
2.4.0
Re: [PATCH 51/51] ext2: enable cgroup writeback support
Quoted 11 lines · Tejun Heo
Writeback now supports cgroup writeback and the generic writeback, buffer, libfs, and mpage helpers that ext2 uses are all updated to work with cgroup writeback.
This patch enables cgroup writeback for ext2 by adding
FS_CGROUP_WRITEBACKto its ->fs_flags.Signed-off-by Tejun Heo <[email protected]>Cc Jens Axboe <[email protected]>Cc Jan Kara <[email protected]>
Hallelujah!
Quoted 20 lines
--- fs/ext2/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)fs/ext2/super.c +1
-1@@ -1543,7 +1543,7 @@ static struct file_system_type ext2_fs_type = { .name = "ext2", .mount = ext2_mount, .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, + .fs_flags = FS_REQUIRES_DEV | FS_CGROUP_WRITEBACK, };MODULE_ALIAS_FS ("ext2" );Signature · 1 line
2.4.0
Signature · 8 lines
Jan Kara <[email protected]> SUSE Labs, CR -- 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>
Tejun Heo
maintainerRe: [PATCH 51/51] ext2: enable cgroup writeback support
Quoted 8 lines · Jan Kara
Quoted 7 lines · Tejun Heo
Writeback now supports cgroup writeback and the generic writeback, buffer, libfs, and mpage helpers that ext2 uses are all updated to work with cgroup writeback.
This patch enables cgroup writeback for ext2 by adding
FS_CGROUP_WRITEBACKto its ->fs_flags.
Quoted 8 lines
Quoted 4 lines
Signed-off-by Tejun Heo <[email protected]>Cc Jens Axboe <[email protected]>Cc Jan Kara <[email protected]>Hallelujah!
Reviewed-by Jan Kara <[email protected]>
Hooray! Thanks a lot for going through all the patches! :)
Signature · 7 lines
tejun -- 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>