Commit 63e0c25d authored by Vasilii Ivanov's avatar Vasilii Ivanov Committed by Konrad Sztyber
Browse files

bdev: add reset_mode to bdev_get_iostat



In current implementation of resetting stats explicit bdev_reset_iostat
call is needed. It is not optimal for usecases
when stat is obtained periodically and then resetted, because
some stats may be lost in between of get and reset.
Introduce new option for bdev_get_iostat that allows to reset stat
right after obtaining it.

Fixes #3525

Change-Id: I77a5ea9310718c25e678336e2450a04fb582c050
Signed-off-by: default avatarVasilii Ivanov <iwanovvvasilij@gmail.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24900


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent e9b86137
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2710,6 +2710,7 @@ Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
name                    | Optional | string      | Block device name
per_channel             | Optional | bool        | Display per channel data for specified block device.
reset_mode              | Optional | string      | Mode to reset I/O statistics after obtaining it: all, maxmin, none (default: none)

#### Response

@@ -2774,7 +2775,7 @@ a block device may be specified by name.
Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
name                    | Optional | string      | Block device name
mode                    | Optional | string      | Mode to reset I/O statistics: all, maxmin (default: all)
mode                    | Optional | string      | Mode to reset I/O statistics: all, maxmin, none (default: all)

#### Example

+13 −2
Original line number Diff line number Diff line
@@ -312,6 +312,15 @@ int spdk_bdev_set_opts(struct spdk_bdev_opts *opts);

typedef void (*spdk_bdev_wait_for_examine_cb)(void *arg);

enum spdk_bdev_reset_stat_mode {
	/** Reset all stats */
	SPDK_BDEV_RESET_STAT_ALL,
	/** Reset only max and min stats */
	SPDK_BDEV_RESET_STAT_MAXMIN,
	/** Do not reset stats at all */
	SPDK_BDEV_RESET_STAT_NONE,
};

/**
 * Report when all bdevs finished the examine process.
 * The registered cb_fn will be called just once.
@@ -2019,10 +2028,11 @@ int spdk_bdev_queue_io_wait(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * \param bdev Block device.
 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel().
 * \param stat The per-channel statistics.
 * \param reset_mode Mode to determine how I/O stat should be reset after obtaining it.
 *
 */
void spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
			   struct spdk_bdev_io_stat *stat);
			   struct spdk_bdev_io_stat *stat, enum spdk_bdev_reset_stat_mode reset_mode);


/**
@@ -2031,11 +2041,12 @@ void spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 *
 * \param bdev Block device to query.
 * \param stat Structure for aggregating collected statistics.  Passed as argument to cb.
 * \param reset_mode Mode to determine how I/O stat should be reset after obtaining it.
 * \param cb Called when this operation completes.
 * \param cb_arg Argument passed to callback function.
 */
void spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat,
			       spdk_bdev_get_device_stat_cb cb, void *cb_arg);
			       enum spdk_bdev_reset_stat_mode reset_mode, spdk_bdev_get_device_stat_cb cb, void *cb_arg);

/**
 * Get the status of bdev_io as an NVMe status code and command specific
+0 −5
Original line number Diff line number Diff line
@@ -1782,11 +1782,6 @@ void spdk_bdev_add_io_stat(struct spdk_bdev_io_stat *total, struct spdk_bdev_io_
 */
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 {
	SPDK_BDEV_RESET_STAT_ALL,
	SPDK_BDEV_RESET_STAT_MAXMIN,
};

/**
 * Reset I/O statistics structure.
 *
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 16
SO_VER := 17
SO_MINOR := 0

C_SRCS = bdev.c bdev_rpc.c bdev_zone.c part.c scsi_nvme.c
+11 −2
Original line number Diff line number Diff line
@@ -360,6 +360,7 @@ struct spdk_bdev_desc {

struct spdk_bdev_iostat_ctx {
	struct spdk_bdev_io_stat *stat;
	enum spdk_bdev_reset_stat_mode reset_mode;
	spdk_bdev_get_device_stat_cb cb;
	void *cb_arg;
};
@@ -4523,6 +4524,10 @@ bdev_get_io_stat(struct spdk_bdev_io_stat *to_stat, struct spdk_bdev_io_stat *fr
void
spdk_bdev_reset_io_stat(struct spdk_bdev_io_stat *stat, enum spdk_bdev_reset_stat_mode mode)
{
	if (mode == SPDK_BDEV_RESET_STAT_NONE) {
		return;
	}

	stat->max_read_latency_ticks = 0;
	stat->min_read_latency_ticks = UINT64_MAX;
	stat->max_write_latency_ticks = 0;
@@ -6690,11 +6695,12 @@ spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,

void
spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
		      struct spdk_bdev_io_stat *stat)
		      struct spdk_bdev_io_stat *stat, enum spdk_bdev_reset_stat_mode reset_mode)
{
	struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch);

	bdev_get_io_stat(stat, channel->stat);
	spdk_bdev_reset_io_stat(stat, reset_mode);
}

static void
@@ -6715,12 +6721,13 @@ bdev_get_each_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev *b
	struct spdk_bdev_channel *channel = __io_ch_to_bdev_ch(ch);

	spdk_bdev_add_io_stat(bdev_iostat_ctx->stat, channel->stat);
	spdk_bdev_reset_io_stat(channel->stat, bdev_iostat_ctx->reset_mode);
	spdk_bdev_for_each_channel_continue(i, 0);
}

void
spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat,
			  spdk_bdev_get_device_stat_cb cb, void *cb_arg)
			  enum spdk_bdev_reset_stat_mode reset_mode, spdk_bdev_get_device_stat_cb cb, void *cb_arg)
{
	struct spdk_bdev_iostat_ctx *bdev_iostat_ctx;

@@ -6738,10 +6745,12 @@ spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat
	bdev_iostat_ctx->stat = stat;
	bdev_iostat_ctx->cb = cb;
	bdev_iostat_ctx->cb_arg = cb_arg;
	bdev_iostat_ctx->reset_mode = reset_mode;

	/* Start with the statistics from previously deleted channels. */
	spdk_spin_lock(&bdev->internal.spinlock);
	bdev_get_io_stat(bdev_iostat_ctx->stat, bdev->internal.stat);
	spdk_bdev_reset_io_stat(bdev->internal.stat, reset_mode);
	spdk_spin_unlock(&bdev->internal.spinlock);

	/* Then iterate and add the statistics from each existing channel. */
Loading