From 3ffdff7c5ab39d1bbaf5f8557ad036d632c6d3dc Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 27 May 2020 09:25:56 +0900 Subject: [PATCH] bdevperf: Set timeout to detect starved I/O and count timeout I/Os The following patches will abort the timeout I/O in bdevperf tool. This is a preparation. Add CLI option to set timeout to detect starved I/O and add count of timeout I/Os to stats. spdk_bdev_set_timeout() disables timeout if timeout value is zero. Hence we do not have to check if g_timeout_in_sec is not zero. Signed-off-by: Shuhei Matsumoto Change-Id: I201682acd321ecd414cfbfd9f5445bf3dc934b41 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2625 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Aleksey Marchuk Reviewed-by: Jim Harris --- test/bdev/bdevperf/bdevperf.c | 42 +++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/test/bdev/bdevperf/bdevperf.c b/test/bdev/bdevperf/bdevperf.c index 19b627a943..e86a88289e 100644 --- a/test/bdev/bdevperf/bdevperf.c +++ b/test/bdev/bdevperf/bdevperf.c @@ -85,6 +85,7 @@ static const char *g_job_bdev_name; static bool g_wait_for_tests = false; static struct spdk_jsonrpc_request *g_request = NULL; static bool g_multithread_mode = false; +static int g_timeout_in_sec; static struct spdk_poller *g_perf_timer = NULL; @@ -101,6 +102,7 @@ struct bdevperf_job { uint64_t io_completed; uint64_t io_failed; + uint64_t io_timeout; uint64_t prev_io_completed; double ema_io_per_second; int current_queue_depth; @@ -136,6 +138,7 @@ struct bdevperf_aggregate_stats { double total_io_per_second; double total_mb_per_second; double total_failed_per_second; + double total_timeout_per_second; }; static struct bdevperf_aggregate_stats g_stats = {}; @@ -171,7 +174,7 @@ get_ema_io_per_second(struct bdevperf_job *job, uint64_t ema_period) static void performance_dump_job(struct bdevperf_aggregate_stats *stats, struct bdevperf_job *job) { - double io_per_second, mb_per_second, failed_per_second; + double io_per_second, mb_per_second, failed_per_second, timeout_per_second; printf("\r Thread name: %s\n", spdk_thread_get_name(job->thread)); printf("\r Core Mask: 0x%s\n", spdk_cpuset_fmt(spdk_thread_get_cpumask(job->thread))); @@ -183,15 +186,18 @@ performance_dump_job(struct bdevperf_aggregate_stats *stats, struct bdevperf_job } mb_per_second = io_per_second * g_io_size / (1024 * 1024); failed_per_second = (double)job->io_failed * 1000000 / stats->io_time_in_usec; + timeout_per_second = (double)job->io_timeout * 1000000 / stats->io_time_in_usec; printf("\r %-20s: %10.2f IOPS %10.2f MiB/s\n", job->name, io_per_second, mb_per_second); if (failed_per_second != 0) { - printf("\r %-20s: %10.2f Fail/s\n", "", failed_per_second); + printf("\r %-20s: %10.2f Fail/s %8.2f TO/s\n", + "", failed_per_second, timeout_per_second); } stats->total_io_per_second += io_per_second; stats->total_mb_per_second += mb_per_second; stats->total_failed_per_second += failed_per_second; + stats->total_timeout_per_second += timeout_per_second; } static void @@ -336,8 +342,9 @@ bdevperf_test_done(void *ctx) printf("\r =====================================================\n"); printf("\r %-20s: %10.2f IOPS %10.2f MiB/s\n", "Total", g_stats.total_io_per_second, g_stats.total_mb_per_second); - if (g_stats.total_failed_per_second != 0) { - printf("\r %-20s: %10.2f Fail/s\n", "", g_stats.total_failed_per_second); + if (g_stats.total_failed_per_second != 0 || g_stats.total_timeout_per_second != 0) { + printf("\r %-20s: %10.2f Fail/s %8.2f TO/s\n", + "", g_stats.total_failed_per_second, g_stats.total_timeout_per_second); } fflush(stdout); @@ -830,6 +837,14 @@ reset_job(void *arg) return -1; } +static void +bdevperf_timeout_cb(void *cb_arg, struct spdk_bdev_io *bdev_io) +{ + struct bdevperf_job *job = cb_arg; + + job->io_timeout++; +} + static void bdevperf_job_run(void *ctx) { @@ -847,6 +862,8 @@ bdevperf_job_run(void *ctx) 10 * 1000000); } + spdk_bdev_set_timeout(job->bdev_desc, g_timeout_in_sec, bdevperf_timeout_cb, job); + for (i = 0; i < g_queue_depth; i++) { task = bdevperf_job_get_task(job); bdevperf_submit_single(job, task); @@ -861,8 +878,9 @@ _performance_dump_done(void *ctx) printf("\r =====================================================\n"); printf("\r %-20s: %10.2f IOPS %10.2f MiB/s\n", "Total", stats->total_io_per_second, stats->total_mb_per_second); - if (stats->total_failed_per_second != 0) { - printf("\r %-20s: %10.2f Fail/s\n", "", stats->total_failed_per_second); + if (stats->total_failed_per_second != 0 || stats->total_timeout_per_second != 0) { + printf("\r %-20s: %10.2f Fail/s %8.2f TO/s\n", + "", stats->total_failed_per_second, stats->total_timeout_per_second); } fflush(stdout); @@ -1410,6 +1428,9 @@ bdevperf_parse_arg(int ch, char *arg) case 't': g_time_in_sec = tmp; break; + case 'k': + g_timeout_in_sec = tmp; + break; case 'M': g_rw_percentage = tmp; g_mix_specified = true; @@ -1435,6 +1456,7 @@ bdevperf_usage(void) printf(" -o io size in bytes\n"); printf(" -w io pattern type, must be one of (read, write, randread, randwrite, rw, randrw, verify, reset, unmap, flush)\n"); printf(" -t