Commit 8ddc102a authored by Richael Zhuang's avatar Richael Zhuang Committed by Jim Harris
Browse files

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: default avatarRichael Zhuang <richael.zhuang@arm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16065


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent 2f500a23
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+29 −0
Original line number Diff line number Diff line
@@ -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.
 */
+12 −12
Original line number Diff line number Diff line
@@ -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,
+2 −6
Original line number Diff line number Diff line
@@ -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 */
+5 −5
Original line number Diff line number Diff line
@@ -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;
Loading