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:
parent
1212b53fb8
commit
cad6f55e33
@ -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.
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user