Skip to content

Commit 703c270

Browse files
htejunaxboe
authored andcommitted
writeback: implement and use inode_congested()
In several places, bdi_congested() and its wrappers are used to determine whether more IOs should be issued. With cgroup writeback support, this question can't be answered solely based on the bdi (backing_dev_info). It's dependent on whether the filesystem and bdi support cgroup writeback and the blkcg the inode is associated with. This patch implements inode_congested() and its wrappers which take @iNode and determines the congestion state considering cgroup writeback. The new functions replace bdi_*congested() calls in places where the query is about specific inode and task. There are several filesystem users which also fit this criteria but they should be updated when each filesystem implements cgroup writeback support. v2: Now that a given inode is associated with only one wb, congestion state can be determined independent from the asking task. Drop @task. Spotted by Vivek. Also, converted to take @iNode instead of @mapping and renamed to inode_congested(). Signed-off-by: Tejun Heo <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Jan Kara <[email protected]> Cc: Vivek Goyal <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 482cf79 commit 703c270

File tree

5 files changed

+58
-8
lines changed

5 files changed

+58
-8
lines changed

fs/fs-writeback.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@ static void __wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
142142
wb_queue_work(wb, work);
143143
}
144144

145+
#ifdef CONFIG_CGROUP_WRITEBACK
146+
147+
/**
148+
* inode_congested - test whether an inode is congested
149+
* @inode: inode to test for congestion
150+
* @cong_bits: mask of WB_[a]sync_congested bits to test
151+
*
152+
* Tests whether @inode is congested. @cong_bits is the mask of congestion
153+
* bits to test and the return value is the mask of set bits.
154+
*
155+
* If cgroup writeback is enabled for @inode, the congestion state is
156+
* determined by whether the cgwb (cgroup bdi_writeback) for the blkcg
157+
* associated with @inode is congested; otherwise, the root wb's congestion
158+
* state is used.
159+
*/
160+
int inode_congested(struct inode *inode, int cong_bits)
161+
{
162+
if (inode) {
163+
struct bdi_writeback *wb = inode_to_wb(inode);
164+
if (wb)
165+
return wb_congested(wb, cong_bits);
166+
}
167+
168+
return wb_congested(&inode_to_bdi(inode)->wb, cong_bits);
169+
}
170+
EXPORT_SYMBOL_GPL(inode_congested);
171+
172+
#endif /* CONFIG_CGROUP_WRITEBACK */
173+
145174
/**
146175
* bdi_start_writeback - start writeback
147176
* @bdi: the backing device to write from

include/linux/backing-dev.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
230230
void __inode_attach_wb(struct inode *inode, struct page *page);
231231
void wb_memcg_offline(struct mem_cgroup *memcg);
232232
void wb_blkcg_offline(struct blkcg *blkcg);
233+
int inode_congested(struct inode *inode, int cong_bits);
233234

234235
/**
235236
* inode_cgwb_enabled - test whether cgroup writeback is enabled on an inode
@@ -438,8 +439,29 @@ static inline void wb_blkcg_offline(struct blkcg *blkcg)
438439
{
439440
}
440441

442+
static inline int inode_congested(struct inode *inode, int cong_bits)
443+
{
444+
return wb_congested(&inode_to_bdi(inode)->wb, cong_bits);
445+
}
446+
441447
#endif /* CONFIG_CGROUP_WRITEBACK */
442448

449+
static inline int inode_read_congested(struct inode *inode)
450+
{
451+
return inode_congested(inode, 1 << WB_sync_congested);
452+
}
453+
454+
static inline int inode_write_congested(struct inode *inode)
455+
{
456+
return inode_congested(inode, 1 << WB_async_congested);
457+
}
458+
459+
static inline int inode_rw_congested(struct inode *inode)
460+
{
461+
return inode_congested(inode, (1 << WB_sync_congested) |
462+
(1 << WB_async_congested));
463+
}
464+
443465
static inline int bdi_congested(struct backing_dev_info *bdi, int cong_bits)
444466
{
445467
return wb_congested(&bdi->wb, cong_bits);

mm/fadvise.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
115115
case POSIX_FADV_NOREUSE:
116116
break;
117117
case POSIX_FADV_DONTNEED:
118-
if (!bdi_write_congested(bdi))
118+
if (!inode_write_congested(mapping->host))
119119
__filemap_fdatawrite_range(mapping, offset, endbyte,
120120
WB_SYNC_NONE);
121121

mm/readahead.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ page_cache_async_readahead(struct address_space *mapping,
541541
/*
542542
* Defer asynchronous read-ahead on IO congestion.
543543
*/
544-
if (bdi_read_congested(inode_to_bdi(mapping->host)))
544+
if (inode_read_congested(mapping->host))
545545
return;
546546

547547
/* do read-ahead */

mm/vmscan.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,13 @@ static inline int is_page_cache_freeable(struct page *page)
452452
return page_count(page) - page_has_private(page) == 2;
453453
}
454454

455-
static int may_write_to_queue(struct backing_dev_info *bdi,
456-
struct scan_control *sc)
455+
static int may_write_to_inode(struct inode *inode, struct scan_control *sc)
457456
{
458457
if (current->flags & PF_SWAPWRITE)
459458
return 1;
460-
if (!bdi_write_congested(bdi))
459+
if (!inode_write_congested(inode))
461460
return 1;
462-
if (bdi == current->backing_dev_info)
461+
if (inode_to_bdi(inode) == current->backing_dev_info)
463462
return 1;
464463
return 0;
465464
}
@@ -538,7 +537,7 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
538537
}
539538
if (mapping->a_ops->writepage == NULL)
540539
return PAGE_ACTIVATE;
541-
if (!may_write_to_queue(inode_to_bdi(mapping->host), sc))
540+
if (!may_write_to_inode(mapping->host, sc))
542541
return PAGE_KEEP;
543542

544543
if (clear_page_dirty_for_io(page)) {
@@ -924,7 +923,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
924923
*/
925924
mapping = page_mapping(page);
926925
if (((dirty || writeback) && mapping &&
927-
bdi_write_congested(inode_to_bdi(mapping->host))) ||
926+
inode_write_congested(mapping->host)) ||
928927
(writeback && PageReclaim(page)))
929928
nr_congested++;
930929

0 commit comments

Comments
 (0)