writeback, cgroup: support switching multiple inodes at once
Currently only a single inode can be switched to another writeback structure at once. That means to switch an inode a separate inode_switch_wbs_context structure must be allocated, and a separate rcu callback and work must be scheduled. It's fine for the existing ad-hoc switching, which is not happening that often, but sub-optimal for massive switching required in order to release a writeback structure. To prepare for it, let's add a support for switching multiple inodes at once. Instead of containing a single inode pointer, inode_switch_wbs_context will contain a NULL-terminated array of inode pointers. inode_do_switch_wbs() will be called for each inode. To optimize the locking bdi->wb_switch_rwsem, old_wb's and new_wb's list_locks will be acquired and released only once altogether for all inodes. wb_wakeup() will be also be called only once. Instead of calling wb_put(old_wb) after each successful switch, wb_put_many() is introduced and used. Link: https://lkml.kernel.org/r/20210608230225.2078447-8-guro@fb.com Signed-off-by: Roman Gushchin <guro@fb.com> Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Jan Kara <jack@suse.cz> Acked-by: Dennis Zhou <dennis@kernel.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Dave Chinner <dchinner@redhat.com> Cc: Jan Kara <jack@suse.com> Cc: Jens Axboe <axboe@kernel.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
72d4512e9c
commit
f5fbe6b7ad
@@ -240,8 +240,9 @@ static inline void wb_get(struct bdi_writeback *wb)
|
||||
/**
|
||||
* wb_put - decrement a wb's refcount
|
||||
* @wb: bdi_writeback to put
|
||||
* @nr: number of references to put
|
||||
*/
|
||||
static inline void wb_put(struct bdi_writeback *wb)
|
||||
static inline void wb_put_many(struct bdi_writeback *wb, unsigned long nr)
|
||||
{
|
||||
if (WARN_ON_ONCE(!wb->bdi)) {
|
||||
/*
|
||||
@@ -252,7 +253,16 @@ static inline void wb_put(struct bdi_writeback *wb)
|
||||
}
|
||||
|
||||
if (wb != &wb->bdi->wb)
|
||||
percpu_ref_put(&wb->refcnt);
|
||||
percpu_ref_put_many(&wb->refcnt, nr);
|
||||
}
|
||||
|
||||
/**
|
||||
* wb_put - decrement a wb's refcount
|
||||
* @wb: bdi_writeback to put
|
||||
*/
|
||||
static inline void wb_put(struct bdi_writeback *wb)
|
||||
{
|
||||
wb_put_many(wb, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,6 +291,10 @@ static inline void wb_put(struct bdi_writeback *wb)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wb_put_many(struct bdi_writeback *wb, unsigned long nr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool wb_dying(struct bdi_writeback *wb)
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user