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: Shuhei 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: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
Shuhei Matsumoto 2022-05-24 06:43:18 +09:00 committed by Tomasz Zawadzki
parent 1212b53fb8
commit cad6f55e33
4 changed files with 77 additions and 0 deletions

View File

@ -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.

View File

@ -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.
*/

View File

@ -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)
{

View File

@ -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;