diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aad89732..2db35330f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index b48979988..310bc8827 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -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. */ diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index c9d47fa59..233ed3d65 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -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, diff --git a/lib/bdev/bdev_internal.h b/lib/bdev/bdev_internal.h index 68fa5d101..f485dfa0f 100644 --- a/lib/bdev/bdev_internal.h +++ b/lib/bdev/bdev_internal.h @@ -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 */ diff --git a/lib/bdev/bdev_rpc.c b/lib/bdev/bdev_rpc.c index ef90d629f..361795b28 100644 --- a/lib/bdev/bdev_rpc.c +++ b/lib/bdev/bdev_rpc.c @@ -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; diff --git a/lib/bdev/spdk_bdev.map b/lib/bdev/spdk_bdev.map index 45f2a49d2..f40a35f66 100644 --- a/lib/bdev/spdk_bdev.map +++ b/lib/bdev/spdk_bdev.map @@ -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;