This patch allows the specification of start delay as range. With a
range each thread will chose an individual startdelay out of the range.
That solves an issue of startdelay being the same for each numjob clone
and that way spreads all kind of activities e.g. that all clones with
mixed r/w jobs switch r/w at the same time. Also all kind of other
"thundering herd" issues can be softened by some time spread due to this
option.
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
o->verify_backlog = le64_to_cpu(top->verify_backlog);
o->start_delay = le64_to_cpu(top->start_delay);
o->verify_backlog = le64_to_cpu(top->verify_backlog);
o->start_delay = le64_to_cpu(top->start_delay);
+ o->start_delay_high = le64_to_cpu(top->start_delay_high);
o->timeout = le64_to_cpu(top->timeout);
o->ramp_time = le64_to_cpu(top->ramp_time);
o->zone_range = le64_to_cpu(top->zone_range);
o->timeout = le64_to_cpu(top->timeout);
o->ramp_time = le64_to_cpu(top->ramp_time);
o->zone_range = le64_to_cpu(top->zone_range);
top->size = __cpu_to_le64(o->size);
top->verify_backlog = __cpu_to_le64(o->verify_backlog);
top->start_delay = __cpu_to_le64(o->start_delay);
top->size = __cpu_to_le64(o->size);
top->verify_backlog = __cpu_to_le64(o->verify_backlog);
top->start_delay = __cpu_to_le64(o->start_delay);
+ top->start_delay_high = __cpu_to_le64(o->start_delay_high);
top->timeout = __cpu_to_le64(o->timeout);
top->ramp_time = __cpu_to_le64(o->ramp_time);
top->zone_range = __cpu_to_le64(o->zone_range);
top->timeout = __cpu_to_le64(o->timeout);
top->ramp_time = __cpu_to_le64(o->ramp_time);
top->zone_range = __cpu_to_le64(o->zone_range);
allowed. For \fBbind\fR and \fBinterleave\fR, \fBnodelist\fR allows
comma delimited list of numbers, A-B ranges, or 'all'.
.TP
allowed. For \fBbind\fR and \fBinterleave\fR, \fBnodelist\fR allows
comma delimited list of numbers, A-B ranges, or 'all'.
.TP
-.BI startdelay \fR=\fPint
-Delay start of job for the specified number of seconds.
+.BI startdelay \fR=\fPirange
+Delay start of job for the specified number of seconds. Supports all time
+suffixes to allow specification of hours, minutes, seconds and
+milliseconds - seconds are the default if a unit is ommited.
+Can be given as a range which causes each thread to choose randomly out of the
+range.
.TP
.BI runtime \fR=\fPint
Terminate processing after the specified number of seconds.
.TP
.BI runtime \fR=\fPint
Terminate processing after the specified number of seconds.
FIO_RAND_SEQ_RAND_READ_OFF,
FIO_RAND_SEQ_RAND_WRITE_OFF,
FIO_RAND_SEQ_RAND_TRIM_OFF,
FIO_RAND_SEQ_RAND_READ_OFF,
FIO_RAND_SEQ_RAND_WRITE_OFF,
FIO_RAND_SEQ_RAND_TRIM_OFF,
os_random_state_t trim_state;
struct frand_state __trim_state;
};
os_random_state_t trim_state;
struct frand_state __trim_state;
};
+ union {
+ os_random_state_t delay_state;
+ struct frand_state __delay_state;
+ };
struct frand_state buf_state;
struct frand_state buf_state;
o->min_bs[DDIR_READ] == o->min_bs[DDIR_TRIM];
}
o->min_bs[DDIR_READ] == o->min_bs[DDIR_TRIM];
}
+
+static unsigned long long get_rand_start_delay(struct thread_data *td)
+{
+ unsigned long long delayrange;
+ unsigned long r;
+
+ delayrange = td->o.start_delay_high - td->o.start_delay;
+
+ if (td->o.use_os_rand) {
+ r = os_random_long(&td->delay_state);
+ delayrange = (unsigned long long) ((double) delayrange * (r / (OS_RAND_MAX + 1.0)));
+ } else {
+ r = __rand(&td->__delay_state);
+ delayrange = (unsigned long long) ((double) delayrange * (r / (FRAND_MAX + 1.0)));
+ }
+
+ delayrange += td->o.start_delay;
+ return delayrange;
+}
+
/*
* Lazy way of fixing up options that depend on each other. We could also
* define option callback handlers, but this is easier.
/*
* Lazy way of fixing up options that depend on each other. We could also
* define option callback handlers, but this is easier.
if (!o->file_size_high)
o->file_size_high = o->file_size_low;
if (!o->file_size_high)
o->file_size_high = o->file_size_low;
+ if (o->start_delay_high)
+ o->start_delay = get_rand_start_delay(td);
+
if (o->norandommap && o->verify != VERIFY_NONE
&& !fixed_block_size(o)) {
log_err("fio: norandommap given for variable block sizes, "
if (o->norandommap && o->verify != VERIFY_NONE
&& !fixed_block_size(o)) {
log_err("fio: norandommap given for variable block sizes, "
os_random_seed(td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], &td->file_size_state);
os_random_seed(td->rand_seeds[FIO_RAND_TRIM_OFF], &td->trim_state);
os_random_seed(td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], &td->file_size_state);
os_random_seed(td->rand_seeds[FIO_RAND_TRIM_OFF], &td->trim_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_START_DELAY], &td->delay_state);
if (!td_random(td))
return;
if (!td_random(td))
return;
init_rand_seed(&td->__file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
init_rand_seed(&td->__trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
init_rand_seed(&td->__file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
init_rand_seed(&td->__trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
+ init_rand_seed(&td->__delay_state, td->rand_seeds[FIO_RAND_START_DELAY]);
if (!td_random(td))
return;
if (!td_random(td))
return;
.lname = "Start delay",
.type = FIO_OPT_STR_VAL_TIME,
.off1 = td_var_offset(start_delay),
.lname = "Start delay",
.type = FIO_OPT_STR_VAL_TIME,
.off1 = td_var_offset(start_delay),
+ .off2 = td_var_offset(start_delay_high),
.help = "Only start job when this period has passed",
.def = "0",
.category = FIO_OPT_C_GENERAL,
.help = "Only start job when this period has passed",
.def = "0",
.category = FIO_OPT_C_GENERAL,
unsigned int fdatasync_blocks;
unsigned int barrier_blocks;
unsigned long long start_delay;
unsigned int fdatasync_blocks;
unsigned int barrier_blocks;
unsigned long long start_delay;
+ unsigned long long start_delay_high;
unsigned long long timeout;
unsigned long long ramp_time;
unsigned int overwrite;
unsigned long long timeout;
unsigned long long ramp_time;
unsigned int overwrite;
uint32_t fdatasync_blocks;
uint32_t barrier_blocks;
uint64_t start_delay;
uint32_t fdatasync_blocks;
uint32_t barrier_blocks;
uint64_t start_delay;
+ uint64_t start_delay_high;
uint64_t timeout;
uint64_t ramp_time;
uint32_t overwrite;
uint64_t timeout;
uint64_t ramp_time;
uint32_t overwrite;