From: Keith Busch <kbusch@meta.com>
To: <fio@vger.kernel.org>
Cc: <axboe@kernel.dk>, <vincentfu@gmail.com>,
Keith Busch <kbusch@kernel.org>
Subject: [PATCH 1/3] eta: don't estimate runtime from an unset job epoch
Date: Thu, 3 Sep 2026 10:20:59 -0700 [thread overview]
Message-ID: <20260903172101.1886315-2-kbusch@meta.com> (raw)
In-Reply-To: <20260903172101.1886315-1-kbusch@meta.com>
From: Keith Busch <kbusch@kernel.org>
run_threads() moves a job from TD_INITIALIZED to TD_RUNNING and only
then releases it. The job itself doesn't call set_epoch_time() until
well into thread_main(), after exec_prerun, pre_read_files(),
fio_verify_init() and rate_submit_init() have run. Until that point
td->epoch is still zeroed, so the "elapsed" that thread_eta() derives
from it is the time since the unix epoch rather than the time this job
has been running.
Nothing currently notices, because the one consumer of elapsed that
could care wraps around on the unsigned subtraction, but it is a trap
for anyone using elapsed as a real number of seconds.
Take a local copy of the runstate and demote a TD_RUNNING or
TD_VERIFYING job whose epoch is not set yet to TD_CREATED, so it gets
estimated as a job that is still starting up.
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
eta.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/eta.c b/eta.c
index c6e3cffb..5dbf4d75 100644
--- a/eta.c
+++ b/eta.c
@@ -162,6 +162,16 @@ static unsigned long thread_eta(struct thread_data *td)
unsigned long eta_sec = 0;
unsigned long elapsed;
uint64_t timeout;
+ int runstate = td->runstate;
+
+ /*
+ * run_threads() moves a job to TD_RUNNING before the job itself has
+ * recorded its epoch, so elapsed is meaningless until then. Estimate
+ * such a job as if it were still starting up.
+ */
+ if (!td->epoch.tv_sec && !td->epoch.tv_nsec &&
+ (runstate == TD_RUNNING || runstate == TD_VERIFYING))
+ runstate = TD_CREATED;
elapsed = (mtime_since_now(&td->epoch) + 999) / 1000;
timeout = td->o.timeout / 1000000UL;
@@ -220,7 +230,7 @@ static unsigned long thread_eta(struct thread_data *td)
}
}
- if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING) {
+ if (runstate == TD_RUNNING || runstate == TD_VERIFYING) {
double perc, perc_t;
bytes_done = ddir_rw_sum(td->io_bytes);
@@ -256,11 +266,11 @@ static unsigned long thread_eta(struct thread_data *td)
if (td->o.timeout &&
eta_sec > (timeout + done_secs - elapsed))
eta_sec = timeout + done_secs - elapsed;
- } else if (td->runstate == TD_NOT_CREATED || td->runstate == TD_CREATED
- || td->runstate == TD_INITIALIZED
- || td->runstate == TD_SETTING_UP
- || td->runstate == TD_RAMP
- || td->runstate == TD_PRE_READING) {
+ } else if (runstate == TD_NOT_CREATED || runstate == TD_CREATED
+ || runstate == TD_INITIALIZED
+ || runstate == TD_SETTING_UP
+ || runstate == TD_RAMP
+ || runstate == TD_PRE_READING) {
int64_t t_eta = 0, r_eta = 0;
unsigned long long rate_bytes;
@@ -278,7 +288,7 @@ static unsigned long thread_eta(struct thread_data *td)
t_eta += ramp_time;
t_eta /= 1000000ULL;
- if ((td->runstate == TD_RAMP) && in_ramp_period(td)) {
+ if ((runstate == TD_RAMP) && in_ramp_period(td)) {
unsigned long ramp_left;
ramp_left = mtime_since_now(&td->epoch);
--
2.52.0
next prev parent reply other threads:[~2026-09-03 17:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 17:20 [PATCH 0/3] fio: fix eta Keith Busch
2026-09-03 17:20 ` Keith Busch [this message]
2026-09-09 17:01 ` [PATCH 1/3] eta: don't estimate runtime from an unset job epoch Vincent Fu
2026-09-09 20:15 ` Keith Busch
2026-09-03 17:21 ` [PATCH 2/3] eta: cap the ETA at the job's own remaining runtime Keith Busch
2026-09-03 17:21 ` [PATCH 3/3] eta: remove now unused done_secs Keith Busch
2026-09-03 20:01 ` [PATCH 0/3] fio: fix eta 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=20260903172101.1886315-2-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox