From 252d613eae8c58db4bf4f60f88b96477908de234 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Wed, 27 Jan 2016 20:37:31 +0100 Subject: [PATCH] Print stats of the number of cached blocks --- cmdline/check.c | 2 +- cmdline/dry.c | 2 +- cmdline/elem.c | 1 + cmdline/elem.h | 2 ++ cmdline/io.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ cmdline/io.h | 5 +++++ cmdline/scrub.c | 2 +- cmdline/state.c | 41 ++++++++++++++++++++++++++++++++++++----- cmdline/state.h | 5 +++-- cmdline/sync.c | 4 ++-- 10 files changed, 98 insertions(+), 12 deletions(-) diff --git a/cmdline/check.c b/cmdline/check.c index 9431efa0..1e5bf7e5 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -1388,7 +1388,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna ++countpos; /* progress */ - if (state_progress(state, i, countpos, countmax, countsize)) { + if (state_progress(state, 0, i, countpos, countmax, countsize)) { /* LCOV_EXCL_START */ break; /* LCOV_EXCL_STOP */ diff --git a/cmdline/dry.c b/cmdline/dry.c index 9986c47b..47ba69dd 100644 --- a/cmdline/dry.c +++ b/cmdline/dry.c @@ -334,7 +334,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit ++countpos; /* progress */ - if (state_progress(state, blockcur, countpos, countmax, countsize)) { + if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { /* LCOV_EXCL_START */ break; /* LCOV_EXCL_STOP */ diff --git a/cmdline/elem.c b/cmdline/elem.c index fb8c209c..47523c95 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -742,6 +742,7 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev disk->smartctl[0] = 0; disk->device = dev; disk->tick = 0; + disk->cached = 0; disk->total_blocks = 0; disk->free_blocks = 0; disk->first_free_block = 0; diff --git a/cmdline/elem.h b/cmdline/elem.h index 87a649e6..ba005329 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -338,6 +338,7 @@ struct snapraid_disk { uint64_t tick; /**< Usage time. */ uint64_t progress_tick[PROGRESS_MAX]; /**< Last ticks of progress. */ + unsigned cached; /**< Number of IO blocks cached. */ /** * First free searching block. @@ -432,6 +433,7 @@ struct snapraid_parity { uint64_t tick; /**< Usage time. */ uint64_t progress_tick[PROGRESS_MAX]; /**< Last cpu ticks of progress. */ + unsigned cached; /**< Number of IO blocks cached. */ }; /** diff --git a/cmdline/io.c b/cmdline/io.c index 32e350d1..7370361b 100644 --- a/cmdline/io.c +++ b/cmdline/io.c @@ -492,6 +492,52 @@ void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* wri #endif } +void io_refresh(struct snapraid_io* io) +{ + unsigned i; + + /* the synchronization is protected by the io mutex */ + pthread_mutex_lock(&io->mutex); + + /* for all readers, count the number of read blocks */ + for (i = 0; i < io->reader_max; ++i) { + unsigned begin, end, cached; + struct snapraid_worker* worker = &io->reader_map[i]; + + /* the first block read */ + begin = io->reader_index + 1; + /* the block in reading */ + end = worker->index; + if (begin > end) + end += io->io_max; + cached = end - begin; + + if (worker->parity_handle) + io->state->parity[worker->parity_handle->level].cached = cached; + else + worker->handle->disk->cached = cached; + } + + /* for all writers, count the number of written blocks */ + /* note that this is a kind of "opposite" of cached blocks */ + for (i = 0; i < io->writer_max; ++i) { + unsigned begin, end, cached; + struct snapraid_worker* worker = &io->writer_map[i]; + + /* the first block written */ + begin = io->writer_index + 1; + /* the block in writing */ + end = worker->index; + if (begin > end) + end += io->io_max; + cached = end - begin; + + io->state->parity[worker->parity_handle->level].cached = cached; + } + + pthread_mutex_unlock(&io->mutex); +} + static struct snapraid_task* io_task_read(struct snapraid_io* io, unsigned base, unsigned count, unsigned* pos, unsigned* waiting_map, unsigned* waiting_mac) { unsigned waiting_cycle; diff --git a/cmdline/io.h b/cmdline/io.h index dd05ece0..0532ea12 100644 --- a/cmdline/io.h +++ b/cmdline/io.h @@ -365,5 +365,10 @@ void io_parity_write(struct snapraid_io* io, unsigned* levcur, unsigned* waiting */ void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* writer_error); +/** + * Refresh the number of cached blocks for all data and parity disks. + */ +void io_refresh(struct snapraid_io* io); + #endif diff --git a/cmdline/scrub.c b/cmdline/scrub.c index e01eebb4..f9c3a78c 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -599,7 +599,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par ++countpos; /* progress */ - if (state_progress(state, blockcur, countpos, countmax, countsize)) { + if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { /* LCOV_EXCL_START */ break; /* LCOV_EXCL_STOP */ diff --git a/cmdline/state.c b/cmdline/state.c index 767ebad1..61c940c4 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -25,6 +25,7 @@ #include "parity.h" #include "stream.h" #include "handle.h" +#include "io.h" #include "raid/raid.h" #include "raid/cpu.h" @@ -155,6 +156,7 @@ void state_init(struct snapraid_state* state) state->parity[l].total_blocks = 0; state->parity[l].free_blocks = 0; state->parity[l].tick = 0; + state->parity[l].cached = 0; state->parity[l].skip_access = 0; state->parity[l].is_excluded = 0; } @@ -3906,7 +3908,7 @@ void state_progress_restart(struct snapraid_state* state) #define PROGRESS_CLEAR " " -int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) +int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize) { time_t now; int pred; @@ -4016,8 +4018,7 @@ int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off out_eta = (countmax - countpos) * delta_time / (60 * delta_pos); if (msg_level >= MSG_VERBOSE) { - printf("\n\n"); - state_usage_graph(state, state->progress_ptr, oldest); + state_usage_graph(state, io, state->progress_ptr, oldest); } } @@ -4164,7 +4165,7 @@ static void printr(const char* str, size_t pad) #define USAGE_COLUMN 60 -void state_usage_graph(struct snapraid_state* state, unsigned current, unsigned oldest) +void state_usage_graph(struct snapraid_state* state, struct snapraid_io* io, unsigned current, unsigned oldest) { uint64_t v; uint64_t tick_total; @@ -4197,7 +4198,37 @@ void state_usage_graph(struct snapraid_state* state, unsigned current, unsigned /* extra space */ pad += 1; - /* here we don't use msg_progress() because it doesn't allow partial output */ + if (io) { + /* refresh the cached blocks info */ + io_refresh(io); + + printf("\ncached blocks (instant)\n"); + + for (i = state->disklist; i != 0; i = i->next) { + struct snapraid_disk* disk = i->data; + v = disk->cached; + printr(disk->name, pad); + printf("%4" PRIu64 " | ", v); + printc('*', v * USAGE_COLUMN / io->io_max); + printf("\n"); + } + + for (l = 0; l < state->level; ++l) { + v = state->parity[l].cached; + printr(lev_config_name(l), pad); + printf("%4" PRIu64 " | ", v); + printc('*', v * USAGE_COLUMN / io->io_max); + printf("\n"); + } + + printr("", pad); + printf(" +-"); + printc('-', USAGE_COLUMN); + printf("\n"); + } + + printf("\nwait time %% (latest %d seconds)\n", PROGRESS_MAX); + for (i = state->disklist; i != 0; i = i->next) { struct snapraid_disk* disk = i->data; v = disk->progress_tick[current] - disk->progress_tick[oldest]; diff --git a/cmdline/state.h b/cmdline/state.h index d5a94916..efcad234 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -21,6 +21,7 @@ #include "elem.h" struct snapraid_handle; +struct snapraid_io; /****************************************************************************/ /* parity level */ @@ -319,7 +320,7 @@ void state_progress_end(struct snapraid_state* state, block_off_t countpos, bloc /** * Write the progress. */ -int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize); +int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize); /** * Stop temporarily the progress. @@ -361,7 +362,7 @@ void state_usage_print(struct snapraid_state* state); /** * Print a graph of usage time. */ -void state_usage_graph(struct snapraid_state* state, unsigned current, unsigned oldest); +void state_usage_graph(struct snapraid_state* state, struct snapraid_io* io, unsigned current, unsigned oldest); /** * Check the file-system on all disks. diff --git a/cmdline/sync.c b/cmdline/sync.c index 6af65d1a..cadbf7a3 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -299,7 +299,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta ++countpos; /* progress */ - if (state_progress(state, i, countpos, countmax, countsize)) { + if (state_progress(state, 0, i, countpos, countmax, countsize)) { /* LCOV_EXCL_START */ *skip_sync = 1; /* avoid to run the next sync */ break; @@ -1258,7 +1258,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari ++countpos; /* progress */ - if (state_progress(state, blockcur, countpos, countmax, countsize)) { + if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) { /* LCOV_EXCL_START */ break; /* LCOV_EXCL_STOP */