Skip to content

Commit

Permalink
writeback, cgroup: switch to rcu_work API in inode_switch_wbs()
Browse files Browse the repository at this point in the history
Inode's wb switching requires two steps divided by an RCU grace period.
It's currently implemented as an RCU callback inode_switch_wbs_rcu_fn(),
which schedules inode_switch_wbs_work_fn() as a work.

Switching to the rcu_work API allows to do the same in a cleaner and
slightly shorter form.

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Roman Gushchin <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Acked-by: Dennis Zhou <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rgushchin authored and torvalds committed Jun 29, 2021
1 parent 8826ee4 commit 29264d9
Showing 1 changed file with 4 additions and 14 deletions.
18 changes: 4 additions & 14 deletions fs/fs-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,7 @@ struct inode_switch_wbs_context {
struct inode *inode;
struct bdi_writeback *new_wb;

struct rcu_head rcu_head;
struct work_struct work;
struct rcu_work work;
};

static void bdi_down_write_wb_switch_rwsem(struct backing_dev_info *bdi)
Expand All @@ -352,7 +351,7 @@ static void bdi_up_write_wb_switch_rwsem(struct backing_dev_info *bdi)
static void inode_switch_wbs_work_fn(struct work_struct *work)
{
struct inode_switch_wbs_context *isw =
container_of(work, struct inode_switch_wbs_context, work);
container_of(to_rcu_work(work), struct inode_switch_wbs_context, work);
struct inode *inode = isw->inode;
struct backing_dev_info *bdi = inode_to_bdi(inode);
struct address_space *mapping = inode->i_mapping;
Expand Down Expand Up @@ -469,16 +468,6 @@ static void inode_switch_wbs_work_fn(struct work_struct *work)
atomic_dec(&isw_nr_in_flight);
}

static void inode_switch_wbs_rcu_fn(struct rcu_head *rcu_head)
{
struct inode_switch_wbs_context *isw = container_of(rcu_head,
struct inode_switch_wbs_context, rcu_head);

/* needs to grab bh-unsafe locks, bounce to work item */
INIT_WORK(&isw->work, inode_switch_wbs_work_fn);
queue_work(isw_wq, &isw->work);
}

/**
* inode_switch_wbs - change the wb association of an inode
* @inode: target inode
Expand Down Expand Up @@ -536,7 +525,8 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
* lock so that stat transfer can synchronize against them.
* Let's continue after I_WB_SWITCH is guaranteed to be visible.
*/
call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
INIT_RCU_WORK(&isw->work, inode_switch_wbs_work_fn);
queue_rcu_work(isw_wq, &isw->work);
return;

out_free:
Expand Down

0 comments on commit 29264d9

Please sign in to comment.