mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
writeback: make congestion functions per bdi_writeback
Currently, all congestion functions take bdi (backing_dev_info) and always operate on the root wb (bdi->wb) and the congestion state from the block layer is propagated only for the root blkcg. This patch introduces {set|clear}_wb_congested() and wb_congested() which take a bdi_writeback_congested and bdi_writeback respectively. The bdi counteparts are now wrappers invoking the wb based functions on @bdi->wb. While converting clear_bdi_congested() to clear_wb_congested(), the local variable declaration order between @wqh and @bit is swapped for cosmetic reason. This patch just adds the new wb based functions. The following patches will apply them. v2: Updated for bdi_writeback_congested. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@kernel.dk> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
dfb8ae5678
commit
ec8a6f2643
@ -163,7 +163,17 @@ enum {
|
|||||||
BLK_RW_SYNC = 1,
|
BLK_RW_SYNC = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void clear_bdi_congested(struct backing_dev_info *bdi, int sync);
|
void clear_wb_congested(struct bdi_writeback_congested *congested, int sync);
|
||||||
void set_bdi_congested(struct backing_dev_info *bdi, int sync);
|
void set_wb_congested(struct bdi_writeback_congested *congested, int sync);
|
||||||
|
|
||||||
|
static inline void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
|
||||||
|
{
|
||||||
|
clear_wb_congested(bdi->wb.congested, sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync)
|
||||||
|
{
|
||||||
|
set_wb_congested(bdi->wb.congested, sync);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __LINUX_BACKING_DEV_DEFS_H */
|
#endif /* __LINUX_BACKING_DEV_DEFS_H */
|
||||||
|
@ -167,27 +167,13 @@ static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
|
|||||||
return sb->s_bdi;
|
return sb->s_bdi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
|
static inline int wb_congested(struct bdi_writeback *wb, int cong_bits)
|
||||||
{
|
{
|
||||||
|
struct backing_dev_info *bdi = wb->bdi;
|
||||||
|
|
||||||
if (bdi->congested_fn)
|
if (bdi->congested_fn)
|
||||||
return bdi->congested_fn(bdi->congested_data, bdi_bits);
|
return bdi->congested_fn(bdi->congested_data, cong_bits);
|
||||||
return (bdi->wb.congested->state & bdi_bits);
|
return wb->congested->state & cong_bits;
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bdi_read_congested(struct backing_dev_info *bdi)
|
|
||||||
{
|
|
||||||
return bdi_congested(bdi, 1 << WB_sync_congested);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bdi_write_congested(struct backing_dev_info *bdi)
|
|
||||||
{
|
|
||||||
return bdi_congested(bdi, 1 << WB_async_congested);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bdi_rw_congested(struct backing_dev_info *bdi)
|
|
||||||
{
|
|
||||||
return bdi_congested(bdi, (1 << WB_sync_congested) |
|
|
||||||
(1 << WB_async_congested));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long congestion_wait(int sync, long timeout);
|
long congestion_wait(int sync, long timeout);
|
||||||
@ -454,4 +440,25 @@ static inline void wb_blkcg_offline(struct blkcg *blkcg)
|
|||||||
|
|
||||||
#endif /* CONFIG_CGROUP_WRITEBACK */
|
#endif /* CONFIG_CGROUP_WRITEBACK */
|
||||||
|
|
||||||
|
static inline int bdi_congested(struct backing_dev_info *bdi, int cong_bits)
|
||||||
|
{
|
||||||
|
return wb_congested(&bdi->wb, cong_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bdi_read_congested(struct backing_dev_info *bdi)
|
||||||
|
{
|
||||||
|
return bdi_congested(bdi, 1 << WB_sync_congested);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bdi_write_congested(struct backing_dev_info *bdi)
|
||||||
|
{
|
||||||
|
return bdi_congested(bdi, 1 << WB_async_congested);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bdi_rw_congested(struct backing_dev_info *bdi)
|
||||||
|
{
|
||||||
|
return bdi_congested(bdi, (1 << WB_sync_congested) |
|
||||||
|
(1 << WB_async_congested));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_BACKING_DEV_H */
|
#endif /* _LINUX_BACKING_DEV_H */
|
||||||
|
@ -896,31 +896,31 @@ static wait_queue_head_t congestion_wqh[2] = {
|
|||||||
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
|
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
|
||||||
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
|
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
|
||||||
};
|
};
|
||||||
static atomic_t nr_bdi_congested[2];
|
static atomic_t nr_wb_congested[2];
|
||||||
|
|
||||||
void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
|
void clear_wb_congested(struct bdi_writeback_congested *congested, int sync)
|
||||||
{
|
{
|
||||||
enum wb_state bit;
|
|
||||||
wait_queue_head_t *wqh = &congestion_wqh[sync];
|
wait_queue_head_t *wqh = &congestion_wqh[sync];
|
||||||
|
enum wb_state bit;
|
||||||
|
|
||||||
bit = sync ? WB_sync_congested : WB_async_congested;
|
bit = sync ? WB_sync_congested : WB_async_congested;
|
||||||
if (test_and_clear_bit(bit, &bdi->wb.congested->state))
|
if (test_and_clear_bit(bit, &congested->state))
|
||||||
atomic_dec(&nr_bdi_congested[sync]);
|
atomic_dec(&nr_wb_congested[sync]);
|
||||||
smp_mb__after_atomic();
|
smp_mb__after_atomic();
|
||||||
if (waitqueue_active(wqh))
|
if (waitqueue_active(wqh))
|
||||||
wake_up(wqh);
|
wake_up(wqh);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(clear_bdi_congested);
|
EXPORT_SYMBOL(clear_wb_congested);
|
||||||
|
|
||||||
void set_bdi_congested(struct backing_dev_info *bdi, int sync)
|
void set_wb_congested(struct bdi_writeback_congested *congested, int sync)
|
||||||
{
|
{
|
||||||
enum wb_state bit;
|
enum wb_state bit;
|
||||||
|
|
||||||
bit = sync ? WB_sync_congested : WB_async_congested;
|
bit = sync ? WB_sync_congested : WB_async_congested;
|
||||||
if (!test_and_set_bit(bit, &bdi->wb.congested->state))
|
if (!test_and_set_bit(bit, &congested->state))
|
||||||
atomic_inc(&nr_bdi_congested[sync]);
|
atomic_inc(&nr_wb_congested[sync]);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(set_bdi_congested);
|
EXPORT_SYMBOL(set_wb_congested);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* congestion_wait - wait for a backing_dev to become uncongested
|
* congestion_wait - wait for a backing_dev to become uncongested
|
||||||
@ -979,7 +979,7 @@ long wait_iff_congested(struct zone *zone, int sync, long timeout)
|
|||||||
* encountered in the current zone, yield if necessary instead
|
* encountered in the current zone, yield if necessary instead
|
||||||
* of sleeping on the congestion queue
|
* of sleeping on the congestion queue
|
||||||
*/
|
*/
|
||||||
if (atomic_read(&nr_bdi_congested[sync]) == 0 ||
|
if (atomic_read(&nr_wb_congested[sync]) == 0 ||
|
||||||
!test_bit(ZONE_CONGESTED, &zone->flags)) {
|
!test_bit(ZONE_CONGESTED, &zone->flags)) {
|
||||||
cond_resched();
|
cond_resched();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user