bdevperf: use rand_r() twice to get 64-bit values

rand_r() only returns up to RAND_MAX which is
INT32_MAX.  This means that on sufficiently large
bdevs, especially with smaller block sizes, bdevperf
may not be issuing I/O across the full range of the
bdev.

Found while investigating issue #2908.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I16db684a57a96f138e709008bded4471428944b6
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16768
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Jim Harris 2023-02-10 15:30:25 +00:00 committed by Tomasz Zawadzki
parent df45f11427
commit 0d11cf939b

View File

@ -1094,11 +1094,17 @@ static void
bdevperf_submit_single(struct bdevperf_job *job, struct bdevperf_task *task)
{
uint64_t offset_in_ios;
uint64_t rand_value;
if (job->zipf) {
offset_in_ios = spdk_zipf_generate(job->zipf);
} else if (job->is_random) {
offset_in_ios = rand_r(&job->seed) % job->size_in_ios;
/* RAND_MAX is only INT32_MAX, so use 2 calls to rand_r to
* get a large enough value to ensure we are issuing I/O
* uniformly across the whole bdev.
*/
rand_value = (uint64_t)rand_r(&job->seed) * RAND_MAX + rand_r(&job->seed);
offset_in_ios = rand_value % job->size_in_ios;
} else {
offset_in_ios = job->offset_in_ios++;
if (job->offset_in_ios == job->size_in_ios) {