* [PATCH v5 0/6] speculative preallocation quota throttling
@ 2013-03-18 14:51 Brian Foster
2013-03-18 14:51 ` [PATCH v5 1/6] xfs: reorganize xfs_iomap_prealloc_size to remove indentation Brian Foster
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
Hi all,
Here is v5 of speculative prealloc. quota throttling. Sorry for the delay. This
is mostly a rebase. I'm running some quick xfstests tests since we've moved onto
3.9-rc1 now, but the only real merge conflict was inheritance of the infinite
loop alloc_blocks fix. Otherwise, this just includes some extra fixups to remove
dependence on typedef's of various functions we happen to modify.
Brian
v5:
- Rebased against current tree (3.9-rc1), incl. e78c420b.
- Added Mark's reviewed-by's.
- Removed use of typedef's in modified functions (affects patches 3 and 4).
v4:
- Drop patch 3/7 from v3 (xfs: cap prealloc size to free space before shift).
- Several updates to patch 4/6:
- Rename xfs_dquot_init_prealloc() to xfs_dquot_set_prealloc_limits().
- Unroll the prealloc threshold loop and remove the increment def.
- Fix up some comments.
v3:
- Rebased on top of updated speculative preallocation algorithm.
v2:
- Fix up xfs_iomap_prealloc_size() rounding (patch 2).
- Add pre-calculated fields to xfs_dquot to support throttling.
- Move to logarithmic (shift) throttler and finer tuned trigger/throttle logic.
Brian Foster (6):
xfs: reorganize xfs_iomap_prealloc_size to remove indentation
xfs: push rounddown_pow_of_two() to after prealloc throttle
xfs: pass xfs_dquot to xfs_qm_adjust_dqlimits() instead of
xfs_disk_dquot_t
xfs: xfs_dquot prealloc throttling watermarks and low free space
xfs: add quota-driven speculative preallocation throttling
xfs: xfs_iomap_prealloc_size() tracepoint
fs/xfs/xfs_dquot.c | 48 ++++++++++++--
fs/xfs/xfs_dquot.h | 16 ++++-
fs/xfs/xfs_iomap.c | 161 +++++++++++++++++++++++++++++++++++++---------
fs/xfs/xfs_qm.c | 2 +-
fs/xfs/xfs_qm.h | 2 +-
fs/xfs/xfs_qm_syscalls.c | 9 ++-
fs/xfs/xfs_trace.h | 24 +++++++
fs/xfs/xfs_trans_dquot.c | 10 ++--
8 files changed, 224 insertions(+), 48 deletions(-)
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v5 1/6] xfs: reorganize xfs_iomap_prealloc_size to remove indentation
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-18 14:51 ` [PATCH v5 2/6] xfs: push rounddown_pow_of_two() to after prealloc throttle Brian Foster
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
The majority of xfs_iomap_prealloc_size() executes within the
check for lack of default I/O size. Reverse the logic to remove the
extra indentation.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_iomap.c | 63 ++++++++++++++++++++++++++-------------------------
1 files changed, 32 insertions(+), 31 deletions(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index c8cb337..344557e 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -381,42 +381,43 @@ xfs_iomap_prealloc_size(
int nimaps)
{
xfs_fsblock_t alloc_blocks = 0;
+ int shift = 0;
+ int64_t freesp;
alloc_blocks = xfs_iomap_eof_prealloc_initial_size(mp, ip, offset,
imap, nimaps);
- if (alloc_blocks > 0) {
- int shift = 0;
- int64_t freesp;
-
- alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN,
- rounddown_pow_of_two(alloc_blocks));
-
- xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
- freesp = mp->m_sb.sb_fdblocks;
- if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) {
- shift = 2;
- if (freesp < mp->m_low_space[XFS_LOWSP_4_PCNT])
- shift++;
- if (freesp < mp->m_low_space[XFS_LOWSP_3_PCNT])
- shift++;
- if (freesp < mp->m_low_space[XFS_LOWSP_2_PCNT])
- shift++;
- if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT])
- shift++;
- }
- if (shift)
- alloc_blocks >>= shift;
-
- /*
- * If we are still trying to allocate more space than is
- * available, squash the prealloc hard. This can happen if we
- * have a large file on a small filesystem and the above
- * lowspace thresholds are smaller than MAXEXTLEN.
- */
- while (alloc_blocks && alloc_blocks >= freesp)
- alloc_blocks >>= 4;
+ if (!alloc_blocks)
+ goto check_writeio;
+
+ alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN,
+ rounddown_pow_of_two(alloc_blocks));
+
+ xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
+ freesp = mp->m_sb.sb_fdblocks;
+ if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) {
+ shift = 2;
+ if (freesp < mp->m_low_space[XFS_LOWSP_4_PCNT])
+ shift++;
+ if (freesp < mp->m_low_space[XFS_LOWSP_3_PCNT])
+ shift++;
+ if (freesp < mp->m_low_space[XFS_LOWSP_2_PCNT])
+ shift++;
+ if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT])
+ shift++;
}
+ if (shift)
+ alloc_blocks >>= shift;
+
+ /*
+ * If we are still trying to allocate more space than is
+ * available, squash the prealloc hard. This can happen if we
+ * have a large file on a small filesystem and the above
+ * lowspace thresholds are smaller than MAXEXTLEN.
+ */
+ while (alloc_blocks && alloc_blocks >= freesp)
+ alloc_blocks >>= 4;
+check_writeio:
if (alloc_blocks < mp->m_writeio_blocks)
alloc_blocks = mp->m_writeio_blocks;
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 2/6] xfs: push rounddown_pow_of_two() to after prealloc throttle
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
2013-03-18 14:51 ` [PATCH v5 1/6] xfs: reorganize xfs_iomap_prealloc_size to remove indentation Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-18 14:51 ` [PATCH v5 3/6] xfs: pass xfs_dquot to xfs_qm_adjust_dqlimits() instead of xfs_disk_dquot_t Brian Foster
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
The round down occurs towards the beginning of the function. Push
it down after throttling has occurred. This is to support adding
further transformations to 'alloc_blocks' that might not preserve
power-of-two alignment (and thus could lead to rounding down
multiple times).
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_iomap.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 344557e..9072794 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -389,8 +389,15 @@ xfs_iomap_prealloc_size(
if (!alloc_blocks)
goto check_writeio;
- alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN,
- rounddown_pow_of_two(alloc_blocks));
+ /*
+ * MAXEXTLEN is not a power of two value but we round the prealloc down
+ * to the nearest power of two value after throttling. To prevent the
+ * round down from unconditionally reducing the maximum supported prealloc
+ * size, we round up first, apply appropriate throttling, round down and
+ * cap the value to MAXEXTLEN.
+ */
+ alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(MAXEXTLEN),
+ alloc_blocks);
xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
freesp = mp->m_sb.sb_fdblocks;
@@ -407,6 +414,14 @@ xfs_iomap_prealloc_size(
}
if (shift)
alloc_blocks >>= shift;
+ /*
+ * rounddown_pow_of_two() returns an undefined result if we pass in
+ * alloc_blocks = 0.
+ */
+ if (alloc_blocks)
+ alloc_blocks = rounddown_pow_of_two(alloc_blocks);
+ if (alloc_blocks > MAXEXTLEN)
+ alloc_blocks = MAXEXTLEN;
/*
* If we are still trying to allocate more space than is
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 3/6] xfs: pass xfs_dquot to xfs_qm_adjust_dqlimits() instead of xfs_disk_dquot_t
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
2013-03-18 14:51 ` [PATCH v5 1/6] xfs: reorganize xfs_iomap_prealloc_size to remove indentation Brian Foster
2013-03-18 14:51 ` [PATCH v5 2/6] xfs: push rounddown_pow_of_two() to after prealloc throttle Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-18 14:51 ` [PATCH v5 4/6] xfs: xfs_dquot prealloc throttling watermarks and low free space Brian Foster
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
Modify xfs_qm_adjust_dqlimits() to take the xfs_dquot as a
parameter instead of just the xfs_disk_dquot_t so we can update
in-memory fields if necessary.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_dquot.c | 7 ++++---
fs/xfs/xfs_dquot.h | 4 ++--
fs/xfs/xfs_qm.c | 2 +-
fs/xfs/xfs_trans_dquot.c | 10 +++++-----
4 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 8025eb2..9c5869e 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -85,10 +85,11 @@ xfs_qm_dqdestroy(
*/
void
xfs_qm_adjust_dqlimits(
- xfs_mount_t *mp,
- xfs_disk_dquot_t *d)
+ struct xfs_mount *mp,
+ struct xfs_dquot *dq)
{
- xfs_quotainfo_t *q = mp->m_quotainfo;
+ struct xfs_quotainfo *q = mp->m_quotainfo;
+ struct xfs_disk_dquot *d = &dq->q_core;
ASSERT(d->d_id);
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index c694a84..f77b711 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -145,8 +145,8 @@ extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **);
extern void xfs_qm_dqunpin_wait(xfs_dquot_t *);
extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
xfs_disk_dquot_t *);
-extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
- xfs_disk_dquot_t *);
+extern void xfs_qm_adjust_dqlimits(struct xfs_mount *,
+ struct xfs_dquot *);
extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
xfs_dqid_t, uint, uint, xfs_dquot_t **);
extern void xfs_qm_dqput(xfs_dquot_t *);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index e5b5cf9..d0acb4e 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1057,7 +1057,7 @@ xfs_qm_quotacheck_dqadjust(
* There are no timers for the default values set in the root dquot.
*/
if (dqp->q_core.d_id) {
- xfs_qm_adjust_dqlimits(mp, &dqp->q_core);
+ xfs_qm_adjust_dqlimits(mp, dqp);
xfs_qm_adjust_dqtimers(mp, &dqp->q_core);
}
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 642c2d6..fec75d0 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -326,12 +326,12 @@ xfs_trans_dqlockedjoin(
*/
void
xfs_trans_apply_dquot_deltas(
- xfs_trans_t *tp)
+ struct xfs_trans *tp)
{
int i, j;
- xfs_dquot_t *dqp;
- xfs_dqtrx_t *qtrx, *qa;
- xfs_disk_dquot_t *d;
+ struct xfs_dquot *dqp;
+ struct xfs_dqtrx *qtrx, *qa;
+ struct xfs_disk_dquot *d;
long totalbdelta;
long totalrtbdelta;
@@ -412,7 +412,7 @@ xfs_trans_apply_dquot_deltas(
* Start/reset the timer(s) if needed.
*/
if (d->d_id) {
- xfs_qm_adjust_dqlimits(tp->t_mountp, d);
+ xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
xfs_qm_adjust_dqtimers(tp->t_mountp, d);
}
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 4/6] xfs: xfs_dquot prealloc throttling watermarks and low free space
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
` (2 preceding siblings ...)
2013-03-18 14:51 ` [PATCH v5 3/6] xfs: pass xfs_dquot to xfs_qm_adjust_dqlimits() instead of xfs_disk_dquot_t Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-18 14:51 ` [PATCH v5 5/6] xfs: add quota-driven speculative preallocation throttling Brian Foster
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
Enable tracking of high and low watermarks for preallocation
throttling of files under quota restrictions. These values are
calculated when the quota limit is read from disk or modified and
cached for later use by the throttling algorithm.
The high watermark specifies when preallocation is disabled, the
low watermark specifies when throttling is enabled and the low free
space data structure contains precalculated low free space limits
to serve as input to determine the level of throttling required.
Note that the low free space data structure is based on the
existing global low free space data structure with the exception of
using three stages (5%, 3% and 1%) rather than five to reduce the
impact of xfs_dquot memory overhead.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_dquot.c | 41 +++++++++++++++++++++++++++++++++++++++--
fs/xfs/xfs_dquot.h | 12 ++++++++++++
fs/xfs/xfs_qm.h | 2 +-
fs/xfs/xfs_qm_syscalls.c | 9 +++++----
4 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 9c5869e..45bb08f 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -90,13 +90,18 @@ xfs_qm_adjust_dqlimits(
{
struct xfs_quotainfo *q = mp->m_quotainfo;
struct xfs_disk_dquot *d = &dq->q_core;
+ int prealloc = 0;
ASSERT(d->d_id);
- if (q->qi_bsoftlimit && !d->d_blk_softlimit)
+ if (q->qi_bsoftlimit && !d->d_blk_softlimit) {
d->d_blk_softlimit = cpu_to_be64(q->qi_bsoftlimit);
- if (q->qi_bhardlimit && !d->d_blk_hardlimit)
+ prealloc = 1;
+ }
+ if (q->qi_bhardlimit && !d->d_blk_hardlimit) {
d->d_blk_hardlimit = cpu_to_be64(q->qi_bhardlimit);
+ prealloc = 1;
+ }
if (q->qi_isoftlimit && !d->d_ino_softlimit)
d->d_ino_softlimit = cpu_to_be64(q->qi_isoftlimit);
if (q->qi_ihardlimit && !d->d_ino_hardlimit)
@@ -105,6 +110,9 @@ xfs_qm_adjust_dqlimits(
d->d_rtb_softlimit = cpu_to_be64(q->qi_rtbsoftlimit);
if (q->qi_rtbhardlimit && !d->d_rtb_hardlimit)
d->d_rtb_hardlimit = cpu_to_be64(q->qi_rtbhardlimit);
+
+ if (prealloc)
+ xfs_dquot_set_prealloc_limits(dq);
}
/*
@@ -249,6 +257,32 @@ xfs_qm_init_dquot_blk(
xfs_trans_log_buf(tp, bp, 0, BBTOB(q->qi_dqchunklen) - 1);
}
+/*
+ * Initialize the dynamic speculative preallocation thresholds. The lo/hi
+ * watermarks correspond to the soft and hard limits by default. If a soft limit
+ * is not specified, we use 95% of the hard limit.
+ */
+void
+xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
+{
+ __uint64_t space;
+
+ dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
+ dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
+ if (!dqp->q_prealloc_lo_wmark) {
+ dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
+ do_div(dqp->q_prealloc_lo_wmark, 100);
+ dqp->q_prealloc_lo_wmark *= 95;
+ }
+
+ space = dqp->q_prealloc_hi_wmark;
+
+ do_div(space, 100);
+ dqp->q_low_space[XFS_QLOWSP_1_PCNT] = space;
+ dqp->q_low_space[XFS_QLOWSP_3_PCNT] = space * 3;
+ dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
+}
+
static void
xfs_dquot_buf_verify(
struct xfs_buf *bp)
@@ -649,6 +683,9 @@ xfs_qm_dqread(
dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);
+ /* initialize the dquot speculative prealloc thresholds */
+ xfs_dquot_set_prealloc_limits(dqp);
+
/* Mark the buf so that this will stay incore a little longer */
xfs_buf_set_ref(bp, XFS_DQUOT_REF);
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index f77b711..4f0ebfc 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -32,6 +32,13 @@
struct xfs_mount;
struct xfs_trans;
+enum {
+ XFS_QLOWSP_1_PCNT = 0,
+ XFS_QLOWSP_3_PCNT,
+ XFS_QLOWSP_5_PCNT,
+ XFS_QLOWSP_MAX
+};
+
/*
* The incore dquot structure
*/
@@ -51,6 +58,9 @@ typedef struct xfs_dquot {
xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */
xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */
xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */
+ xfs_qcnt_t q_prealloc_lo_wmark;/* prealloc throttle wmark */
+ xfs_qcnt_t q_prealloc_hi_wmark;/* prealloc disabled wmark */
+ int64_t q_low_space[XFS_QLOWSP_MAX];
struct mutex q_qlock; /* quota lock */
struct completion q_flush; /* flush completion queue */
atomic_t q_pincount; /* dquot pin count */
@@ -153,6 +163,8 @@ extern void xfs_qm_dqput(xfs_dquot_t *);
extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
+extern void xfs_dquot_set_prealloc_limits(struct xfs_dquot *);
+
static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
{
xfs_dqlock(dqp);
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 44b858b..82c2108 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -116,7 +116,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
fs_disk_quota_t *);
-extern int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
+extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
fs_disk_quota_t *);
extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index cf9a340..c41190c 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -472,15 +472,15 @@ xfs_qm_scall_getqstat(
*/
int
xfs_qm_scall_setqlim(
- xfs_mount_t *mp,
+ struct xfs_mount *mp,
xfs_dqid_t id,
uint type,
fs_disk_quota_t *newlim)
{
struct xfs_quotainfo *q = mp->m_quotainfo;
- xfs_disk_dquot_t *ddq;
- xfs_dquot_t *dqp;
- xfs_trans_t *tp;
+ struct xfs_disk_dquot *ddq;
+ struct xfs_dquot *dqp;
+ struct xfs_trans *tp;
int error;
xfs_qcnt_t hard, soft;
@@ -529,6 +529,7 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
ddq->d_blk_hardlimit = cpu_to_be64(hard);
ddq->d_blk_softlimit = cpu_to_be64(soft);
+ xfs_dquot_set_prealloc_limits(dqp);
if (id == 0) {
q->qi_bhardlimit = hard;
q->qi_bsoftlimit = soft;
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 5/6] xfs: add quota-driven speculative preallocation throttling
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
` (3 preceding siblings ...)
2013-03-18 14:51 ` [PATCH v5 4/6] xfs: xfs_dquot prealloc throttling watermarks and low free space Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-18 14:51 ` [PATCH v5 6/6] xfs: xfs_iomap_prealloc_size() tracepoint Brian Foster
2013-03-22 23:17 ` [PATCH v5 0/6] speculative preallocation quota throttling Ben Myers
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
Introduce the need_throttle() and calc_throttle() functions to
independently check whether throttling is required for a particular
dquot and if so, calculate the associated throttling metrics based
on the state of the quota. We use the same general algorithm to
calculate the throttle shift as for global free space with the
exception of using three stages rather than five.
Update xfs_iomap_prealloc_size() to use the smallest available
prealloc size based on each of the constraints and apply the
maximum shift to obtain the throttled preallocation size.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_iomap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 82 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 9072794..0a53085 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -42,6 +42,8 @@
#include "xfs_iomap.h"
#include "xfs_trace.h"
#include "xfs_icache.h"
+#include "xfs_dquot_item.h"
+#include "xfs_dquot.h"
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
@@ -366,6 +368,61 @@ xfs_iomap_eof_prealloc_initial_size(
return XFS_B_TO_FSB(mp, offset);
}
+STATIC bool
+xfs_quota_need_throttle(
+ struct xfs_inode *ip,
+ int type,
+ xfs_fsblock_t alloc_blocks)
+{
+ struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
+
+ if (!dq || !xfs_this_quota_on(ip->i_mount, type))
+ return false;
+
+ /* no hi watermark, no throttle */
+ if (!dq->q_prealloc_hi_wmark)
+ return false;
+
+ /* under the lo watermark, no throttle */
+ if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark)
+ return false;
+
+ return true;
+}
+
+STATIC void
+xfs_quota_calc_throttle(
+ struct xfs_inode *ip,
+ int type,
+ xfs_fsblock_t *qblocks,
+ int *qshift)
+{
+ int64_t freesp;
+ int shift = 0;
+ struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
+
+ /* over hi wmark, squash the prealloc completely */
+ if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
+ *qblocks = 0;
+ return;
+ }
+
+ freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount;
+ if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
+ shift = 2;
+ if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
+ shift += 2;
+ if (freesp < dq->q_low_space[XFS_QLOWSP_1_PCNT])
+ shift += 2;
+ }
+
+ /* only overwrite the throttle values if we are more aggressive */
+ if ((freesp >> shift) < (*qblocks >> *qshift)) {
+ *qblocks = freesp;
+ *qshift = shift;
+ }
+}
+
/*
* If we don't have a user specified preallocation size, dynamically increase
* the preallocation size as the size of the file grows. Cap the maximum size
@@ -383,11 +440,14 @@ xfs_iomap_prealloc_size(
xfs_fsblock_t alloc_blocks = 0;
int shift = 0;
int64_t freesp;
+ xfs_fsblock_t qblocks;
+ int qshift = 0;
alloc_blocks = xfs_iomap_eof_prealloc_initial_size(mp, ip, offset,
imap, nimaps);
if (!alloc_blocks)
goto check_writeio;
+ qblocks = alloc_blocks;
/*
* MAXEXTLEN is not a power of two value but we round the prealloc down
@@ -412,6 +472,28 @@ xfs_iomap_prealloc_size(
if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT])
shift++;
}
+
+ /*
+ * Check each quota to cap the prealloc size and provide a shift
+ * value to throttle with.
+ */
+ if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks))
+ xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift);
+ if (xfs_quota_need_throttle(ip, XFS_DQ_GROUP, alloc_blocks))
+ xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift);
+ if (xfs_quota_need_throttle(ip, XFS_DQ_PROJ, alloc_blocks))
+ xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift);
+
+ /*
+ * The final prealloc size is set to the minimum of free space available
+ * in each of the quotas and the overall filesystem.
+ *
+ * The shift throttle value is set to the maximum value as determined by
+ * the global low free space values and per-quota low free space values.
+ */
+ alloc_blocks = MIN(alloc_blocks, qblocks);
+ shift = MAX(shift, qshift);
+
if (shift)
alloc_blocks >>= shift;
/*
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 6/6] xfs: xfs_iomap_prealloc_size() tracepoint
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
` (4 preceding siblings ...)
2013-03-18 14:51 ` [PATCH v5 5/6] xfs: add quota-driven speculative preallocation throttling Brian Foster
@ 2013-03-18 14:51 ` Brian Foster
2013-03-22 23:17 ` [PATCH v5 0/6] speculative preallocation quota throttling Ben Myers
6 siblings, 0 replies; 8+ messages in thread
From: Brian Foster @ 2013-03-18 14:51 UTC (permalink / raw)
To: xfs
Add a tracepoint to provide some feedback on preallocation size
calculation.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
fs/xfs/xfs_iomap.c | 3 +++
fs/xfs/xfs_trace.h | 24 ++++++++++++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 0a53085..8f8aaee 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -518,6 +518,9 @@ check_writeio:
if (alloc_blocks < mp->m_writeio_blocks)
alloc_blocks = mp->m_writeio_blocks;
+ trace_xfs_iomap_prealloc_size(ip, alloc_blocks, shift,
+ mp->m_writeio_blocks);
+
return alloc_blocks;
}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 16a8129..aa4db33 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -619,6 +619,30 @@ DECLARE_EVENT_CLASS(xfs_iref_class,
(char *)__entry->caller_ip)
)
+TRACE_EVENT(xfs_iomap_prealloc_size,
+ TP_PROTO(struct xfs_inode *ip, xfs_fsblock_t blocks, int shift,
+ unsigned int writeio_blocks),
+ TP_ARGS(ip, blocks, shift, writeio_blocks),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(xfs_ino_t, ino)
+ __field(xfs_fsblock_t, blocks)
+ __field(int, shift)
+ __field(unsigned int, writeio_blocks)
+ ),
+ TP_fast_assign(
+ __entry->dev = VFS_I(ip)->i_sb->s_dev;
+ __entry->ino = ip->i_ino;
+ __entry->blocks = blocks;
+ __entry->shift = shift;
+ __entry->writeio_blocks = writeio_blocks;
+ ),
+ TP_printk("dev %d:%d ino 0x%llx prealloc blocks %llu shift %d "
+ "m_writeio_blocks %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino,
+ __entry->blocks, __entry->shift, __entry->writeio_blocks)
+)
+
#define DEFINE_IREF_EVENT(name) \
DEFINE_EVENT(xfs_iref_class, name, \
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/6] speculative preallocation quota throttling
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
` (5 preceding siblings ...)
2013-03-18 14:51 ` [PATCH v5 6/6] xfs: xfs_iomap_prealloc_size() tracepoint Brian Foster
@ 2013-03-22 23:17 ` Ben Myers
6 siblings, 0 replies; 8+ messages in thread
From: Ben Myers @ 2013-03-22 23:17 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
Brian,
On Mon, Mar 18, 2013 at 10:51:42AM -0400, Brian Foster wrote:
> Here is v5 of speculative prealloc. quota throttling. Sorry for the delay. This
> is mostly a rebase. I'm running some quick xfstests tests since we've moved onto
> 3.9-rc1 now, but the only real merge conflict was inheritance of the infinite
> loop alloc_blocks fix. Otherwise, this just includes some extra fixups to remove
> dependence on typedef's of various functions we happen to modify.
Applied this series.
Regards,
Ben
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-03-22 23:17 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-18 14:51 [PATCH v5 0/6] speculative preallocation quota throttling Brian Foster
2013-03-18 14:51 ` [PATCH v5 1/6] xfs: reorganize xfs_iomap_prealloc_size to remove indentation Brian Foster
2013-03-18 14:51 ` [PATCH v5 2/6] xfs: push rounddown_pow_of_two() to after prealloc throttle Brian Foster
2013-03-18 14:51 ` [PATCH v5 3/6] xfs: pass xfs_dquot to xfs_qm_adjust_dqlimits() instead of xfs_disk_dquot_t Brian Foster
2013-03-18 14:51 ` [PATCH v5 4/6] xfs: xfs_dquot prealloc throttling watermarks and low free space Brian Foster
2013-03-18 14:51 ` [PATCH v5 5/6] xfs: add quota-driven speculative preallocation throttling Brian Foster
2013-03-18 14:51 ` [PATCH v5 6/6] xfs: xfs_iomap_prealloc_size() tracepoint Brian Foster
2013-03-22 23:17 ` [PATCH v5 0/6] speculative preallocation quota throttling Ben Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox