From 5b53b568e46d9e9833c7a779a59316ec891a2171 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 15 Jun 2017 19:59:02 +0300 Subject: [PATCH] add VTune support: spin-wait stat Change-Id: Ie25a87c4b3f781299fa744fdcff6c9a63d473935 Signed-off-by: Roman Reviewed-on: https://review.gerrithub.io/365723 Reviewed-by: Ben Walker Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System --- include/spdk_internal/bdev.h | 5 ++++ lib/bdev/bdev.c | 10 +++++-- lib/bdev/nvme/bdev_nvme.c | 57 ++++++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 190187f07..a56c31665 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -151,6 +151,11 @@ struct spdk_bdev_fn_table { * (most likely another nested object). */ int (*dump_config_json)(void *ctx, struct spdk_json_write_ctx *w); + + /** Get spin-time per I/O channel in microseconds. + * Optional - may be NULL. + */ + uint64_t (*get_spin_time)(struct spdk_io_channel *ch); }; /** bdev I/O completion status */ diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 32252100c..c91f6603e 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -49,6 +49,8 @@ #ifdef SPDK_CONFIG_VTUNE #include "ittnotify.h" +#include "ittnotify_types.h" +int __itt_init_ittlib(const char *, __itt_group_id); #endif #define SPDK_BDEV_IO_POOL_SIZE (64 * 1024) @@ -646,7 +648,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) #ifdef SPDK_CONFIG_VTUNE { char *name; - + __itt_init_ittlib(NULL, 0); name = spdk_sprintf_alloc("spdk_bdev_%s_%p", ch->bdev->name, ch); if (!name) { return -1; @@ -1264,15 +1266,17 @@ spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status sta #ifdef SPDK_CONFIG_VTUNE uint64_t now_tsc = spdk_get_ticks(); if (now_tsc > (bdev_io->ch->start_tsc + bdev_io->ch->interval_tsc)) { - uint64_t data[4]; + uint64_t data[5]; data[0] = bdev_io->ch->stat.num_read_ops; data[1] = bdev_io->ch->stat.bytes_read; data[2] = bdev_io->ch->stat.num_write_ops; data[3] = bdev_io->ch->stat.bytes_written; + data[4] = bdev_io->bdev->fn_table->get_spin_time ? + bdev_io->bdev->fn_table->get_spin_time(bdev_io->ch->channel) : 0; __itt_metadata_add(g_bdev_mgr.domain, __itt_null, bdev_io->ch->handle, - __itt_metadata_u64, 4, data); + __itt_metadata_u64, 5, data); memset(&bdev_io->ch->stat, 0, sizeof(bdev_io->ch->stat)); bdev_io->ch->start_tsc = now_tsc; diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index 95001392d..4b743113e 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -77,6 +77,11 @@ struct nvme_bdev { struct nvme_io_channel { struct spdk_nvme_qpair *qpair; struct spdk_bdev_poller *poller; + + bool collect_spin_stat; + uint64_t spin_ticks; + uint64_t start_ticks; + uint64_t end_ticks; }; #define NVME_DEFAULT_MAX_UNMAP_BDESC_COUNT 1 @@ -186,9 +191,28 @@ static void bdev_nvme_poll(void *arg) { struct nvme_io_channel *ch = arg; + int32_t num_completions; - if (ch->qpair != NULL) { - spdk_nvme_qpair_process_completions(ch->qpair, 0); + if (ch->qpair == NULL) { + return; + } + + if (ch->collect_spin_stat && ch->start_ticks == 0) { + ch->start_ticks = spdk_get_ticks(); + } + + num_completions = spdk_nvme_qpair_process_completions(ch->qpair, 0); + + if (ch->collect_spin_stat) { + if (num_completions > 0) { + if (ch->end_ticks != 0) { + ch->spin_ticks += (ch->end_ticks - ch->start_ticks); + ch->end_ticks = 0; + } + ch->start_ticks = 0; + } else { + ch->end_ticks = spdk_get_ticks(); + } } } @@ -423,6 +447,12 @@ bdev_nvme_create_cb(void *io_device, void *ctx_buf) struct spdk_nvme_ctrlr *ctrlr = io_device; struct nvme_io_channel *ch = ctx_buf; +#ifdef SPDK_CONFIG_VTUNE + ch->collect_spin_stat = true; +#else + ch->collect_spin_stat = false; +#endif + ch->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, 0); if (ch->qpair == NULL) { @@ -585,12 +615,35 @@ bdev_nvme_dump_config_json(void *ctx, struct spdk_json_write_ctx *w) return 0; } +static uint64_t +bdev_nvme_get_spin_time(struct spdk_io_channel *ch) +{ + struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch); + uint64_t spin_time; + + if (!nvme_ch->collect_spin_stat) { + return 0; + } + + if (nvme_ch->end_ticks != 0) { + nvme_ch->spin_ticks += (nvme_ch->end_ticks - nvme_ch->start_ticks); + nvme_ch->end_ticks = 0; + } + + spin_time = (nvme_ch->spin_ticks * 1000000ULL) / spdk_get_ticks_hz(); + nvme_ch->start_ticks = 0; + nvme_ch->spin_ticks = 0; + + return spin_time; +} + static const struct spdk_bdev_fn_table nvmelib_fn_table = { .destruct = bdev_nvme_destruct, .submit_request = bdev_nvme_submit_request, .io_type_supported = bdev_nvme_io_type_supported, .get_io_channel = bdev_nvme_get_io_channel, .dump_config_json = bdev_nvme_dump_config_json, + .get_spin_time = bdev_nvme_get_spin_time, }; static bool