On Thu, 6 Feb 2014 15:17:26 +0100, Andreas Rohner wrote: > This patch adds a flag, that enables the GC to skip the timeout in > certain situations. For example if the cleaning of some segments > was deferred to a later time, then no real progress has been > made. Apart from reading a few summary blocks, no data was read or > written to disk. In this situation it makes sense to skip the > normal timeout once and immediately try to clean the next set of > segments. > > Unfortunately it is not possible, to directly continue the cleaning > loop, because this would lead to an unresponsive GC process. > Therefore the timeout is simply set to 0 seconds. > > Signed-off-by: Andreas Rohner <andreas.rohner@xxxxxxx> > --- > sbin/cleanerd/cleanerd.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/sbin/cleanerd/cleanerd.c b/sbin/cleanerd/cleanerd.c > index 4c9f69b..3506c20 100644 > --- a/sbin/cleanerd/cleanerd.c > +++ b/sbin/cleanerd/cleanerd.c > @@ -141,6 +141,7 @@ const static struct option long_option[] = { > * @running: running state > * @fallback: fallback state > * @retry_cleaning: retrying reclamation for protected segments > + * @no_timeout: the next timeout will be 0 seconds > * @ncleansegs: number of semgents cleaned per cycle > * @cleaning_interval: cleaning interval > * @target: target time for sleeping > @@ -169,6 +170,7 @@ struct nilfs_cleanerd { > int running; > int fallback; > int retry_cleaning; > + int no_timeout; > int shutdown; > long ncleansegs; > struct timeval cleaning_interval; > @@ -896,7 +898,7 @@ static int nilfs_cleanerd_recalc_interval(struct nilfs_cleanerd *cleanerd, > interval = nilfs_cleanerd_cleaning_interval(cleanerd); > /* timercmp() does not work for '>=' or '<='. */ > /* curr >= target */ > - if (!timercmp(&curr, &cleanerd->target, <)) { > + if (!timercmp(&curr, &cleanerd->target, <) || cleanerd->no_timeout) { > cleanerd->timeout.tv_sec = 0; > cleanerd->timeout.tv_usec = 0; > timeradd(&curr, interval, &cleanerd->target); > @@ -1428,6 +1430,7 @@ static int nilfs_cleanerd_clean_segments(struct nilfs_cleanerd *cleanerd, > nilfs_cleanerd_progress(cleanerd, stat.deferred_segs); > cleanerd->fallback = 0; > cleanerd->retry_cleaning = 0; > + cleanerd->no_timeout = 1; > > *ndone = stat.deferred_segs; > } else { > @@ -1501,6 +1504,8 @@ static int nilfs_cleanerd_clean_loop(struct nilfs_cleanerd *cleanerd) > nilfs_cleanerd_clean_check_pause(cleanerd); > > while (!cleanerd->shutdown) { > + cleanerd->no_timeout = 0; > + > if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) { > syslog(LOG_ERR, "cannot set signal mask: %m"); > return -1; > -- > 1.8.5.3 This one looks good to me. Regards, Ryusuke Konishi -- To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html