From: Ryusuke Konishi <konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
To: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
Cc: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v5 5/6] nilfs-utils: add optimized version of nilfs_xreclaim_segments
Date: Fri, 07 Feb 2014 13:56:56 +0900 (JST) [thread overview]
Message-ID: <20140207.135656.15669706.konishi.ryusuke@lab.ntt.co.jp> (raw)
In-Reply-To: <a2aaefaedbeee6fd8727c2f3bfec5f2a0a048941.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
On Thu, 6 Feb 2014 15:17:25 +0100, Andreas Rohner wrote:
> This patch adds an additional parameter min_reclaimable_blks to
> the nilfs_reclaim_params structure. This parameter specifies the
> minimum number of reclaimable blocks in a segment, before it can be
> cleaned. If a segment is below this threshold, it is considered to
> be not worth cleaning, because all the live blocks would need to be
> moved to a new segment, which is expensive, and the number of
> reclaimable blocks is too low. But it is still necessary to update
> the segment usage information to turn the old segment into a new
> one.
>
> This is basically a shortcut to cleaning the segment. It is still
> necessary to read the segment summary information, but the writing
> of the live blocks can be skipped if it's not worth it.
>
> This optimization can be enabled and disabled by the
> use_set_suinfo switch in the configuration file. If the kernel
> doesn't support the set_suinfo ioctl it returns the error
> number ENOTTY, which also permanently disables the optimization.
>
> Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
> ---
> include/nilfs_gc.h | 11 ++++----
> lib/gc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++----
> sbin/cleanerd/cleanerd.c | 24 +++++++++++++---
> 3 files changed, 93 insertions(+), 15 deletions(-)
>
> diff --git a/include/nilfs_gc.h b/include/nilfs_gc.h
> index e49cbf4..8bd83d7 100644
> --- a/include/nilfs_gc.h
> +++ b/include/nilfs_gc.h
> @@ -15,20 +15,21 @@
> #include "nilfs.h"
>
> /* flags for nilfs_reclaim_params struct */
> -#define NILFS_RECLAIM_PARAM_PROTSEQ (1UL << 0)
> -#define NILFS_RECLAIM_PARAM_PROTCNO (1UL << 1)
> -#define __NR_NILFS_RECLAIM_PARAMS 2
> +#define NILFS_RECLAIM_PARAM_PROTSEQ (1UL << 0)
> +#define NILFS_RECLAIM_PARAM_PROTCNO (1UL << 1)
> +#define NILFS_RECLAIM_PARAM_MIN_RECLAIMABLE_BLKS (1UL << 2)
> +#define __NR_NILFS_RECLAIM_PARAMS 3
>
> /**
> * struct nilfs_reclaim_params - structure to specify GC parameters
> * @flags: flags of valid fields
> - * @reserved: padding bytes
> + * @min_reclaimable_blks: minimum number of reclaimable blocks
> * @protseq: start of sequence number of protected segments
> * @protcno: start number of checkpoint to be protected
> */
> struct nilfs_reclaim_params {
> unsigned long flags;
> - unsigned long reserved;
> + unsigned long min_reclaimable_blks;
> __u64 protseq;
> nilfs_cno_t protcno;
> };
> diff --git a/lib/gc.c b/lib/gc.c
> index 71c7307..5a1c2fe 100644
> --- a/lib/gc.c
> +++ b/lib/gc.c
> @@ -29,6 +29,10 @@
> #include <syslog.h>
> #endif /* HAVE_SYSLOG_H */
>
> +#if HAVE_SYS_TIME_H
> +#include <sys/time.h>
> +#endif /* HAVE_SYS_TIME */
> +
> #include <errno.h>
> #include <assert.h>
> #include <stdarg.h>
> @@ -614,11 +618,14 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
> const struct nilfs_reclaim_params *params,
> struct nilfs_reclaim_stat *stat)
> {
> - struct nilfs_vector *vdescv, *bdescv, *periodv, *vblocknrv;
> + struct nilfs_vector *vdescv, *bdescv, *periodv, *vblocknrv, *supv;
> sigset_t sigset, oldset, waitset;
> nilfs_cno_t protcno;
> - ssize_t n, ret = -1;
> + ssize_t n, i, ret = -1;
> size_t nblocks;
> + __u32 reclaimable_blocks;
> + struct nilfs_suinfo_update *sup;
> + struct timeval tv;
>
> if (!(params->flags & NILFS_RECLAIM_PARAM_PROTSEQ) ||
> (params->flags & (~0UL << __NR_NILFS_RECLAIM_PARAMS))) {
> @@ -637,7 +644,8 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
> bdescv = nilfs_vector_create(sizeof(struct nilfs_bdesc));
> periodv = nilfs_vector_create(sizeof(struct nilfs_period));
> vblocknrv = nilfs_vector_create(sizeof(__u64));
> - if (!vdescv || !bdescv || !periodv || !vblocknrv)
> + supv = nilfs_vector_create(sizeof(struct nilfs_suinfo_update));
> + if (!vdescv || !bdescv || !periodv || !vblocknrv || !supv)
> goto out_vec;
>
> sigemptyset(&sigset);
> @@ -703,13 +711,16 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
> if (ret < 0)
> goto out_lock;
>
> + reclaimable_blocks = (nilfs_get_blocks_per_segment(nilfs) * n) -
> + (nilfs_vector_get_size(vdescv) +
> + nilfs_vector_get_size(bdescv));
> +
> if (stat) {
> stat->live_pblks = nilfs_vector_get_size(bdescv);
> stat->defunct_pblks = nblocks - stat->live_pblks;
>
> stat->live_blks = stat->live_vblks + stat->live_pblks;
> - stat->defunct_blks = n * nilfs_get_blocks_per_segment(nilfs) -
> - stat->live_blks;
> + stat->defunct_blks = reclaimable_blocks;
> }
> if (dryrun)
> goto out_lock;
> @@ -725,6 +736,54 @@ int nilfs_xreclaim_segment(struct nilfs *nilfs,
> goto out_lock;
> }
>
> + /*
> + * if there are less reclaimable blocks than the minimal
> + * threshold try to update suinfo instead of cleaning
> + */
> + if ((params->flags & NILFS_RECLAIM_PARAM_MIN_RECLAIMABLE_BLKS) &&
> + reclaimable_blocks < params->min_reclaimable_blks * n) {
I think nilfs_opt_test_set_suinfo(nilfs) should be tested here instead
of the nilfs_cleanerd_clean_segments() side.
Later, I will fix it.
> + if (stat) {
> + stat->deferred_segs = n;
> + stat->cleaned_segs = 0;
> + }
> +
> + ret = gettimeofday(&tv, NULL);
> + if (ret < 0)
> + goto out_lock;
> +
> + for (i = 0; i < n; ++i) {
> + sup = nilfs_vector_get_new_element(supv);
> + if (!sup)
> + goto out_lock;
> +
> + sup->sup_segnum = segnums[i];
> + sup->sup_flags = 0;
> + nilfs_suinfo_update_set_lastmod(sup);
> + sup->sup_sui.sui_lastmod = tv.tv_sec;
> + }
> +
> + ret = nilfs_set_suinfo(nilfs, nilfs_vector_get_data(supv), n);
> +
> + if (ret == 0)
> + goto out_lock;
> +
> + if (ret < 0 && errno != ENOTTY) {
> + nilfs_gc_logger(LOG_ERR, "cannot set suinfo: %s",
> + strerror(errno));
> + goto out_lock;
> + }
> +
> + /* errno == ENOTTY */
> + nilfs_gc_logger(LOG_WARNING,
> + "set_suinfo ioctl is not supported");
> + nilfs_opt_clear_set_suinfo(nilfs);
> + if (stat) {
> + stat->deferred_segs = 0;
> + stat->cleaned_segs = n;
> + }
> + /* Try nilfs_clean_segments */
> + }
> +
> ret = nilfs_clean_segments(nilfs,
> nilfs_vector_get_data(vdescv),
> nilfs_vector_get_size(vdescv),
> @@ -759,6 +818,8 @@ out_vec:
> nilfs_vector_destroy(periodv);
> if (vblocknrv != NULL)
> nilfs_vector_destroy(vblocknrv);
> + if (supv != NULL)
> + nilfs_vector_destroy(supv);
> /*
> * Flags of valid fields in stat->exflags must be unset.
> */
> @@ -783,7 +844,7 @@ ssize_t nilfs_reclaim_segment(struct nilfs *nilfs,
>
> params.flags =
> NILFS_RECLAIM_PARAM_PROTSEQ | NILFS_RECLAIM_PARAM_PROTCNO;
> - params.reserved = 0;
> + params.min_reclaimable_blks = 0;
> params.protseq = protseq;
> params.protcno = protcno;
> memset(&stat, 0, sizeof(stat));
> diff --git a/sbin/cleanerd/cleanerd.c b/sbin/cleanerd/cleanerd.c
> index 2896af8..4c9f69b 100644
> --- a/sbin/cleanerd/cleanerd.c
> +++ b/sbin/cleanerd/cleanerd.c
> @@ -1376,7 +1376,7 @@ static void nilfs_cleanerd_progress(struct nilfs_cleanerd *cleanerd, int nsegs)
> static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd,
> __u64 *segnums, size_t nsegs,
> __u64 protseq, __u64 prottime,
> - size_t *ncleaned)
> + size_t *ndone)
> {
> struct nilfs_reclaim_params params;
> struct nilfs_reclaim_stat stat;
> @@ -1384,7 +1384,11 @@ static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd,
>
> params.flags =
> NILFS_RECLAIM_PARAM_PROTSEQ | NILFS_RECLAIM_PARAM_PROTCNO;
> - params.reserved = 0;
> + if (nilfs_opt_test_set_suinfo(cleanerd->nilfs))
> + params.flags |= NILFS_RECLAIM_PARAM_MIN_RECLAIMABLE_BLKS;
> +
> + params.min_reclaimable_blks =
> + nilfs_cleanerd_min_reclaimable_blocks(cleanerd);
> params.protseq = protseq;
>
> ret = nilfs_cnoconv_time2cno(cleanerd->cnoconv, prottime,
> @@ -1402,7 +1406,7 @@ static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd,
> if (errno == ENOMEM) {
> nilfs_cleanerd_reduce_ncleansegs_for_retry(cleanerd);
> cleanerd->fallback = 1;
> - *ncleaned = 0;
> + *ndone = 0;
> ret = 0;
> }
> goto out;
> @@ -1415,6 +1419,17 @@ static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd,
> nilfs_cleanerd_progress(cleanerd, stat.cleaned_segs);
> cleanerd->fallback = 0;
> cleanerd->retry_cleaning = 0;
> +
> + *ndone = stat.cleaned_segs;
> + } else if (stat.deferred_segs > 0) {
> + for (i = 0; i < stat.deferred_segs; i++)
> + syslog(LOG_DEBUG, "segment %llu deferred",
> + (unsigned long long)segnums[i]);
> + nilfs_cleanerd_progress(cleanerd, stat.deferred_segs);
> + cleanerd->fallback = 0;
> + cleanerd->retry_cleaning = 0;
> +
> + *ndone = stat.deferred_segs;
> } else {
> syslog(LOG_DEBUG, "no segments cleaned");
>
> @@ -1428,8 +1443,9 @@ static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd,
> } else {
> cleanerd->retry_cleaning = 0;
> }
> + *ndone = 0;
This condition judgment supposes that stat.deferred_segs and
stat.cleaned_segs are exclusive. It is correct in the current
implementation, but I don't want to define the semantics of
nilfs_xreclaim_segment() as such.
Can you rewrite this patch ?
Or, I will change this post handling.
> }
> - *ncleaned = stat.cleaned_segs;
> +
> out:
> return ret;
> }
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2014-02-07 4:56 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-06 14:17 [PATCH v5 0/6] nilfs-utils: shortcut for certain GC operations Andreas Rohner
[not found] ` <cover.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-06 14:17 ` [PATCH v5 1/6] nilfs-utils: cldconfig add an option to set min. reclaimable blocks Andreas Rohner
[not found] ` <d7f1a80dab87a673a1e32d789959374309b6d9e8.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-07 0:43 ` Ryusuke Konishi
2014-02-06 14:17 ` [PATCH v5 2/6] nilfs-utils: add NILFS_OPT_SET_SUINFO Andreas Rohner
[not found] ` <8f8e0f20685c057505ef3150398de39c8427d1ea.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-07 0:44 ` Ryusuke Konishi
2014-02-06 14:17 ` [PATCH v5 3/6] nilfs-utils: nilfs-clean add cmdline param min-reclaimable-blocks Andreas Rohner
[not found] ` <f93e550aaf08c0edaa6f04518ceb34b42975c839.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-07 1:43 ` Ryusuke Konishi
2014-02-06 14:17 ` [PATCH v5 4/6] nilfs-utils: add suport for NILFS_IOCTL_SET_SUINFO ioctl Andreas Rohner
2014-02-06 14:17 ` [PATCH v5 5/6] nilfs-utils: add optimized version of nilfs_xreclaim_segments Andreas Rohner
[not found] ` <a2aaefaedbeee6fd8727c2f3bfec5f2a0a048941.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-07 4:56 ` Ryusuke Konishi [this message]
[not found] ` <20140207.135656.15669706.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-02-07 5:34 ` Ryusuke Konishi
2014-02-06 14:17 ` [PATCH v5 6/6] nilfs-utils: add a no_timeout flag to enable faster loop Andreas Rohner
[not found] ` <c332aafb27e77cafc51f4bb6b6c7632290a5290d.1391692941.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-02-07 4:59 ` Ryusuke Konishi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140207.135656.15669706.konishi.ryusuke@lab.ntt.co.jp \
--to=konishi.ryusuke-zyj7fxus5i5l9jvzuh4aog@public.gmane.org \
--cc=andreas.rohner-hi6Y0CQ0nG0@public.gmane.org \
--cc=linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox