From: Keith Busch <kbusch@meta.com>
To: <fio@vger.kernel.org>
Cc: <axboe@kernel.dk>, <vincentfu@gmail.com>,
Keith Busch <kbusch@kernel.org>
Subject: [PATCHv2 3/4] eta: cap the ETA at the job's own remaining runtime
Date: Thu, 10 Sep 2026 09:13:09 -0700 [thread overview]
Message-ID: <20260910161310.1478081-4-kbusch@meta.com> (raw)
In-Reply-To: <20260910161310.1478081-1-kbusch@meta.com>
From: Keith Busch <kbusch@kernel.org>
The ETA of a running job is capped at "timeout + done_secs - elapsed".
done_secs is a global accumulator of the runtime of every job reaped so
far, so the cap grows every time a job finishes. Whenever the cap is
what actually gets reported, the ETA jumps back up by the runtime of
everything that has already completed.
The cap is what gets reported when the progress based estimate exceeds
the remaining runtime, that is when perc is below elapsed/timeout. Any
job that is behind on bytes relative to its runtime is in that state,
so this covers the common "size the job to the whole device, bound it
with runtime" pattern. A job that would complete its size early stays
at or above elapsed/timeout and never reaches the cap.
time_based makes no difference either way. It only lowers perc to
min(perc, elapsed/timeout), so a time_based job that cannot finish its
size within the runtime is affected exactly like a size based one.
It is most visible with stonewalled jobs, where the ETA climbs back to
the full run time at every batch boundary instead of counting down:
fio --name=global --filename=/dev/zero --runtime=5 --size=10T \
--stonewall --name=a --name=b --name=c --name=d --name=e
before: 22 21 20 24 23 22 21 20 24 23 22 21 20 24 ...
after: 22 21 20 19 18 17 16 15 14 13 ... 02 01 00
Shrinking size until the jobs complete it within the runtime makes the
symptom disappear, which is a good way to confirm the cap is what is
being reported.
It is not specific to stonewall. Two concurrent jobs with runtime=5 and
runtime=20 show the same jump when the short one is reaped at t=5.
done_secs made sense when it was introduced: thread_eta() was handed
the global elapsed time back then, so "timeout + done_secs" was this
job's projected finish time relative to the start of the whole run.
b29ee5b3 switched elapsed to be per job, measured from td->epoch, but
left the done_secs term behind.
A job is terminated once utime_since(&td->epoch, now) reaches
td->o.timeout, so with a per job elapsed the cap is simply
"timeout - elapsed". Use that, and clamp at zero instead of relying on
the unsigned subtraction wrapping.
Fixes: b29ee5b3dee4 ("Update ramp_time")
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
eta.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/eta.c b/eta.c
index 70efc208..d17b8c3f 100644
--- a/eta.c
+++ b/eta.c
@@ -253,9 +253,18 @@ static unsigned long thread_eta(struct thread_data *td)
eta_sec = (unsigned long) (elapsed * (1.0 / perc)) - elapsed;
}
- if (td->o.timeout &&
- eta_sec > (timeout + done_secs - elapsed))
- eta_sec = timeout + done_secs - elapsed;
+ /*
+ * A job never runs for longer than its own timeout, which is
+ * measured from its own epoch. Cap the estimate at whatever
+ * time this job has left.
+ */
+ if (td->o.timeout) {
+ unsigned long timeout_left;
+
+ timeout_left = timeout > elapsed ? timeout - elapsed : 0;
+ if (eta_sec > timeout_left)
+ eta_sec = timeout_left;
+ }
} else if (td->runstate == TD_NOT_CREATED || td->runstate == TD_CREATED
|| td->runstate == TD_INITIALIZED
|| td->runstate == TD_SETTING_UP
--
2.53.0-Meta
next prev parent reply other threads:[~2026-09-10 16:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 16:13 [PATCHv2 0/4] fio: fix eta Keith Busch
2026-09-10 16:13 ` [PATCHv2 1/4] eta: count a job that is setting up as running Keith Busch
2026-09-10 16:13 ` [PATCHv2 2/4] backend: don't mark a job as running before it has set up Keith Busch
2026-09-11 19:49 ` Vincent Fu
2026-09-10 16:13 ` Keith Busch [this message]
2026-09-10 16:13 ` [PATCHv2 4/4] eta: remove now unused done_secs Keith Busch
2026-09-11 19:45 ` [PATCHv2 0/4] fio: fix eta Vincent Fu
2026-09-11 21:09 ` fiotestbot
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=20260910161310.1478081-4-kbusch@meta.com \
--to=kbusch@meta.com \
--cc=axboe@kernel.dk \
--cc=fio@vger.kernel.org \
--cc=kbusch@kernel.org \
--cc=vincentfu@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.