Lib/Bdev: add the new API spdk_bdev_for_each_channel
And also related function pointers and APIs: spdk_bdev_for_each_channel_msg; spdk_bdev_for_each_channel_done; spdk_bdev_for_each_channel_continue; Change-Id: I52f0f6f27717d53c238faf2f998810c9c5ee45d4 Signed-off-by: GangCao <gang.cao@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14614 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Community-CI: Mellanox Build Bot
This commit is contained in:
parent
6a5ecb3276
commit
f0494649e3
@ -13,6 +13,11 @@ Protection information is now supported by the malloc bdev module.
|
||||
Changing scheduler from dynamic back to static is no longer possible,
|
||||
as there is no way of saving original SPDK thread distribution on reactors.
|
||||
|
||||
### bdev
|
||||
|
||||
New APIs `spdk_bdev_for_each_channel` and `spdk_bdev_for_each_channel_continue` and
|
||||
associated function pointers were added to iterate each channel of the required bdev.
|
||||
|
||||
## v22.09
|
||||
|
||||
### accel
|
||||
|
@ -1934,6 +1934,60 @@ size_t spdk_bdev_get_media_events(struct spdk_bdev_desc *bdev_desc,
|
||||
int spdk_bdev_get_memory_domains(struct spdk_bdev *bdev, struct spdk_memory_domain **domains,
|
||||
int array_size);
|
||||
|
||||
/**
|
||||
* \brief SPDK bdev channel iterator.
|
||||
*
|
||||
* This is a virtual representation of a bdev channel iterator.
|
||||
*/
|
||||
struct spdk_bdev_channel_iter;
|
||||
|
||||
/**
|
||||
* Called on the appropriate thread for each channel associated with the given bdev.
|
||||
*
|
||||
* \param i bdev channel iterator.
|
||||
* \param bdev Block device.
|
||||
* \param ch I/O channel.
|
||||
* \param ctx context of the bdev channel iterator.
|
||||
*/
|
||||
typedef void (*spdk_bdev_for_each_channel_msg)(struct spdk_bdev_channel_iter *i,
|
||||
struct spdk_bdev *bdev, struct spdk_io_channel *ch, void *ctx);
|
||||
|
||||
/**
|
||||
* spdk_bdev_for_each_channel() function's final callback with the given bdev.
|
||||
*
|
||||
* \param bdev Block device.
|
||||
* \param ctx context of the bdev channel iterator.
|
||||
* \param status 0 if it completed successfully, or negative errno if it failed.
|
||||
*/
|
||||
typedef void (*spdk_bdev_for_each_channel_done)(struct spdk_bdev *bdev, void *ctx, int status);
|
||||
|
||||
/**
|
||||
* Helper function to iterate the next channel for spdk_bdev_for_each_channel().
|
||||
*
|
||||
* \param i bdev channel iterator.
|
||||
* \param status Status for the bdev channel iterator;
|
||||
* for non 0 status remaining iterations are terminated.
|
||||
*/
|
||||
void spdk_bdev_for_each_channel_continue(struct spdk_bdev_channel_iter *i, int status);
|
||||
|
||||
/**
|
||||
* Call 'fn' on each channel associated with the given bdev.
|
||||
*
|
||||
* This happens asynchronously, so fn may be called after spdk_bdev_for_each_channel
|
||||
* returns. 'fn' will be called for each channel serially, such that two calls
|
||||
* to 'fn' will not overlap in time. After 'fn' has been called, call
|
||||
* spdk_bdev_for_each_channel_continue() to continue iterating. Note that the
|
||||
* spdk_bdev_for_each_channel_continue() function can be called asynchronously.
|
||||
*
|
||||
* \param bdev 'fn' will be called on each channel associated with this given bdev.
|
||||
* \param fn Called on the appropriate thread for each channel associated with the given bdev.
|
||||
* \param ctx Context for the caller.
|
||||
* \param cpl Called on the thread that spdk_bdev_for_each_channel was initially called
|
||||
* from when 'fn' has been called on each channel.
|
||||
*/
|
||||
void spdk_bdev_for_each_channel(struct spdk_bdev *bdev, spdk_bdev_for_each_channel_msg fn,
|
||||
void *ctx, spdk_bdev_for_each_channel_done cpl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
SO_VER := 10
|
||||
SO_MINOR := 0
|
||||
SO_MINOR := 1
|
||||
|
||||
ifeq ($(CONFIG_VTUNE),y)
|
||||
CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify
|
||||
|
@ -321,6 +321,13 @@ struct set_qos_limit_ctx {
|
||||
struct spdk_bdev *bdev;
|
||||
};
|
||||
|
||||
struct spdk_bdev_channel_iter {
|
||||
spdk_bdev_for_each_channel_msg fn;
|
||||
spdk_bdev_for_each_channel_done cpl;
|
||||
struct spdk_io_channel_iter *i;
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
#define __bdev_to_io_dev(bdev) (((char *)bdev) + 1)
|
||||
#define __bdev_from_io_dev(io_dev) ((struct spdk_bdev *)(((char *)io_dev) - 1))
|
||||
|
||||
@ -8033,6 +8040,66 @@ spdk_bdev_for_each_bdev_io(struct spdk_bdev *bdev, void *_ctx, spdk_bdev_io_fn f
|
||||
bdev_for_each_io_done);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_for_each_channel_continue(struct spdk_bdev_channel_iter *iter, int status)
|
||||
{
|
||||
spdk_for_each_channel_continue(iter->i, status);
|
||||
}
|
||||
|
||||
static struct spdk_bdev *
|
||||
io_channel_iter_get_bdev(struct spdk_io_channel_iter *i)
|
||||
{
|
||||
void *io_device = spdk_io_channel_iter_get_io_device(i);
|
||||
|
||||
return __bdev_from_io_dev(io_device);
|
||||
}
|
||||
|
||||
static void
|
||||
bdev_each_channel_msg(struct spdk_io_channel_iter *i)
|
||||
{
|
||||
struct spdk_bdev_channel_iter *iter = spdk_io_channel_iter_get_ctx(i);
|
||||
struct spdk_bdev *bdev = io_channel_iter_get_bdev(i);
|
||||
struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i);
|
||||
|
||||
iter->i = i;
|
||||
iter->fn(iter, bdev, ch, iter->ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
bdev_each_channel_cpl(struct spdk_io_channel_iter *i, int status)
|
||||
{
|
||||
struct spdk_bdev_channel_iter *iter = spdk_io_channel_iter_get_ctx(i);
|
||||
struct spdk_bdev *bdev = io_channel_iter_get_bdev(i);
|
||||
|
||||
iter->i = i;
|
||||
iter->cpl(bdev, iter->ctx, status);
|
||||
|
||||
free(iter);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_for_each_channel(struct spdk_bdev *bdev, spdk_bdev_for_each_channel_msg fn,
|
||||
void *ctx, spdk_bdev_for_each_channel_done cpl)
|
||||
{
|
||||
struct spdk_bdev_channel_iter *iter;
|
||||
|
||||
assert(bdev != NULL && fn != NULL && ctx != NULL);
|
||||
|
||||
iter = calloc(1, sizeof(struct spdk_bdev_channel_iter));
|
||||
if (iter == NULL) {
|
||||
SPDK_ERRLOG("Unable to allocate iterator\n");
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
iter->fn = fn;
|
||||
iter->cpl = cpl;
|
||||
iter->ctx = ctx;
|
||||
|
||||
spdk_for_each_channel(__bdev_to_io_dev(bdev), bdev_each_channel_msg,
|
||||
iter, bdev_each_channel_cpl);
|
||||
}
|
||||
|
||||
SPDK_LOG_REGISTER_COMPONENT(bdev)
|
||||
|
||||
SPDK_TRACE_REGISTER_FN(bdev_trace, "bdev", TRACE_GROUP_BDEV)
|
||||
|
@ -103,6 +103,8 @@
|
||||
spdk_bdev_get_memory_domains;
|
||||
spdk_bdev_readv_blocks_ext;
|
||||
spdk_bdev_writev_blocks_ext;
|
||||
spdk_bdev_for_each_channel;
|
||||
spdk_bdev_for_each_channel_continue;
|
||||
|
||||
# Public functions in bdev_module.h
|
||||
spdk_bdev_register;
|
||||
|
Loading…
Reference in New Issue
Block a user