diff --git a/CHANGELOG.md b/CHANGELOG.md index 34fd778a3..f6328d9b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## v18.07: (Upcoming Release) +### Bdev + +The spdk_bdev_get_io_stat() function now returns cumulative totals instead of resetting +on each call. This allows multiple callers to query I/O statistics without conflicting +with each other. Existing users will need to adjust their code to record the previous +I/O statistics to calculate the delta between calls. + ### git pre-commit and pre-push hooks The pre-commit hook will run `scripts/check_format.sh` and verify there are no formating diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index b6d77fc32..c4419c12a 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -776,8 +776,7 @@ int spdk_bdev_nvme_io_passthru_md(struct spdk_bdev_desc *bdev_desc, int spdk_bdev_free_io(struct spdk_bdev_io *bdev_io); /** - * Return I/O statistics for this channel. After returning stats, zero out - * the current state of the statistics. + * Return I/O statistics for this channel. * * \param bdev Block device. * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 006d46cea..368d6cfee 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -205,6 +205,7 @@ struct spdk_bdev_channel { uint64_t start_tsc; uint64_t interval_tsc; __itt_string_handle *handle; + struct spdk_bdev_io_stat prev_stat; #endif }; @@ -1117,6 +1118,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) } memset(&ch->stat, 0, sizeof(ch->stat)); + ch->stat.ticks_rate = spdk_get_ticks_hz(); ch->io_outstanding = 0; TAILQ_INIT(&ch->queued_resets); ch->flags = 0; @@ -1135,6 +1137,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) free(name); ch->start_tsc = spdk_get_ticks(); ch->interval_tsc = spdk_get_ticks_hz() / 100; + memset(&ch->prev_stat, 0, sizeof(ch->prev_stat)); } #endif @@ -1961,17 +1964,9 @@ void spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch, struct spdk_bdev_io_stat *stat) { -#ifdef SPDK_CONFIG_VTUNE - SPDK_ERRLOG("Calling spdk_bdev_get_io_stat is not allowed when VTune integration is enabled.\n"); - memset(stat, 0, sizeof(*stat)); - return; -#endif - struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch); - channel->stat.ticks_rate = spdk_get_ticks_hz(); *stat = channel->stat; - memset(&channel->stat, 0, sizeof(channel->stat)); } static void @@ -2233,17 +2228,17 @@ _spdk_bdev_io_complete(void *ctx) if (now_tsc > (bdev_io->ch->start_tsc + bdev_io->ch->interval_tsc)) { 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[0] = bdev_io->ch->stat.num_read_ops - bdev_io->ch->prev_stat.num_read_ops; + data[1] = bdev_io->ch->stat.bytes_read - bdev_io->ch->prev_stat.bytes_read; + data[2] = bdev_io->ch->stat.num_write_ops - bdev_io->ch->prev_stat.num_write_ops; + data[3] = bdev_io->ch->stat.bytes_written - bdev_io->ch->prev_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, 5, data); - memset(&bdev_io->ch->stat, 0, sizeof(bdev_io->ch->stat)); + bdev_io->ch->prev_stat = bdev_io->ch->stat; bdev_io->ch->start_tsc = now_tsc; } #endif