logging: expand runstates eligible for logging
authorVincent Fu <vincent.fu@samsung.com>
Wed, 24 Jan 2024 17:41:16 +0000 (17:41 +0000)
committerVincent Fu <vincent.fu@samsung.com>
Tue, 13 Feb 2024 16:44:43 +0000 (11:44 -0500)
Currently recording log entries for IOPS and BW logging with
log_avg_msec enabled only happens when a thread has completed its ramp
time and is in the TD_RUNNING or TD_VERIFYING run states.

It may happen that a final bandwidth or IOPS log entry is missed
when a job transitions from TD_RUNNING/TD_VERIFYING to TD_FINISHING
before the helper thread has a chance to calculate a final log entry.

This patch expands the run states where logging is permitted, allowing
log entries to be recorded for jobs in the TD_FINISHING or TD_EXITED
states. Each job cleans itself up and typically transitions quickly from
TD_FINISHING to TD_EXITED. The main fio backend thread carries out the
transition from TD_EXITED to TD_REAPED.

The window during which a job is in the TD_FINISHING and TD_EXITED
states is short, so measurements should still be reasonablly accurate.

I tested these patches with the following job:

fio --name=test --ioengine=null --time_based --runtime=3s --filesize=1T \
  --write_iops_log=test --write_bw_log=test --log_avg_msec=1000 \
  && cat test_iops.1.log && cat test_bw.1.log

Before this patch series 10/10 trials had missing log entries. With only
the helper_thread change in the preceding patch 3/10 trials had missing
log entries. With this entire patch series, only 1/10 trials had missing
log entries.

Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
stat.c

diff --git a/stat.c b/stat.c
index ab901ecd718ac2bb5c904a905afc43b0587fd7bb..b98e8b27c3b0a70b2cb220411406665ac96d68f5 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -3576,6 +3576,22 @@ static int add_iops_samples(struct thread_data *td, struct timespec *t)
                                td->ts.iops_stat, td->iops_log, false);
 }
 
+static bool td_in_logging_state(struct thread_data *td)
+{
+       if (in_ramp_time(td))
+               return false;
+
+       switch(td->runstate) {
+       case TD_RUNNING:
+       case TD_VERIFYING:
+       case TD_FINISHING:
+       case TD_EXITED:
+               return true;
+       default:
+               return false;
+       }
+}
+
 /*
  * Returns msecs to next event
  */
@@ -3591,8 +3607,7 @@ int calc_log_samples(void)
 
                if (!td->o.stats)
                        continue;
-               if (in_ramp_time(td) ||
-                   !(td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING)) {
+               if (!td_in_logging_state(td)) {
                        next = min(td->o.iops_avg_time, td->o.bw_avg_time);
                        continue;
                }