X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=init.c;h=d12b75d5ee33108075731d879d2870b5a11a34ff;hp=5482c665c277e5050b89a5759fa9bcd49895fd26;hb=95a12fbe88afa768926403c5a4ef53346ba2544d;hpb=52d892b24cbcd887fe30cce96577a067ee171ea0 diff --git a/init.c b/init.c index 5482c665..d12b75d5 100644 --- a/init.c +++ b/init.c @@ -25,11 +25,13 @@ #include "server.h" #include "idletime.h" #include "filelock.h" +#include "steadystate.h" #include "oslib/getopt.h" #include "oslib/strcasestr.h" #include "crc/test.h" +#include "lib/pow2.h" const char fio_version_string[] = FIO_VERSION; @@ -103,7 +105,7 @@ static struct option l_opts[FIO_NR_OPTIONS] = { }, { .name = (char *) "bandwidth-log", - .has_arg = required_argument, + .has_arg = no_argument, .val = 'b' | FIO_CLIENT_FLAG, }, { @@ -298,7 +300,6 @@ void free_threads_shm(void) static void free_shm(void) { if (threads) { - file_hash_exit(); flow_exit(); fio_debug_jobp = NULL; free_threads_shm(); @@ -311,6 +312,7 @@ static void free_shm(void) options_free(fio_options, &def_thread.o); fio_filelock_exit(); + file_hash_exit(); scleanup(); } @@ -322,8 +324,6 @@ static void free_shm(void) */ static int setup_thread_area(void) { - void *hash; - if (threads) return 0; @@ -334,7 +334,6 @@ static int setup_thread_area(void) do { size_t size = max_jobs * sizeof(struct thread_data); - size += file_hash_size; size += sizeof(unsigned int); #ifndef CONFIG_NO_SHM @@ -366,10 +365,8 @@ static int setup_thread_area(void) #endif memset(threads, 0, max_jobs * sizeof(struct thread_data)); - hash = (void *) threads + max_jobs * sizeof(struct thread_data); - fio_debug_jobp = (void *) hash + file_hash_size; + fio_debug_jobp = (void *) threads + max_jobs * sizeof(struct thread_data); *fio_debug_jobp = -1; - file_hash_init(hash); flow_init(); @@ -827,7 +824,8 @@ static int fixup_options(struct thread_data *td) * If size is set but less than the min block size, complain */ if (o->size && o->size < td_min_bs(td)) { - log_err("fio: size too small, must be larger than the IO size: %llu\n", (unsigned long long) o->size); + log_err("fio: size too small, must not be less than minimum block size: %llu < %u\n", + (unsigned long long) o->size, td_min_bs(td)); ret = 1; } @@ -868,27 +866,6 @@ static int fixup_options(struct thread_data *td) return ret; } -/* - * This function leaks the buffer - */ -char *fio_uint_to_kmg(unsigned int val) -{ - char *buf = malloc(32); - char post[] = { 0, 'K', 'M', 'G', 'P', 'E', 0 }; - char *p = post; - - do { - if (val & 1023) - break; - - val >>= 10; - p++; - } while (*p); - - snprintf(buf, 32, "%u%c", val, *p); - return buf; -} - /* External engines are specified by "external:name.o") */ static const char *get_engine_name(const char *str) { @@ -1394,7 +1371,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, if (setup_rate(td)) goto err; - if (o->lat_log_file) { + if (o->write_lat_log) { struct log_params p = { .td = td, .avg_msec = o->log_avg_msec, @@ -1405,6 +1382,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; + const char *pre = o->lat_log_file ? o->lat_log_file : o->name; const char *suf; if (p.log_gz_store) @@ -1412,20 +1390,20 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, else suf = "log"; - gen_log_name(logname, sizeof(logname), "lat", o->lat_log_file, + gen_log_name(logname, sizeof(logname), "lat", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->lat_log, &p, logname); - gen_log_name(logname, sizeof(logname), "slat", o->lat_log_file, + gen_log_name(logname, sizeof(logname), "slat", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->slat_log, &p, logname); - gen_log_name(logname, sizeof(logname), "clat", o->lat_log_file, + gen_log_name(logname, sizeof(logname), "clat", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->clat_log, &p, logname); } - if (o->hist_log_file) { + if (o->write_hist_log) { struct log_params p = { .td = td, .avg_msec = o->log_avg_msec, @@ -1436,6 +1414,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; + const char *pre = o->hist_log_file ? o->hist_log_file : o->name; const char *suf; #ifndef CONFIG_ZLIB @@ -1450,12 +1429,12 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, else suf = "log"; - gen_log_name(logname, sizeof(logname), "clat_hist", o->hist_log_file, + gen_log_name(logname, sizeof(logname), "clat_hist", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->clat_hist_log, &p, logname); } - if (o->bw_log_file) { + if (o->write_bw_log) { struct log_params p = { .td = td, .avg_msec = o->log_avg_msec, @@ -1466,6 +1445,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; + const char *pre = o->bw_log_file ? o->bw_log_file : o->name; const char *suf; if (fio_option_is_set(o, bw_avg_time)) @@ -1481,11 +1461,11 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, else suf = "log"; - gen_log_name(logname, sizeof(logname), "bw", o->bw_log_file, + gen_log_name(logname, sizeof(logname), "bw", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->bw_log, &p, logname); } - if (o->iops_log_file) { + if (o->write_iops_log) { struct log_params p = { .td = td, .avg_msec = o->log_avg_msec, @@ -1496,6 +1476,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; + const char *pre = o->iops_log_file ? o->iops_log_file : o->name; const char *suf; if (fio_option_is_set(o, iops_avg_time)) @@ -1511,7 +1492,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, else suf = "log"; - gen_log_name(logname, sizeof(logname), "iops", o->iops_log_file, + gen_log_name(logname, sizeof(logname), "iops", pre, td->thread_number, suf, o->per_job_logs); setup_log(&td->iops_log, &p, logname); } @@ -1527,15 +1508,16 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, if (!td_ioengine_flagged(td, FIO_NOIO)) { char *c1, *c2, *c3, *c4; char *c5 = NULL, *c6 = NULL; + int i2p = is_power_of_2(o->kb_base); - c1 = fio_uint_to_kmg(o->min_bs[DDIR_READ]); - c2 = fio_uint_to_kmg(o->max_bs[DDIR_READ]); - c3 = fio_uint_to_kmg(o->min_bs[DDIR_WRITE]); - c4 = fio_uint_to_kmg(o->max_bs[DDIR_WRITE]); + c1 = num2str(o->min_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE); + c2 = num2str(o->max_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE); + c3 = num2str(o->min_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE); + c4 = num2str(o->max_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE); if (!o->bs_is_seq_rand) { - c5 = fio_uint_to_kmg(o->min_bs[DDIR_TRIM]); - c6 = fio_uint_to_kmg(o->max_bs[DDIR_TRIM]); + c5 = num2str(o->min_bs[DDIR_TRIM], 4, 1, i2p, N2S_BYTE); + c6 = num2str(o->max_bs[DDIR_TRIM], 4, 1, i2p, N2S_BYTE); } log_info("%s: (g=%d): rw=%s, ", td->o.name, @@ -1543,10 +1525,10 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, ddir_str(o->td_ddir)); if (o->bs_is_seq_rand) - log_info("bs(seq/rand)=%s-%s/%s-%s, ", + log_info("bs=%s-%s,%s-%s, bs_is_seq_rand, ", c1, c2, c3, c4); else - log_info("bs=%s-%s/%s-%s/%s-%s, ", + log_info("bs=%s-%s,%s-%s,%s-%s, ", c1, c2, c3, c4, c5, c6); log_info("ioengine=%s, iodepth=%u\n", @@ -1563,6 +1545,9 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, log_info("...\n"); } + if (td_steadystate_init(td)) + goto err; + /* * recurse add identical jobs, clear numjobs and stonewall options * as they don't apply to sub-jobs @@ -1578,6 +1563,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, td_new->o.stonewall = 0; td_new->o.new_group = 0; td_new->subjob_number = numjobs; + td_new->o.ss_dur = o->ss_dur * 1000000l; + td_new->o.ss_limit = o->ss_limit; if (file_alloced) { if (td_new->files) { @@ -1680,7 +1667,7 @@ static int is_empty_or_comment(char *line) /* * This is our [ini] type file parser. */ -int __parse_jobs_ini(struct thread_data *td, +static int __parse_jobs_ini(struct thread_data *td, char *file, int is_buf, int stonewall_flag, int type, int nested, char *name, char ***popts, int *aopts, int *nopts) { @@ -2006,14 +1993,15 @@ static void usage(const char *name) printf(" --parse-only\t\tParse options only, don't start any IO\n"); printf(" --output\t\tWrite output to file\n"); printf(" --runtime\t\tRuntime in seconds\n"); - printf(" --bandwidth-log\tGenerate per-job bandwidth logs\n"); + printf(" --bandwidth-log\tGenerate aggregate bandwidth logs\n"); printf(" --minimal\t\tMinimal (terse) output\n"); - printf(" --output-format=x\tOutput format (terse,json,json+,normal)\n"); - printf(" --terse-version=x\tSet terse version output format to 'x'\n"); + printf(" --output-format=type\tOutput format (terse,json,json+,normal)\n"); + printf(" --terse-version=type\tSet terse version output format" + " (default 3, or 2 or 4)\n"); printf(" --version\t\tPrint version info and exit\n"); printf(" --help\t\tPrint this page\n"); printf(" --cpuclock-test\tPerform test/validation of CPU clock\n"); - printf(" --crctest\t\tTest speed of checksum functions\n"); + printf(" --crctest=type\tTest speed of checksum functions\n"); printf(" --cmdhelp=cmd\t\tPrint command help, \"all\" for all of" " them\n"); printf(" --enghelp=engine\tPrint ioengine help, or list" @@ -2029,14 +2017,15 @@ static void usage(const char *name) 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"); + printf(" --section=name\tOnly run specified section in job file," + " multiple sections can be specified\n"); printf(" --alloc-size=kb\tSet smalloc pool to this size in kb" - " (def 1024)\n"); + " (def 16384)\n"); printf(" --warnings-fatal\tFio parser warnings are fatal\n"); printf(" --max-jobs=nr\t\tMaximum number of threads/processes to support\n"); printf(" --server=args\t\tStart a backend fio server\n"); printf(" --daemonize=pidfile\tBackground fio server, write pid to file\n"); - printf(" --client=hostname\tTalk to remote backend fio server at hostname\n"); + printf(" --client=hostname\tTalk to remote backend(s) fio server at hostname\n"); printf(" --remote-config=file\tTell fio server to load this local job file\n"); printf(" --idle-prof=option\tReport cpu idleness on a system or percpu basis\n" "\t\t\t(option=system,percpu) or run unit work\n" @@ -2120,6 +2109,14 @@ struct debug_level debug_levels[] = { .help = "Log compression logging", .shift = FD_COMPRESS, }, + { .name = "steadystate", + .help = "Steady state detection logging", + .shift = FD_STEADYSTATE, + }, + { .name = "helperthread", + .help = "Helper thread logging", + .shift = FD_HELPERTHREAD, + }, { .name = NULL, }, }; @@ -2309,6 +2306,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) case 'a': smalloc_pool_size = atoi(optarg); smalloc_pool_size <<= 10; + sinit(); break; case 't': if (check_str_time(optarg, &def_timeout, 1)) {