From aec9d3dcb5953ea7552351d7acaa57e76d1ab18d Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 6 Apr 2017 14:40:29 -0700 Subject: [PATCH] bdev: Add I/O stat tracking Change-Id: I05bb8294471bac3f9ecc4744e28d7d40e57e5364 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/362622 Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System --- include/spdk/bdev.h | 9 +++++++++ lib/bdev/bdev.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index cd0117ca5..5d7e044fc 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -97,6 +97,13 @@ typedef void (*spdk_bdev_io_completion_cb)(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg); +struct spdk_bdev_io_stat { + uint64_t bytes_read; + uint64_t num_read_ops; + uint64_t bytes_written; + uint64_t num_write_ops; +}; + struct spdk_bdev *spdk_bdev_get_by_name(const char *bdev_name); void spdk_bdev_unregister(struct spdk_bdev *bdev); @@ -214,6 +221,8 @@ struct spdk_bdev_io *spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_chan struct spdk_bdev_io *spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch, uint64_t offset, uint64_t length, spdk_bdev_io_completion_cb cb, void *cb_arg); +void spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch, + struct spdk_bdev_io_stat *stat); int spdk_bdev_free_io(struct spdk_bdev_io *bdev_io); int spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch, spdk_bdev_io_completion_cb cb, void *cb_arg); diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 8c11b050e..8cc7d285a 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -87,6 +87,8 @@ struct spdk_bdev_channel { /* Channel for the bdev manager */ struct spdk_io_channel *mgmt_channel; + + struct spdk_bdev_io_stat stat; }; struct spdk_bdev * @@ -559,6 +561,7 @@ spdk_bdev_channel_create(void *io_device, void *ctx_buf) ch->bdev = io_device; ch->channel = bdev->fn_table->get_io_channel(bdev->ctxt); ch->mgmt_channel = spdk_get_io_channel(&g_bdev_mgr); + memset(&ch->stat, 0, sizeof(ch->stat)); return 0; } @@ -950,6 +953,17 @@ spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch, return 0; } +void +spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch, + struct spdk_bdev_io_stat *stat) +{ + + struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch); + + *stat = channel->stat; + memset(&channel->stat, 0, sizeof(channel->stat)); +} + int spdk_bdev_free_io(struct spdk_bdev_io *bdev_io) { @@ -1034,6 +1048,21 @@ spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status sta bdev_io->status = status; + if (bdev_io->status == SPDK_BDEV_IO_STATUS_SUCCESS) { + switch (bdev_io->type) { + case SPDK_BDEV_IO_TYPE_READ: + bdev_io->ch->stat.bytes_read += bdev_io->u.read.len; + bdev_io->ch->stat.num_read_ops++; + break; + case SPDK_BDEV_IO_TYPE_WRITE: + bdev_io->ch->stat.bytes_written += bdev_io->u.write.len; + bdev_io->ch->stat.num_write_ops++; + break; + default: + break; + } + } + assert(bdev_io->cb != NULL); bdev_io->cb(bdev_io, status == SPDK_BDEV_IO_STATUS_SUCCESS, bdev_io->caller_ctx); }