From 64402a8a7b158c1b7a778b5f2508e625a6fc6317 Mon Sep 17 00:00:00 2001 From: Hannes Weisbach Date: Wed, 27 Nov 2019 10:57:49 +0100 Subject: [PATCH] Expand choices for exitall Add exit_what thread_option with the following choices: - "group" (default) exit all jobs of the same group (equal to "exitall=1") - "stonewall", quit all jobs until the next stonewall - "all", quit *all* jobs Signed-off-by: Hannes Weisbach --- HOWTO | 18 +++++++++++++++--- backend.c | 12 ++++++------ cconv.c | 6 ++++-- fio.1 | 17 ++++++++++++++--- fio.h | 10 ++++++++-- libfio.c | 7 +++++-- options.c | 24 ++++++++++++++++++++++++ server.c | 4 ++-- thread_options.h | 6 ++++-- 9 files changed, 82 insertions(+), 22 deletions(-) diff --git a/HOWTO b/HOWTO index 88dbb03f..41a667af 100644 --- a/HOWTO +++ b/HOWTO @@ -2814,9 +2814,21 @@ Threads, processes and job synchronization .. option:: exitall - By default, fio will continue running all other jobs when one job finishes - but sometimes this is not the desired action. Setting ``exitall`` will - instead make fio terminate all other jobs when one job finishes. + By default, fio will continue running all other jobs when one job finishes. + Sometimes this is not the desired action. Setting ``exitall`` will instead + make fio terminate all jobs in the same group, as soon as one job of that + group finishes. + +.. option:: exit_what + + By default, fio will continue running all other jobs when one job finishes. + Sometimes this is not the desired action. Setting ``exit_all`` will + instead make fio terminate all jobs in the same group. The option + ``exit_what`` allows to control which jobs get terminated when ``exitall`` is + enabled. The default is ``group`` and does not change the behaviour of + ``exitall``. The setting ``all`` terminates all jobs. The setting ``stonewall`` + terminates all currently running jobs across all groups and continues execution + with the next stonewalled group. .. option:: exec_prerun=str diff --git a/backend.c b/backend.c index 1c339408..d0d691b3 100644 --- a/backend.c +++ b/backend.c @@ -81,7 +81,7 @@ static void sig_int(int sig) exit_value = 128; } - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); } } @@ -1091,7 +1091,7 @@ reap: if (!in_ramp_time(td) && should_check_rate(td)) { if (check_min_rate(td, &comp_time)) { if (exitall_on_terminate || td->o.exitall_error) - fio_terminate_threads(td->groupid); + fio_terminate_threads(td->groupid, td->o.exit_what); td_verror(td, EIO, "check_min_rate"); break; } @@ -1898,7 +1898,7 @@ static void *thread_main(void *data) exec_string(o, o->exec_postrun, (const char *)"postrun"); if (exitall_on_terminate || (o->exitall_error && td->error)) - fio_terminate_threads(td->groupid); + fio_terminate_threads(td->groupid, td->o.exit_what); err: if (td->error) @@ -2050,7 +2050,7 @@ reaped: } if (*nr_running == cputhreads && !pending && realthreads) - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); } static bool __check_trigger_file(void) @@ -2100,7 +2100,7 @@ void check_trigger_file(void) fio_clients_send_trigger(trigger_remote_cmd); else { verify_save_state(IO_LIST_ALL); - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); exec_trigger(trigger_cmd); } } @@ -2373,7 +2373,7 @@ reap: dprint(FD_MUTEX, "wait on startup_sem\n"); if (fio_sem_down_timeout(startup_sem, 10000)) { log_err("fio: job startup hung? exiting.\n"); - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); fio_abort = true; nr_started--; free(fd); diff --git a/cconv.c b/cconv.c index bff5e34f..04854b0e 100644 --- a/cconv.c +++ b/cconv.c @@ -236,7 +236,8 @@ void convert_thread_options_to_cpu(struct thread_options *o, o->loops = le32_to_cpu(top->loops); o->mem_type = le32_to_cpu(top->mem_type); o->mem_align = le32_to_cpu(top->mem_align); - o->stonewall = le32_to_cpu(top->stonewall); + o->exit_what = le16_to_cpu(top->exit_what); + o->stonewall = le16_to_cpu(top->stonewall); o->new_group = le32_to_cpu(top->new_group); o->numjobs = le32_to_cpu(top->numjobs); o->cpus_allowed_policy = le32_to_cpu(top->cpus_allowed_policy); @@ -433,7 +434,8 @@ void convert_thread_options_to_net(struct thread_options_pack *top, top->loops = cpu_to_le32(o->loops); top->mem_type = cpu_to_le32(o->mem_type); top->mem_align = cpu_to_le32(o->mem_align); - top->stonewall = cpu_to_le32(o->stonewall); + top->exit_what = cpu_to_le16(o->exit_what); + top->stonewall = cpu_to_le16(o->stonewall); top->new_group = cpu_to_le32(o->new_group); top->numjobs = cpu_to_le32(o->numjobs); top->cpus_allowed_policy = cpu_to_le32(o->cpus_allowed_policy); diff --git a/fio.1 b/fio.1 index 14569e9f..a60863f6 100644 --- a/fio.1 +++ b/fio.1 @@ -2509,9 +2509,20 @@ wall also implies starting a new reporting group, see \fBgroup_reporting\fR. .TP .BI exitall -By default, fio will continue running all other jobs when one job finishes -but sometimes this is not the desired action. Setting \fBexitall\fR will -instead make fio terminate all other jobs when one job finishes. +By default, fio will continue running all other jobs when one job finishes. +Sometimes this is not the desired action. Setting \fBexitall\fR will instead +make fio terminate all jobs in the same group, as soon as one job of that +group finishes. +.TP +.BI exit_what +By default, fio will continue running all other jobs when one job finishes. +Sometimes this is not the desired action. Setting \fBexit_all\fR will instead +make fio terminate all jobs in the same group. The option \fBexit_what\fR +allows to control which jobs get terminated when \fBexitall\fR is enabled. The +default is \fBgroup\fR and does not change the behaviour of \fBexitall\fR. The +setting \fBall\fR terminates all jobs. The setting \fBstonewall\fR terminates +all currently running jobs across all groups and continues execution with the +next stonewalled group. .TP .BI exec_prerun \fR=\fPstr Before running this job, issue the command specified through diff --git a/fio.h b/fio.h index 2094d30b..e943ad16 100644 --- a/fio.h +++ b/fio.h @@ -660,8 +660,14 @@ extern const char *runstate_to_name(int runstate); */ #define FIO_REAP_TIMEOUT 300 -#define TERMINATE_ALL (-1U) -extern void fio_terminate_threads(unsigned int); +enum { + TERMINATE_NONE = 0, + TERMINATE_GROUP = 1, + TERMINATE_STONEWALL = 2, + TERMINATE_ALL = -1, +}; + +extern void fio_terminate_threads(unsigned int, unsigned int); extern void fio_mark_td_terminate(struct thread_data *); /* diff --git a/libfio.c b/libfio.c index 674bc1dc..7348b164 100644 --- a/libfio.c +++ b/libfio.c @@ -233,7 +233,7 @@ void fio_mark_td_terminate(struct thread_data *td) td->terminate = true; } -void fio_terminate_threads(unsigned int group_id) +void fio_terminate_threads(unsigned int group_id, unsigned int terminate) { struct thread_data *td; pid_t pid = getpid(); @@ -242,7 +242,10 @@ void fio_terminate_threads(unsigned int group_id) dprint(FD_PROCESS, "terminate group_id=%d\n", group_id); for_each_td(td, i) { - if (group_id == TERMINATE_ALL || group_id == td->groupid) { + if ((terminate == TERMINATE_GROUP && group_id == TERMINATE_ALL) || + (terminate == TERMINATE_GROUP && group_id == td->groupid) || + (terminate == TERMINATE_STONEWALL && td->runstate >= TD_RUNNING) || + (terminate == TERMINATE_ALL)) { dprint(FD_PROCESS, "setting terminate on %s/%d\n", td->o.name, (int) td->pid); diff --git a/options.c b/options.c index e4262def..287f0435 100644 --- a/options.c +++ b/options.c @@ -3941,6 +3941,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_PROCESS, }, + { + .name = "exit_what", + .lname = "What jobs to quit on terminate", + .type = FIO_OPT_STR, + .off1 = offsetof(struct thread_options, exit_what), + .help = "Fine-grained control for exitall", + .def = "group", + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_PROCESS, + .posval = { + { .ival = "group", + .oval = TERMINATE_GROUP, + .help = "exit_all=1 default behaviour", + }, + { .ival = "stonewall", + .oval = TERMINATE_STONEWALL, + .help = "quit all currently running jobs; continue with next stonewall", + }, + { .ival = "all", + .oval = TERMINATE_ALL, + .help = "Quit everything", + }, + }, + }, { .name = "exitall_on_error", .lname = "Exit-all on terminate in error", diff --git a/server.c b/server.c index 824f036a..b7347b43 100644 --- a/server.c +++ b/server.c @@ -975,7 +975,7 @@ static int handle_trigger_cmd(struct fio_net_cmd *cmd, struct flist_head *job_li } else fio_net_queue_cmd(FIO_NET_CMD_VTRIGGER, rep, sz, NULL, SK_F_FREE | SK_F_INLINE); - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); fio_server_check_jobs(job_list); exec_trigger(buf); return 0; @@ -992,7 +992,7 @@ static int handle_command(struct sk_out *sk_out, struct flist_head *job_list, switch (cmd->opcode) { case FIO_NET_CMD_QUIT: - fio_terminate_threads(TERMINATE_ALL); + fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL); ret = 0; break; case FIO_NET_CMD_EXIT: diff --git a/thread_options.h b/thread_options.h index ee6e4d6d..4b131bda 100644 --- a/thread_options.h +++ b/thread_options.h @@ -201,7 +201,8 @@ struct thread_options { unsigned long long max_latency; - unsigned int stonewall; + unsigned short exit_what; + unsigned short stonewall; unsigned int new_group; unsigned int numjobs; os_cpu_mask_t cpumask; @@ -489,7 +490,8 @@ struct thread_options_pack { uint32_t mem_type; uint32_t mem_align; - uint32_t stonewall; + uint16_t exit_what; + uint16_t stonewall; uint32_t new_group; uint32_t numjobs; /* -- 2.25.1