It is also possible to get fio to dump the current output while it is
running, without terminating the job. To do that, send fio the USR1 signal.
+You can also get regularly timed dumps by using the --status-interval
+parameter, or by creating a file in /tmp named fio-dump-status. If fio
+sees this file, it will unlink it and dump the current output status.
7.0 Terse output
9.0 CPU idleness profiling
-
+--------------------------
In some cases, we want to understand CPU overhead in a test. For example,
we test patches for the specific goodness of whether they reduce CPU usage.
fio implements a balloon approach to create a thread per CPU that runs at
--eta=when When ETA estimate should be printed
May be "always", "never" or "auto"
--eta-newline=time Force a new line for every 'time' period passed
+ --status-interval=t Force full status dump every 't' period passed
--section=name Only run specified section in job file.
Multiple sections can be specified.
--alloc-size=kb Set smalloc pool to this size in kb (def 1024)
fio_terminate_threads(TERMINATE_ALL);
}
+static void do_usleep(unsigned int usecs)
+{
+ check_for_running_stats();
+ usleep(usecs);
+}
+
/*
* Main function for kicking off and reaping jobs, as needed.
*/
if (mtime_since_now(&this_start) > JOB_START_TIMEOUT)
break;
- usleep(100000);
+ do_usleep(100000);
for (i = 0; i < this_jobs; i++) {
td = map[i];
reap_threads(&nr_running, &t_rate, &m_rate);
if (todo)
- usleep(100000);
+ do_usleep(100000);
}
while (nr_running) {
reap_threads(&nr_running, &t_rate, &m_rate);
- usleep(10000);
+ do_usleep(10000);
}
fio_idle_prof_stop();
extern int is_backend;
extern int nr_clients;
extern int log_syslog;
+extern int status_interval;
extern const char fio_version_string[];
extern struct thread_data *threads;
int write_bw_log = 0;
int read_only = 0;
+int status_interval = 0;
static int write_lat_log;
.val = 'c' | FIO_CLIENT_FLAG,
},
{
- .name = (char *) "enghelp",
+ .name = (char *) "enghelp",
.has_arg = optional_argument,
- .val = 'i' | FIO_CLIENT_FLAG,
+ .val = 'i' | FIO_CLIENT_FLAG,
},
{
.name = (char *) "showcmd",
.has_arg = required_argument,
.val = 'I',
},
+ {
+ .name = (char *) "status-interval",
+ .has_arg = required_argument,
+ .val = 'L',
+ },
{
.name = NULL,
},
printf(" \t\tMay be \"always\", \"never\" or \"auto\"\n");
printf(" --eta-newline=time\tForce a new line for every 'time'");
printf(" period passed\n");
+ printf(" --status-interval=t\tForce full status dump every");
+ printf(" 't' period passed\n");
printf(" --readonly\t\tTurn on safety read-only checks, preventing"
" writes\n");
printf(" --section=name\tOnly run specified section in job file\n");
do_exit++;
exit_val = fio_monotonic_clocktest();
break;
+ case 'L': {
+ long long val;
+
+ if (check_str_time(optarg, &val)) {
+ log_err("fio: failed parsing time %s\n", optarg);
+ do_exit++;
+ exit_val = 1;
+ break;
+ }
+ status_interval = val * 1000;
+ break;
+ }
case '?':
log_err("%s: unrecognized option '%s'\n", argv[0],
argv[optind - 1]);
return str_to_decimal(p, val, 1, data);
}
-static int check_str_time(const char *p, long long *val)
+int check_str_time(const char *p, long long *val)
{
return str_to_decimal(p, val, 0, NULL);
}
extern void strip_blank_end(char *);
extern int str_to_decimal(const char *, long long *, int, void *);
extern int check_str_bytes(const char *p, long long *val, void *data);
+extern int check_str_time(const char *p, long long *val);
extern int str_to_float(const char *str, double *val);
/*
pthread_detach(thread);
}
+static int status_interval_init;
+static struct timeval status_time;
+
+#define FIO_STATUS_FILE "/tmp/fio-dump-status"
+
+static int check_status_file(void)
+{
+ struct stat sb;
+
+ if (stat(FIO_STATUS_FILE, &sb))
+ return 0;
+
+ unlink(FIO_STATUS_FILE);
+ return 1;
+}
+
+void check_for_running_stats(void)
+{
+ if (status_interval) {
+ if (!status_interval_init) {
+ fio_gettime(&status_time, NULL);
+ status_interval_init = 1;
+ } else if (mtime_since_now(&status_time) >= status_interval) {
+ show_running_run_stats();
+ fio_gettime(&status_time, NULL);
+ return;
+ }
+ }
+ if (check_status_file()) {
+ show_running_run_stats();
+ return;
+ }
+}
+
static inline void add_stat_sample(struct io_stat *is, unsigned long data)
{
double val = data;
extern void display_thread_status(struct jobs_eta *je);
extern void show_run_stats(void);
extern void show_running_run_stats(void);
+extern void check_for_running_stats(void);
extern void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr);
extern void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src);
extern void init_thread_stat(struct thread_stat *ts);