[Top] [All Lists]

Re: [PATCH 3/4] xfs: add quota-driven speculative preallocation throttli

To: Brian Foster <bfoster@xxxxxxxxxx>
Subject: Re: [PATCH 3/4] xfs: add quota-driven speculative preallocation throttling
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Sun, 16 Dec 2012 08:25:30 +1100
Cc: xfs@xxxxxxxxxxx
In-reply-to: <50CB500C.8090203@xxxxxxxxxx>
References: <1354726078-31793-1-git-send-email-bfoster@xxxxxxxxxx> <1354726078-31793-4-git-send-email-bfoster@xxxxxxxxxx> <20121213022530.GF16353@dastard> <50CB500C.8090203@xxxxxxxxxx>
User-agent: Mutt/1.5.21 (2010-09-15)
On Fri, Dec 14, 2012 at 11:13:00AM -0500, Brian Foster wrote:
> On 12/12/2012 09:25 PM, Dave Chinner wrote:
> > On Wed, Dec 05, 2012 at 11:47:57AM -0500, Brian Foster wrote:
> ...
> >>
> >> Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx>
> > 
> > I'm having trouble determining what the algorithm is supposed to be
> > and what might be bugs in the algorithm....
> > 
> > These are notes, somewhat incoherent, but I'll post them anyway
> > because i think they convey my concerns and solutions well enough.
> > 
> Ok...
> >     - if there is a hard limit but no soft limit, it *always*
> >       throttles preallocation to the default percentage even
> >       where there is lots of space available for the full
> >       prealloc.
> > 
> I'm not following you here. xfs_prealloc_dquot_max() should return the
> maximum allowed preallocation for a quota by calculating some percentage
> of the free space in the quota (regardless of the existence of a soft
> limit; that serves as a throttling watermark and percentage modifier).

Say you have a quota and 50GB of free space and we are trying to
preallocate 8GB of that, xfs_prealloc_dquot_max() will always
return a max of 2.5GB. Hence preallocation will be limited even
though there's plenty of space available for a preallocation that is
larger than this....

> xfs_prealloc_quota_max() just extends that across all quota types and
> returns the most limiting value. For an inode with plenty of space in
> its quota set, we should get a large value back for max_quota_prealloc,
> which is then ignored because alloc_blocks doesn't violate that limit.

But if we are trying to do a large file allocation (as per above),
it does limit it atificially. IOWs, files without quota soft limits set by
the user are treated as _always over the soft limit_.

> > need_throttle()
> > {
> >     if (!xfs_this_quota_on(mp, type))
> >             return false;
> > 
> >     dq = xfs_inode_dquot(ip, type);
> > 
> >     /* no hard limit, no throttle */
> >     if (!dq->q_hard_limit)
> >             return false;
> > 
> >     /* over hard limit, always throttle */
> >     if (dq->q_res_bcount > dq->q_hard_limit)
> >             return true;
> > 
> >     /*
> >      * Under soft limit, no throttle.
> >      *
> >      * Note: we always have a soft limit for prealloc,
> >      * calculated at dquot instantiation or limit change
> >      */
> >     if (dq->q_res_bcount + alloc_blocks < dq->q_soft_limit)
> >             return false;
> > 
> >     /* between soft limit and hard limit, need to throttle */
> >     return true;
> > }
> > 
> > - needs struct xfs-dquot to be initialised appropriately and quota
> >   limit changes to handle changes correctly.
> > 
> > - allows soft limit defaults to be set in memory if they aren't on
> >   disk. i.e. default throttling values will be no different in
> >   implementation to on-disk limits.
> > 
> This comment is not quite clear to me. I suspect it relates to the
> pseudocode comment above with regard to a default soft limit. To this
> point, I'm interpreting your design proposal as something like the
> following, at a high-level:
> - xfs_dquot grows a (in memory) table of low space limits. This table is
> populated in when the quota is read from disk, created and/or the input
> parameters (hard/soft limit) change.
> - The soft limit as a percentage modifier goes away by nature of using
> the 3-5% logarithmic throttle (shift).

not 3-5% :P, a divisor of 2, 8 or 16....

> - The soft limit as a prealloc throttling trigger remains, just
> implemented as a separate function as depicted above.
> There are no on-disk changes proposed, correct?


> Are you suggesting we
> set a default soft limit value on all quotas with a hard limit?

Yes. Your code already does this, effectively, by treating files
that have no softlimit set as always being over the soft limit.

> I'm a little unsure about applying a shift selected for one limit
> against the preallocation size of another, but I suppose it can't hurt
> to be aggressive.

Which is what this sort of throttling needs to be.

Essentially, the idea is that if we are close to a quota limit and
ENOSPC at the same time, whichever limit we are closer to exceeding
should determine the amount of throttling that will take place (i.e.
the shift value).

The size of the preallocation is a separate calculation to this -
the quota thresholds only ever reduce the size, but that doesn't
change how close we are to throttle thresholds. IOWs, even if the
base prealloc is smaller than the max quota prealloc size, we still
should throttle it according to the quota throttle if we are closer
to exceeding the quota thresholds than we are the ENOSPC

> This design should bubble up all the relevant
> parameters to a single point anyways, so that should be easier to reason
> about and measure when I have some code.

Exactly. You've just put words to the concept I was struggling to
describe. :)


Dave Chinner

<Prev in Thread] Current Thread [Next in Thread>