bdev: add public APIs for IO statictics processing

Export functions bdev_reset_io_stat(), bdev_add_io_stat() and
bdev_dump_io_stat_json() as public APIs.

Change-Id: Ibd0bcf44f2967d79d1ceb9e183c08579410061db
Signed-off-by: Richael Zhuang <richael.zhuang@arm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16065
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
This commit is contained in:
Richael Zhuang 2022-12-21 16:09:17 +08:00 committed by Jim Harris
parent 2f500a23fb
commit 8ddc102a31
6 changed files with 54 additions and 23 deletions

View File

@ -63,6 +63,9 @@ context.
A new option `nvme_error_stat` was added to the `bdev_nvme_set_options` RPC to enable
collecting NVMe error counts.
New APIs `spdk_bdev_reset_io_stat`, `spdk_bdev_add_io_stat` and `spdk_bdev_dump_io_stat_json`
were added to process I/O statistics outside the generic bdev layer, especially in bdev modules.
### event
Added core lock file mechanism to prevent the same CPU cores from being used by multiple

View File

@ -1475,6 +1475,35 @@ typedef void (*spdk_bdev_get_current_qd_cb)(struct spdk_bdev *bdev, uint64_t cur
void spdk_bdev_get_current_qd(struct spdk_bdev *bdev,
spdk_bdev_get_current_qd_cb cb_fn, void *cb_arg);
/**
* Add I/O statictics.
*
* \param total The aggregated I/O statictics.
* \param add The I/O statictics to be added.
*/
void spdk_bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_stat *add);
/**
* Output bdev I/O statictics information to a JSON stream.
*
* \param stat The bdev I/O statictics to output.
* \param w JSON write context.
*/
void spdk_bdev_dump_io_stat_json(struct spdk_bdev_io_stat *stat, struct spdk_json_write_ctx *w);
enum spdk_bdev_reset_stat_mode {
BDEV_RESET_STAT_ALL,
BDEV_RESET_STAT_MAXMIN,
};
/**
* Reset I/O statictics structure.
*
* \param stat The I/O statictics to reset.
* \param mode The mode to reset I/O statictics.
*/
void spdk_bdev_reset_io_stat(struct spdk_bdev_io_stat *stat, enum spdk_bdev_reset_stat_mode mode);
/*
* Macro used to register module for later initialization.
*/

View File

