From 84422acde41c9cf462245de115d425cf5a82124c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Feb 2008 20:10:26 +0100 Subject: [PATCH] More random fixes Signed-off-by: Jens Axboe --- fio.h | 3 ++- init.c | 1 + io_u.c | 21 +++++++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/fio.h b/fio.h index d8c65950..7551ef60 100644 --- a/fio.h +++ b/fio.h @@ -683,7 +683,7 @@ static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u) } #define BLOCKS_PER_MAP (8 * sizeof(long)) -#define TO_MAP_BLOCK(td, f, b) ((b) / ((unsigned long long) (td)->o.rw_min_bs)) +#define TO_MAP_BLOCK(td, f, b) (b) #define RAND_MAP_IDX(td, f, b) (TO_MAP_BLOCK(td, f, b) / BLOCKS_PER_MAP) #define RAND_MAP_BIT(td, f, b) (TO_MAP_BLOCK(td, f, b) & (BLOCKS_PER_MAP - 1)) @@ -981,6 +981,7 @@ enum { FD_MEM, FD_BLKTRACE, FD_VERIFY, + FD_RANDOM, FD_DEBUG_MAX, }; diff --git a/init.c b/init.c index d559a7ac..92c5b8cd 100644 --- a/init.c +++ b/init.c @@ -811,6 +811,7 @@ struct debug_level debug_levels[] = { { .name = "mem", .shift = FD_MEM, }, { .name = "blktrace", .shift = FD_BLKTRACE }, { .name = "verify", .shift = FD_VERIFY }, + { .name = "random", .shift = FD_RANDOM }, { }, }; diff --git a/io_u.c b/io_u.c index 9ab33f39..7ac31a0d 100644 --- a/io_u.c +++ b/io_u.c @@ -25,11 +25,13 @@ struct io_completion_data { * to yet. Used to make sure we cover the entire range in a fair fashion. */ static int random_map_free(struct thread_data *td, struct fio_file *f, - unsigned long long block) + const unsigned long long block) { unsigned int idx = RAND_MAP_IDX(td, f, block); unsigned int bit = RAND_MAP_BIT(td, f, block); + dprint(FD_RANDOM, "free: b=%llu, idx=%u, bit=%u\n", block, idx, bit); + return (f->file_map[idx] & (1UL << bit)) == 0; } @@ -78,7 +80,7 @@ static inline unsigned long long last_block(struct thread_data *td, { unsigned long long max_blocks; - max_blocks = f->io_size / td->o.min_bs[ddir]; + max_blocks = f->io_size / (unsigned long long) td->o.min_bs[ddir]; if (!max_blocks) return 0; @@ -91,11 +93,12 @@ static inline unsigned long long last_block(struct thread_data *td, static int get_next_free_block(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { + unsigned long long min_bs = td->o.rw_min_bs; int i; i = f->last_free_lookup; *b = (i * BLOCKS_PER_MAP); - while ((*b) * td->o.rw_min_bs < f->real_file_size) { + while ((*b) * min_bs < f->real_file_size) { if (f->file_map[i] != -1UL) { *b += fio_ffz(f->file_map[i]); if (*b > last_block(td, f, ddir)) @@ -115,12 +118,13 @@ static int get_next_free_block(struct thread_data *td, struct fio_file *f, static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { - unsigned long long r, rb; + unsigned long long r; int loops = 5; do { r = os_random_long(&td->random_state); - *b = last_block(td, f, ddir); + dprint(FD_RANDOM, "off rand %llu\n", r); + *b = (last_block(td, f, ddir) - 1) * (r / ((unsigned long long) RAND_MAX + 1.0)); /* * if we are not maintaining a random map, we are done. @@ -129,12 +133,13 @@ static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, return 0; /* - * calculate map offset and chec if it's free + * calculate map offset and check if it's free */ - rb = *b; - if (random_map_free(td, f, rb)) + if (random_map_free(td, f, *b)) return 0; + dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n", + *b); } while (--loops); /* -- 2.25.1