[Devel] [PATCH rh7 2/2] mm/page-writeback: Introduce per-CT dirty memory limit.
Vladimir Davydov
vdavydov at virtuozzo.com
Mon Jan 18 03:42:37 PST 2016
On Fri, Jan 15, 2016 at 06:17:25PM +0300, Andrey Ryabinin wrote:
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 91c1b07..836ce88 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -195,6 +195,28 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
> bdi_wakeup_thread(bdi);
> }
>
> +/**
> + * bdi_start_background_writeback_ub - start background writeback for ub
> + * @bdi: the backing device to write from
> + * @ub: taks's io beancounter
> + *
> + * Description:
> + * This makes sure WB_SYNC_NONE background writeback happens. When
> + * this function returns, it is only guaranteed that for given BDI
> + * some IO is happening if we are over background dirty threshold.
> + * Caller need not hold sb s_umount semaphore.
> + */
> +void bdi_start_background_writeback_ub(struct backing_dev_info *bdi,
> + struct user_beancounter *ub)
> +{
> + /*
> + * We just wake up the flusher thread. It will perform background
> + * writeback as soon as there is no other work to do.
> + */
> + trace_writeback_wake_background(bdi);
> + __bdi_start_writeback(bdi, LONG_MAX, true, WB_REASON_BACKGROUND, ub);
> +}
> +
> /*
> * Remove the inode from the writeback list it is on.
> */
> @@ -708,6 +730,15 @@ static long writeback_sb_inodes(struct super_block *sb,
> * kind writeout is handled by the freer.
> */
> spin_lock(&inode->i_lock);
> + /* Filter ub inodes if bdi dirty limit isn't exceeded */
> + if (work->ub && !wb->bdi->dirty_exceeded &&
> + (inode->i_state & I_DIRTY) == I_DIRTY_PAGES &&
> + ub_should_skip_writeback(work->ub, inode)) {
> + spin_unlock(&inode->i_lock);
> + redirty_tail(inode, wb);
> + continue;
> + }
> +
> if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
> spin_unlock(&inode->i_lock);
> redirty_tail(inode, wb);
I think the two hunks above should go to patch #1.
> diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
> index b7668cf..ae0e828 100644
> --- a/include/linux/backing-dev.h
> +++ b/include/linux/backing-dev.h
...
> @@ -1654,6 +1894,12 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping)
> struct backing_dev_info *bdi = mapping->backing_dev_info;
> int ratelimit;
> int *p;
> + struct user_beancounter *ub = get_io_ub();
> +
> + if (ub != get_ub0()) {
> + balance_dirty_pages_ratelimited_nr(mapping, 1);
> + return;
> + }
I don't think it's a good idea to skip global background writeback
altogether in case of containers. I'd use per-ub writeback in
conjunction with the global writeback, i.e. if we exceed per-ub dirty
limit do per-ub writeback, then check the global dirty limit and perform
global writeback if needed. The point is that the global writeback code
will be invoked more often, I guess, and it works better, so we'd better
make use of it whenever possible.
>
> if (!bdi_cap_account_dirty(bdi))
> return;
More information about the Devel
mailing list