@ -3716,8 +3716,8 @@ bdev_qos_destroy(struct spdk_bdev *bdev)
return 0;
}
static void
bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_stat *add)
void
spdk_bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_stat *add)
{
total->bytes_read += add->bytes_read;
total->num_read_ops += add->num_read_ops;
@ -3768,8 +3768,8 @@ bdev_get_io_stat(struct spdk_bdev_io_stat *to_stat, struct spdk_bdev_io_stat *fr
}
}
static void
bdev_reset_io_stat(struct spdk_bdev_io_stat *stat, enum bdev_reset_stat_mode mode)
void
spdk_bdev_reset_io_stat(struct spdk_bdev_io_stat *stat, enum spdk_bdev_reset_stat_mode mode)
{
stat->max_read_latency_ticks = 0;
stat->min_read_latency_ticks = UINT64_MAX;
@ -3822,7 +3822,7 @@ bdev_alloc_io_stat(bool io_error_stat)
stat->io_error = NULL;
}
bdev_reset_io_stat(stat, BDEV_RESET_STAT_ALL);
spdk_bdev_reset_io_stat(stat, BDEV_RESET_STAT_ALL);
return stat;
}
@ -3837,7 +3837,7 @@ bdev_free_io_stat(struct spdk_bdev_io_stat *stat)
}
void
bdev_dump_io_stat_json(struct spdk_bdev_io_stat *stat, struct spdk_json_write_ctx *w)
spdk_bdev_dump_io_stat_json(struct spdk_bdev_io_stat *stat, struct spdk_json_write_ctx *w)
{
int i;
@ -3906,7 +3906,7 @@ bdev_channel_destroy(void *io_device, void *ctx_buf)
/* This channel is going away, so add its statistics into the bdev so that they don't get lost. */
spdk_spin_lock(&ch->bdev->internal.spinlock);
bdev_add_io_stat(ch->bdev->internal.stat, ch->stat);
spdk_bdev_add_io_stat(ch->bdev->internal.stat, ch->stat);
spdk_spin_unlock(&ch->bdev->internal.spinlock);
bdev_abort_all_queued_io(&ch->queued_resets, ch);
@ -5813,7 +5813,7 @@ bdev_get_each_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev *b
struct spdk_bdev_iostat_ctx *bdev_iostat_ctx = _ctx;
struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch);
bdev_add_io_stat(bdev_iostat_ctx->stat, channel->stat);
spdk_bdev_add_io_stat(bdev_iostat_ctx->stat, channel->stat);
spdk_bdev_for_each_channel_continue(i, 0);
}
@ -5849,7 +5849,7 @@ spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat
}
struct bdev_iostat_reset_ctx {
enum bdev_reset_stat_mode mode;
enum spdk_bdev_reset_stat_mode mode;
bdev_reset_device_stat_cb cb;
void *cb_arg;
};
@ -5871,13 +5871,13 @@ bdev_reset_each_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev
struct bdev_iostat_reset_ctx *ctx = _ctx;
struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch);
bdev_reset_io_stat(channel->stat, ctx->mode);
spdk_bdev_reset_io_stat(channel->stat, ctx->mode);
spdk_bdev_for_each_channel_continue(i, 0);
}
void
bdev_reset_device_stat(struct spdk_bdev *bdev, enum bdev_reset_stat_mode mode,
bdev_reset_device_stat(struct spdk_bdev *bdev, enum spdk_bdev_reset_stat_mode mode,
bdev_reset_device_stat_cb cb, void *cb_arg)
{
struct bdev_iostat_reset_ctx *ctx;
@ -5897,7 +5897,7 @@ bdev_reset_device_stat(struct spdk_bdev *bdev, enum bdev_reset_stat_mode mode,
ctx->cb_arg = cb_arg;
spdk_spin_lock(&bdev->internal.spinlock);
bdev_reset_io_stat(bdev->internal.stat, mode);
spdk_bdev_reset_io_stat(bdev->internal.stat, mode);
spdk_spin_unlock(&bdev->internal.spinlock);
spdk_bdev_for_each_channel(bdev,

View File

@ -23,16 +23,12 @@ void bdev_io_submit(struct spdk_bdev_io *bdev_io);
struct spdk_bdev_io_stat *bdev_alloc_io_stat(bool io_error_stat);
void bdev_free_io_stat(struct spdk_bdev_io_stat *stat);
void bdev_dump_io_stat_json(struct spdk_bdev_io_stat *stat, struct spdk_json_write_ctx *w);
enum bdev_reset_stat_mode {
BDEV_RESET_STAT_ALL,
BDEV_RESET_STAT_MAXMIN,
};
enum spdk_bdev_reset_stat_mode;
typedef void (*bdev_reset_device_stat_cb)(struct spdk_bdev *bdev, void *cb_arg, int rc);
void bdev_reset_device_stat(struct spdk_bdev *bdev, enum bdev_reset_stat_mode mode,
void bdev_reset_device_stat(struct spdk_bdev *bdev, enum spdk_bdev_reset_stat_mode mode,
bdev_reset_device_stat_cb cb, void *cb_arg);
#endif /* SPDK_BDEV_INTERNAL_H */

View File

@ -264,7 +264,7 @@ bdev_get_iostat_done(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat,
spdk_json_write_named_string(w, "name", spdk_bdev_get_name(bdev));
bdev_dump_io_stat_json(stat, w);
spdk_bdev_dump_io_stat_json(stat, w);
if (spdk_bdev_get_qd_sampling_period(bdev)) {
spdk_json_write_named_uint64(w, "queue_depth_polling_period",
@ -344,7 +344,7 @@ bdev_get_per_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev *bd
spdk_json_write_object_begin(w);
spdk_json_write_named_uint64(w, "thread_id", spdk_thread_get_id(spdk_get_thread()));
bdev_dump_io_stat_json(bdev_ctx->stat, w);
spdk_bdev_dump_io_stat_json(bdev_ctx->stat, w);
spdk_json_write_object_end(w);
spdk_bdev_for_each_channel_continue(i, 0);
@ -469,7 +469,7 @@ struct rpc_reset_iostat_ctx {
int rc;
struct spdk_jsonrpc_request *request;
struct spdk_json_write_ctx *w;
enum bdev_reset_stat_mode mode;
enum spdk_bdev_reset_stat_mode mode;
};
struct bdev_reset_iostat_ctx {
@ -546,7 +546,7 @@ bdev_reset_iostat(void *ctx, struct spdk_bdev *bdev)
struct rpc_bdev_reset_iostat {
char *name;
enum bdev_reset_stat_mode mode;
enum spdk_bdev_reset_stat_mode mode;
};
static void
@ -558,7 +558,7 @@ free_rpc_bdev_reset_iostat(struct rpc_bdev_reset_iostat *r)
static int
rpc_decode_reset_iostat_mode(const struct spdk_json_val *val, void *out)
{
enum bdev_reset_stat_mode *mode = out;
enum spdk_bdev_reset_stat_mode *mode = out;
if (spdk_json_strequal(val, "all") == true) {
*mode = BDEV_RESET_STAT_ALL;

View File

@ -159,6 +159,9 @@
spdk_bdev_push_media_events;
spdk_bdev_notify_media_management;
spdk_bdev_for_each_bdev_io;
spdk_bdev_reset_io_stat;
spdk_bdev_add_io_stat;
spdk_bdev_dump_io_stat_json;
# Public functions in bdev_zone.h
spdk_bdev_get_zone_size;