Commit cad6f55e authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

bdev: Add spdk_bdev_get_current_qd to measure and return current value



The generic bdev layer has a public API spdk_bdev_get_qd() but its
value is the most recently measured value and it requires qd sampling
to be enabled. We will have bdev modules to want to wait until
all bdev_ios are aborted by a reset. Unfortunately, spdk_bdev_get_qd()
is not suitable for the custom bdev module. Furthermore,
spdk_bdev_channel::io_outstanding is not accessible from bdev modules.
Hence, add a new public API spdk_bdev_get_current_qd().
This function should be used only from the bdev module and it should
be ensured that the bdev is not unregistered during execution.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: Ica30a8d8fe3264e28f0772a39bdf5f9ba72933e1
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12791


Community-CI: Mellanox Build Bot
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>
parent 1212b53f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ New RPCs `bdev_xnvme_create` and `bdev_xnvme_delete` were added to support the x
A new API `spdk_bdev_for_each_bdev_io` was added to execute the function on the appropriate
thread for each bdev_io submitted to the bdev.

A new API `spdk_bdev_get_current_qd` was added to measure and return the queue depth from a
bdev. This API is available even when queue depth sampling is disabled.

### sock

Added new `ssl` based socket implementation, the code is located in module/sock/posix.
+21 −0
Original line number Diff line number Diff line
@@ -1313,6 +1313,27 @@ typedef void (*spdk_bdev_for_each_io_cb)(void *ctx, int rc);
void spdk_bdev_for_each_bdev_io(struct spdk_bdev *bdev, void *ctx, spdk_bdev_io_fn fn,
				spdk_bdev_for_each_io_cb cb);

typedef void (*spdk_bdev_get_current_qd_cb)(struct spdk_bdev *bdev, uint64_t current_qd,
		void *cb_arg, int rc);

/**
 * Measure and return the queue depth from a bdev.
 *
 * Note: spdk_bdev_get_qd() works only when the user enables queue depth sampling,
 * while this new function works even when queue depth sampling is disabled.
 * The returned queue depth may not be exact, for example, some additional I/Os may
 * have been submitted or completed during the for_each_channel operation.
 * This function should be used only in the bdev module and it should be ensured
 * that the dev is not unregistered while executing the function.
 * cb_fn is required to specify.
 *
 * \param bdev Block device to query.
 * \param cb_fn Callback function to be called with queue depth measured for a bdev.
 * \param cb_arg Argument to pass to callback function.
 */
void spdk_bdev_get_current_qd(struct spdk_bdev *bdev,
			      spdk_bdev_get_current_qd_cb cb_fn, void *cb_arg);

/*
 *  Macro used to register module for later initialization.
 */
+52 −0
Original line number Diff line number Diff line
@@ -4052,6 +4052,58 @@ spdk_bdev_set_qd_sampling_period(struct spdk_bdev *bdev, uint64_t period)
				   bdev, period);
}

struct bdev_get_current_qd_ctx {
	uint64_t current_qd;
	spdk_bdev_get_current_qd_cb cb_fn;
	void *cb_arg;
};

static void
bdev_get_current_qd_done(struct spdk_io_channel_iter *i, int status)
{
	struct bdev_get_current_qd_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
	void *io_dev = spdk_io_channel_iter_get_io_device(i);

	ctx->cb_fn(__bdev_from_io_dev(io_dev), ctx->current_qd, ctx->cb_arg, 0);

	free(ctx);
}

static void
bdev_get_current_qd(struct spdk_io_channel_iter *i)
{
	struct bdev_get_current_qd_ctx *ctx = spdk_io_channel_iter_get_ctx(i);
	struct spdk_io_channel *io_ch = spdk_io_channel_iter_get_channel(i);
	struct spdk_bdev_channel *bdev_ch = spdk_io_channel_get_ctx(io_ch);

	ctx->current_qd += bdev_ch->io_outstanding;

	spdk_for_each_channel_continue(i, 0);
}

void
spdk_bdev_get_current_qd(struct spdk_bdev *bdev, spdk_bdev_get_current_qd_cb cb_fn,
			 void *cb_arg)
{
	struct bdev_get_current_qd_ctx *ctx;

	assert(cb_fn != NULL);

	ctx = calloc(1, sizeof(*ctx));
	if (ctx == NULL) {
		cb_fn(bdev, 0, cb_arg, -ENOMEM);
		return;
	}

	ctx->cb_fn = cb_fn;
	ctx->cb_arg = cb_arg;

	spdk_for_each_channel(__bdev_to_io_dev(bdev),
			      bdev_get_current_qd,
			      ctx,
			      bdev_get_current_qd_done);
}

static void
_resize_notify(void *arg)
{
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
	spdk_bdev_get_dif_type;
	spdk_bdev_is_dif_head_of_md;
	spdk_bdev_is_dif_check_enabled;
	spdk_bdev_get_current_qd;
	spdk_bdev_get_qd;
	spdk_bdev_get_qd_sampling_period;
	spdk_bdev_set_qd_sampling_period;