mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-06 22:42:10 +00:00
writeback: move backing_dev_info->state into bdi_writeback
Currently, a bdi (backing_dev_info) embeds single wb (bdi_writeback) and the role of the separation is unclear. For cgroup support for writeback IOs, a bdi will be updated to host multiple wb's where each wb serves writeback IOs of a different cgroup on the bdi. To achieve that, a wb should carry all states necessary for servicing writeback IOs for a cgroup independently. This patch moves bdi->state into wb. * enum bdi_state is renamed to wb_state and the prefix of all enums is changed from BDI_ to WB_. * Explicit zeroing of bdi->state is removed without adding zeoring of wb->state as the whole data structure is zeroed on init anyway. * As there's still only one bdi_writeback per backing_dev_info, all uses of bdi->state are mechanically replaced with bdi->wb.state introducing no behavior changes. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Jan Kara <jack@suse.cz> Cc: Jens Axboe <axboe@kernel.dk> Cc: Wu Fengguang <fengguang.wu@intel.com> Cc: drbd-dev@lists.linbit.com Cc: Neil Brown <neilb@suse.de> Cc: Alasdair Kergon <agk@redhat.com> Cc: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
ad7fa852d3
commit
4452226ea2
8 changed files with 38 additions and 39 deletions
|
@ -621,7 +621,6 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
|
||||||
|
|
||||||
q->backing_dev_info.ra_pages =
|
q->backing_dev_info.ra_pages =
|
||||||
(VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
|
(VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
|
||||||
q->backing_dev_info.state = 0;
|
|
||||||
q->backing_dev_info.capabilities = 0;
|
q->backing_dev_info.capabilities = 0;
|
||||||
q->backing_dev_info.name = "block";
|
q->backing_dev_info.name = "block";
|
||||||
q->node = node_id;
|
q->node = node_id;
|
||||||
|
|
|
@ -2359,7 +2359,7 @@ static void drbd_cleanup(void)
|
||||||
* @congested_data: User data
|
* @congested_data: User data
|
||||||
* @bdi_bits: Bits the BDI flusher thread is currently interested in
|
* @bdi_bits: Bits the BDI flusher thread is currently interested in
|
||||||
*
|
*
|
||||||
* Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested.
|
* Returns 1<<WB_async_congested and/or 1<<WB_sync_congested if we are congested.
|
||||||
*/
|
*/
|
||||||
static int drbd_congested(void *congested_data, int bdi_bits)
|
static int drbd_congested(void *congested_data, int bdi_bits)
|
||||||
{
|
{
|
||||||
|
@ -2376,14 +2376,14 @@ static int drbd_congested(void *congested_data, int bdi_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(CALLBACK_PENDING, &first_peer_device(device)->connection->flags)) {
|
if (test_bit(CALLBACK_PENDING, &first_peer_device(device)->connection->flags)) {
|
||||||
r |= (1 << BDI_async_congested);
|
r |= (1 << WB_async_congested);
|
||||||
/* Without good local data, we would need to read from remote,
|
/* Without good local data, we would need to read from remote,
|
||||||
* and that would need the worker thread as well, which is
|
* and that would need the worker thread as well, which is
|
||||||
* currently blocked waiting for that usermode helper to
|
* currently blocked waiting for that usermode helper to
|
||||||
* finish.
|
* finish.
|
||||||
*/
|
*/
|
||||||
if (!get_ldev_if_state(device, D_UP_TO_DATE))
|
if (!get_ldev_if_state(device, D_UP_TO_DATE))
|
||||||
r |= (1 << BDI_sync_congested);
|
r |= (1 << WB_sync_congested);
|
||||||
else
|
else
|
||||||
put_ldev(device);
|
put_ldev(device);
|
||||||
r &= bdi_bits;
|
r &= bdi_bits;
|
||||||
|
@ -2399,9 +2399,9 @@ static int drbd_congested(void *congested_data, int bdi_bits)
|
||||||
reason = 'b';
|
reason = 'b';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bdi_bits & (1 << BDI_async_congested) &&
|
if (bdi_bits & (1 << WB_async_congested) &&
|
||||||
test_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags)) {
|
test_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags)) {
|
||||||
r |= (1 << BDI_async_congested);
|
r |= (1 << WB_async_congested);
|
||||||
reason = reason == 'b' ? 'a' : 'n';
|
reason = reason == 'b' ? 'a' : 'n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2074,7 +2074,7 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
|
||||||
* the query about congestion status of request_queue
|
* the query about congestion status of request_queue
|
||||||
*/
|
*/
|
||||||
if (dm_request_based(md))
|
if (dm_request_based(md))
|
||||||
r = md->queue->backing_dev_info.state &
|
r = md->queue->backing_dev_info.wb.state &
|
||||||
bdi_bits;
|
bdi_bits;
|
||||||
else
|
else
|
||||||
r = dm_table_any_congested(map, bdi_bits);
|
r = dm_table_any_congested(map, bdi_bits);
|
||||||
|
|
|
@ -745,7 +745,7 @@ static int raid1_congested(struct mddev *mddev, int bits)
|
||||||
struct r1conf *conf = mddev->private;
|
struct r1conf *conf = mddev->private;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
if ((bits & (1 << BDI_async_congested)) &&
|
if ((bits & (1 << WB_async_congested)) &&
|
||||||
conf->pending_count >= max_queued_requests)
|
conf->pending_count >= max_queued_requests)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -760,7 +760,7 @@ static int raid1_congested(struct mddev *mddev, int bits)
|
||||||
/* Note the '|| 1' - when read_balance prefers
|
/* Note the '|| 1' - when read_balance prefers
|
||||||
* non-congested targets, it can be removed
|
* non-congested targets, it can be removed
|
||||||
*/
|
*/
|
||||||
if ((bits & (1<<BDI_async_congested)) || 1)
|
if ((bits & (1 << WB_async_congested)) || 1)
|
||||||
ret |= bdi_congested(&q->backing_dev_info, bits);
|
ret |= bdi_congested(&q->backing_dev_info, bits);
|
||||||
else
|
else
|
||||||
ret &= bdi_congested(&q->backing_dev_info, bits);
|
ret &= bdi_congested(&q->backing_dev_info, bits);
|
||||||
|
|
|
@ -914,7 +914,7 @@ static int raid10_congested(struct mddev *mddev, int bits)
|
||||||
struct r10conf *conf = mddev->private;
|
struct r10conf *conf = mddev->private;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
if ((bits & (1 << BDI_async_congested)) &&
|
if ((bits & (1 << WB_async_congested)) &&
|
||||||
conf->pending_count >= max_queued_requests)
|
conf->pending_count >= max_queued_requests)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ unsigned int dirtytime_expire_interval = 12 * 60 * 60;
|
||||||
*/
|
*/
|
||||||
int writeback_in_progress(struct backing_dev_info *bdi)
|
int writeback_in_progress(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
return test_bit(BDI_writeback_running, &bdi->state);
|
return test_bit(WB_writeback_running, &bdi->wb.state);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(writeback_in_progress);
|
EXPORT_SYMBOL(writeback_in_progress);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(wbc_writepage);
|
||||||
static void bdi_wakeup_thread(struct backing_dev_info *bdi)
|
static void bdi_wakeup_thread(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
spin_lock_bh(&bdi->wb_lock);
|
spin_lock_bh(&bdi->wb_lock);
|
||||||
if (test_bit(BDI_registered, &bdi->state))
|
if (test_bit(WB_registered, &bdi->wb.state))
|
||||||
mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
|
||||||
spin_unlock_bh(&bdi->wb_lock);
|
spin_unlock_bh(&bdi->wb_lock);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ static void bdi_queue_work(struct backing_dev_info *bdi,
|
||||||
trace_writeback_queue(bdi, work);
|
trace_writeback_queue(bdi, work);
|
||||||
|
|
||||||
spin_lock_bh(&bdi->wb_lock);
|
spin_lock_bh(&bdi->wb_lock);
|
||||||
if (!test_bit(BDI_registered, &bdi->state)) {
|
if (!test_bit(WB_registered, &bdi->wb.state)) {
|
||||||
if (work->done)
|
if (work->done)
|
||||||
complete(work->done);
|
complete(work->done);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@ -1057,7 +1057,7 @@ static long wb_do_writeback(struct bdi_writeback *wb)
|
||||||
struct wb_writeback_work *work;
|
struct wb_writeback_work *work;
|
||||||
long wrote = 0;
|
long wrote = 0;
|
||||||
|
|
||||||
set_bit(BDI_writeback_running, &wb->bdi->state);
|
set_bit(WB_writeback_running, &wb->state);
|
||||||
while ((work = get_next_work_item(bdi)) != NULL) {
|
while ((work = get_next_work_item(bdi)) != NULL) {
|
||||||
|
|
||||||
trace_writeback_exec(bdi, work);
|
trace_writeback_exec(bdi, work);
|
||||||
|
@ -1079,7 +1079,7 @@ static long wb_do_writeback(struct bdi_writeback *wb)
|
||||||
*/
|
*/
|
||||||
wrote += wb_check_old_data_flush(wb);
|
wrote += wb_check_old_data_flush(wb);
|
||||||
wrote += wb_check_background_flush(wb);
|
wrote += wb_check_background_flush(wb);
|
||||||
clear_bit(BDI_writeback_running, &wb->bdi->state);
|
clear_bit(WB_writeback_running, &wb->state);
|
||||||
|
|
||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
|
@ -1099,7 +1099,7 @@ void bdi_writeback_workfn(struct work_struct *work)
|
||||||
current->flags |= PF_SWAPWRITE;
|
current->flags |= PF_SWAPWRITE;
|
||||||
|
|
||||||
if (likely(!current_is_workqueue_rescuer() ||
|
if (likely(!current_is_workqueue_rescuer() ||
|
||||||
!test_bit(BDI_registered, &bdi->state))) {
|
!test_bit(WB_registered, &wb->state))) {
|
||||||
/*
|
/*
|
||||||
* The normal path. Keep writing back @bdi until its
|
* The normal path. Keep writing back @bdi until its
|
||||||
* work_list is empty. Note that this path is also taken
|
* work_list is empty. Note that this path is also taken
|
||||||
|
@ -1323,7 +1323,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
spin_lock(&bdi->wb.list_lock);
|
spin_lock(&bdi->wb.list_lock);
|
||||||
if (bdi_cap_writeback_dirty(bdi)) {
|
if (bdi_cap_writeback_dirty(bdi)) {
|
||||||
WARN(!test_bit(BDI_registered, &bdi->state),
|
WARN(!test_bit(WB_registered, &bdi->wb.state),
|
||||||
"bdi-%s not registered\n", bdi->name);
|
"bdi-%s not registered\n", bdi->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -25,13 +25,13 @@ struct device;
|
||||||
struct dentry;
|
struct dentry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bits in backing_dev_info.state
|
* Bits in bdi_writeback.state
|
||||||
*/
|
*/
|
||||||
enum bdi_state {
|
enum wb_state {
|
||||||
BDI_async_congested, /* The async (write) queue is getting full */
|
WB_async_congested, /* The async (write) queue is getting full */
|
||||||
BDI_sync_congested, /* The sync queue is getting full */
|
WB_sync_congested, /* The sync queue is getting full */
|
||||||
BDI_registered, /* bdi_register() was done */
|
WB_registered, /* bdi_register() was done */
|
||||||
BDI_writeback_running, /* Writeback is in progress */
|
WB_writeback_running, /* Writeback is in progress */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (congested_fn)(void *, int);
|
typedef int (congested_fn)(void *, int);
|
||||||
|
@ -49,6 +49,7 @@ enum bdi_stat_item {
|
||||||
struct bdi_writeback {
|
struct bdi_writeback {
|
||||||
struct backing_dev_info *bdi; /* our parent bdi */
|
struct backing_dev_info *bdi; /* our parent bdi */
|
||||||
|
|
||||||
|
unsigned long state; /* Always use atomic bitops on this */
|
||||||
unsigned long last_old_flush; /* last old data flush */
|
unsigned long last_old_flush; /* last old data flush */
|
||||||
|
|
||||||
struct delayed_work dwork; /* work item used for writeback */
|
struct delayed_work dwork; /* work item used for writeback */
|
||||||
|
@ -62,7 +63,6 @@ struct bdi_writeback {
|
||||||
struct backing_dev_info {
|
struct backing_dev_info {
|
||||||
struct list_head bdi_list;
|
struct list_head bdi_list;
|
||||||
unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
|
unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
|
||||||
unsigned long state; /* Always use atomic bitops on this */
|
|
||||||
unsigned int capabilities; /* Device capabilities */
|
unsigned int capabilities; /* Device capabilities */
|
||||||
congested_fn *congested_fn; /* Function pointer if device is md/dm */
|
congested_fn *congested_fn; /* Function pointer if device is md/dm */
|
||||||
void *congested_data; /* Pointer to aux data for congested func */
|
void *congested_data; /* Pointer to aux data for congested func */
|
||||||
|
@ -250,23 +250,23 @@ static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
|
||||||
{
|
{
|
||||||
if (bdi->congested_fn)
|
if (bdi->congested_fn)
|
||||||
return bdi->congested_fn(bdi->congested_data, bdi_bits);
|
return bdi->congested_fn(bdi->congested_data, bdi_bits);
|
||||||
return (bdi->state & bdi_bits);
|
return (bdi->wb.state & bdi_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bdi_read_congested(struct backing_dev_info *bdi)
|
static inline int bdi_read_congested(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
return bdi_congested(bdi, 1 << BDI_sync_congested);
|
return bdi_congested(bdi, 1 << WB_sync_congested);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bdi_write_congested(struct backing_dev_info *bdi)
|
static inline int bdi_write_congested(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
return bdi_congested(bdi, 1 << BDI_async_congested);
|
return bdi_congested(bdi, 1 << WB_async_congested);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bdi_rw_congested(struct backing_dev_info *bdi)
|
static inline int bdi_rw_congested(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
return bdi_congested(bdi, (1 << BDI_sync_congested) |
|
return bdi_congested(bdi, (1 << WB_sync_congested) |
|
||||||
(1 << BDI_async_congested));
|
(1 << WB_async_congested));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -96,7 +96,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
|
||||||
nr_io,
|
nr_io,
|
||||||
nr_more_io,
|
nr_more_io,
|
||||||
nr_dirty_time,
|
nr_dirty_time,
|
||||||
!list_empty(&bdi->bdi_list), bdi->state);
|
!list_empty(&bdi->bdi_list), bdi->wb.state);
|
||||||
#undef K
|
#undef K
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -280,7 +280,7 @@ void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi)
|
||||||
|
|
||||||
timeout = msecs_to_jiffies(dirty_writeback_interval * 10);
|
timeout = msecs_to_jiffies(dirty_writeback_interval * 10);
|
||||||
spin_lock_bh(&bdi->wb_lock);
|
spin_lock_bh(&bdi->wb_lock);
|
||||||
if (test_bit(BDI_registered, &bdi->state))
|
if (test_bit(WB_registered, &bdi->wb.state))
|
||||||
queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
|
queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
|
||||||
spin_unlock_bh(&bdi->wb_lock);
|
spin_unlock_bh(&bdi->wb_lock);
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
|
||||||
bdi->dev = dev;
|
bdi->dev = dev;
|
||||||
|
|
||||||
bdi_debug_register(bdi, dev_name(dev));
|
bdi_debug_register(bdi, dev_name(dev));
|
||||||
set_bit(BDI_registered, &bdi->state);
|
set_bit(WB_registered, &bdi->wb.state);
|
||||||
|
|
||||||
spin_lock_bh(&bdi_lock);
|
spin_lock_bh(&bdi_lock);
|
||||||
list_add_tail_rcu(&bdi->bdi_list, &bdi_list);
|
list_add_tail_rcu(&bdi->bdi_list, &bdi_list);
|
||||||
|
@ -339,7 +339,7 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
/* Make sure nobody queues further work */
|
/* Make sure nobody queues further work */
|
||||||
spin_lock_bh(&bdi->wb_lock);
|
spin_lock_bh(&bdi->wb_lock);
|
||||||
if (!test_and_clear_bit(BDI_registered, &bdi->state)) {
|
if (!test_and_clear_bit(WB_registered, &bdi->wb.state)) {
|
||||||
spin_unlock_bh(&bdi->wb_lock);
|
spin_unlock_bh(&bdi->wb_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -492,11 +492,11 @@ static atomic_t nr_bdi_congested[2];
|
||||||
|
|
||||||
void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
|
void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
|
||||||
{
|
{
|
||||||
enum bdi_state bit;
|
enum wb_state bit;
|
||||||
wait_queue_head_t *wqh = &congestion_wqh[sync];
|
wait_queue_head_t *wqh = &congestion_wqh[sync];
|
||||||
|
|
||||||
bit = sync ? BDI_sync_congested : BDI_async_congested;
|
bit = sync ? WB_sync_congested : WB_async_congested;
|
||||||
if (test_and_clear_bit(bit, &bdi->state))
|
if (test_and_clear_bit(bit, &bdi->wb.state))
|
||||||
atomic_dec(&nr_bdi_congested[sync]);
|
atomic_dec(&nr_bdi_congested[sync]);
|
||||||
smp_mb__after_atomic();
|
smp_mb__after_atomic();
|
||||||
if (waitqueue_active(wqh))
|
if (waitqueue_active(wqh))
|
||||||
|
@ -506,10 +506,10 @@ EXPORT_SYMBOL(clear_bdi_congested);
|
||||||
|
|
||||||
void set_bdi_congested(struct backing_dev_info *bdi, int sync)
|
void set_bdi_congested(struct backing_dev_info *bdi, int sync)
|
||||||
{
|
{
|
||||||
enum bdi_state bit;
|
enum wb_state bit;
|
||||||
|
|
||||||
bit = sync ? BDI_sync_congested : BDI_async_congested;
|
bit = sync ? WB_sync_congested : WB_async_congested;
|
||||||
if (!test_and_set_bit(bit, &bdi->state))
|
if (!test_and_set_bit(bit, &bdi->wb.state))
|
||||||
atomic_inc(&nr_bdi_congested[sync]);
|
atomic_inc(&nr_bdi_congested[sync]);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(set_bdi_congested);
|
EXPORT_SYMBOL(set_bdi_congested);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue