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 A new option `nvme_error_stat` was added to the `bdev_nvme_set_options` RPC to enable
collecting NVMe error counts. 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 ### event
Added core lock file mechanism to prevent the same CPU cores from being used by multiple 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, void spdk_bdev_get_current_qd(struct spdk_bdev *bdev,
spdk_bdev_get_current_qd_cb cb_fn, void *cb_arg); 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. * Macro used to register module for later initialization.
*/ */

View File

@ -3716,8 +3716,8 @@ bdev_qos_destroy(struct spdk_bdev *bdev)
return 0; return 0;
} }
static void void
bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_stat *add) spdk_bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_stat *add)
{ {
total->bytes_read += add->bytes_read; total->bytes_read += add->bytes_read;
total->num_read_ops += add->num_read_ops; 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 void
bdev_reset_io_stat(struct spdk_bdev_io_stat *stat, enum bdev_reset_stat_mode mode) 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->max_read_latency_ticks = 0;
stat->min_read_latency_ticks = UINT64_MAX; stat->min_read_latency_ticks = UINT64_MAX;
@ -3822,7 +3822,7 @@ bdev_alloc_io_stat(bool io_error_stat)
stat->io_error = NULL; 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; return stat;
} }
@ -3837,7 +3837,7 @@ bdev_free_io_stat(struct spdk_bdev_io_stat *stat)
} }
void 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; 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. */ /* 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); 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); spdk_spin_unlock(&ch->bdev->internal.spinlock);
bdev_abort_all_queued_io(&ch->queued_resets, ch); 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_iostat_ctx *bdev_iostat_ctx = _ctx;
struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch); 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); 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 { struct bdev_iostat_reset_ctx {
enum bdev_reset_stat_mode mode; enum spdk_bdev_reset_stat_mode mode;
bdev_reset_device_stat_cb cb; bdev_reset_device_stat_cb cb;
void *cb_arg; 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 bdev_iostat_reset_ctx *ctx = _ctx;
struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch); 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); spdk_bdev_for_each_channel_continue(i, 0);
} }
void 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) bdev_reset_device_stat_cb cb, void *cb_arg)
{ {
struct bdev_iostat_reset_ctx *ctx; 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; ctx->cb_arg = cb_arg;
spdk_spin_lock(&bdev->internal.spinlock); 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_spin_unlock(&bdev->internal.spinlock);
spdk_bdev_for_each_channel(bdev, 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); 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_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 { enum spdk_bdev_reset_stat_mode;
BDEV_RESET_STAT_ALL,
BDEV_RESET_STAT_MAXMIN,
};
typedef void (*bdev_reset_device_stat_cb)(struct spdk_bdev *bdev, void *cb_arg, int rc); 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); bdev_reset_device_stat_cb cb, void *cb_arg);
#endif /* SPDK_BDEV_INTERNAL_H */ #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)); 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)) { if (spdk_bdev_get_qd_sampling_period(bdev)) {
spdk_json_write_named_uint64(w, "queue_depth_polling_period", 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_object_begin(w);
spdk_json_write_named_uint64(w, "thread_id", spdk_thread_get_id(spdk_get_thread())); 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_json_write_object_end(w);
spdk_bdev_for_each_channel_continue(i, 0); spdk_bdev_for_each_channel_continue(i, 0);
@ -469,7 +469,7 @@ struct rpc_reset_iostat_ctx {
int rc; int rc;
struct spdk_jsonrpc_request *request; struct spdk_jsonrpc_request *request;
struct spdk_json_write_ctx *w; struct spdk_json_write_ctx *w;
enum bdev_reset_stat_mode mode; enum spdk_bdev_reset_stat_mode mode;
}; };
struct bdev_reset_iostat_ctx { struct bdev_reset_iostat_ctx {
@ -546,7 +546,7 @@ bdev_reset_iostat(void *ctx, struct spdk_bdev *bdev)
struct rpc_bdev_reset_iostat { struct rpc_bdev_reset_iostat {
char *name; char *name;
enum bdev_reset_stat_mode mode; enum spdk_bdev_reset_stat_mode mode;
}; };
static void static void
@ -558,7 +558,7 @@ free_rpc_bdev_reset_iostat(struct rpc_bdev_reset_iostat *r)
static int static int
rpc_decode_reset_iostat_mode(const struct spdk_json_val *val, void *out) 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) { if (spdk_json_strequal(val, "all") == true) {
*mode = BDEV_RESET_STAT_ALL; *mode = BDEV_RESET_STAT_ALL;

View File

@ -159,6 +159,9 @@
spdk_bdev_push_media_events; spdk_bdev_push_media_events;
spdk_bdev_notify_media_management; spdk_bdev_notify_media_management;
spdk_bdev_for_each_bdev_io; 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 # Public functions in bdev_zone.h
spdk_bdev_get_zone_size; spdk_bdev_get_zone_size;