Message ID | 20180511225107.27171-2-david@fromorbit.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On Sat, May 12, 2018 at 08:50:58AM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > For the new growfs work, we want to ensure that we serialise > secondary superblock updates with other operations (e.g. scrub) > correctly, but we don't want to cache the buffers for long term > reuse. We need cached buffers for serialisation, however. > > To solve this, introduce a "oneshot" buffer which will be marshalled > through the cache but then released once the last current reference > goes away. If the buffer is already cached, then we ignore the > "one-shot" behaviour and leave the buffer in the state it was prior > to the one-shot command being run. This means we don't perturb > either the working set or existing cached buffer state by a one-shot > operation. > > Signed-Off-By: Dave Chinner <dchinner@redhat.com> Hmm, should the xfs_sb_read_secondary function in "xfs: superblock scrub should use short-lived buffers" be calling this to set a zero lru_ref instead of doing it directly? The code itself looks ok, Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > --- > fs/xfs/xfs_buf.h | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h > index 830e2f6c064a..f5f2b71c2fde 100644 > --- a/fs/xfs/xfs_buf.h > +++ b/fs/xfs/xfs_buf.h > @@ -347,6 +347,18 @@ extern void xfs_buf_terminate(void); > > void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref); > > +/* > + * If the buffer is already on the LRU, do nothing. Otherwise set the buffer > + * up with a reference count of 0 so it will be tossed from the cache when > + * released. > + */ > +static inline void xfs_buf_oneshot(struct xfs_buf *bp) > +{ > + if (!list_empty(&bp->b_lru) || atomic_read(&bp->b_lru_ref) > 1) > + return; > + atomic_set(&bp->b_lru_ref, 0); > +} > + > static inline int xfs_buf_ispinned(struct xfs_buf *bp) > { > return atomic_read(&bp->b_pin_count); > -- > 2.17.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, May 11, 2018 at 05:24:48PM -0700, Darrick J. Wong wrote: > On Sat, May 12, 2018 at 08:50:58AM +1000, Dave Chinner wrote: > > From: Dave Chinner <dchinner@redhat.com> > > > > For the new growfs work, we want to ensure that we serialise > > secondary superblock updates with other operations (e.g. scrub) > > correctly, but we don't want to cache the buffers for long term > > reuse. We need cached buffers for serialisation, however. > > > > To solve this, introduce a "oneshot" buffer which will be marshalled > > through the cache but then released once the last current reference > > goes away. If the buffer is already cached, then we ignore the > > "one-shot" behaviour and leave the buffer in the state it was prior > > to the one-shot command being run. This means we don't perturb > > either the working set or existing cached buffer state by a one-shot > > operation. > > > > Signed-Off-By: Dave Chinner <dchinner@redhat.com> > > Hmm, should the xfs_sb_read_secondary function in "xfs: superblock scrub > should use short-lived buffers" be calling this to set a zero lru_ref > instead of doing it directly? That's not yet merged, is it? I'm guessing that it all depends on what order everything gets merged - we can clean up all the loose ends once we get everything in? Cheers, Dave.
On Sat, May 12, 2018 at 12:06:06PM +1000, Dave Chinner wrote: > On Fri, May 11, 2018 at 05:24:48PM -0700, Darrick J. Wong wrote: > > On Sat, May 12, 2018 at 08:50:58AM +1000, Dave Chinner wrote: > > > From: Dave Chinner <dchinner@redhat.com> > > > > > > For the new growfs work, we want to ensure that we serialise > > > secondary superblock updates with other operations (e.g. scrub) > > > correctly, but we don't want to cache the buffers for long term > > > reuse. We need cached buffers for serialisation, however. > > > > > > To solve this, introduce a "oneshot" buffer which will be marshalled > > > through the cache but then released once the last current reference > > > goes away. If the buffer is already cached, then we ignore the > > > "one-shot" behaviour and leave the buffer in the state it was prior > > > to the one-shot command being run. This means we don't perturb > > > either the working set or existing cached buffer state by a one-shot > > > operation. > > > > > > Signed-Off-By: Dave Chinner <dchinner@redhat.com> > > > > Hmm, should the xfs_sb_read_secondary function in "xfs: superblock scrub > > should use short-lived buffers" be calling this to set a zero lru_ref > > instead of doing it directly? > > That's not yet merged, is it? I'm guessing that it all depends on > what order everything gets merged - we can clean up all the loose > ends once we get everything in? I... already have a series of cleanups to go in after online repair lands, so I don't mind tacking more on. 8-) --D > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 830e2f6c064a..f5f2b71c2fde 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -347,6 +347,18 @@ extern void xfs_buf_terminate(void); void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref); +/* + * If the buffer is already on the LRU, do nothing. Otherwise set the buffer + * up with a reference count of 0 so it will be tossed from the cache when + * released. + */ +static inline void xfs_buf_oneshot(struct xfs_buf *bp) +{ + if (!list_empty(&bp->b_lru) || atomic_read(&bp->b_lru_ref) > 1) + return; + atomic_set(&bp->b_lru_ref, 0); +} + static inline int xfs_buf_ispinned(struct xfs_buf *bp) { return atomic_read(&bp->b_pin_count);