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:
GangCao 2022-09-21 21:32:37 -04:00 committed by Tomasz Zawadzki
parent 6a5ecb3276
commit f0494649e3
5 changed files with 129 additions and 1 deletions

View File

@ -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, Changing scheduler from dynamic back to static is no longer possible,
as there is no way of saving original SPDK thread distribution on reactors. 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 ## v22.09
### accel ### accel

View File

@ -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 spdk_bdev_get_memory_domains(struct spdk_bdev *bdev, struct spdk_memory_domain **domains,
int array_size); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -7,7 +7,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
SO_VER := 10 SO_VER := 10
SO_MINOR := 0 SO_MINOR := 1
ifeq ($(CONFIG_VTUNE),y) ifeq ($(CONFIG_VTUNE),y)
CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify

View File

@ -321,6 +321,13 @@ struct set_qos_limit_ctx {
struct spdk_bdev *bdev; 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_to_io_dev(bdev) (((char *)bdev) + 1)
#define __bdev_from_io_dev(io_dev) ((struct spdk_bdev *)(((char *)io_dev) - 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); 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_LOG_REGISTER_COMPONENT(bdev)
SPDK_TRACE_REGISTER_FN(bdev_trace, "bdev", TRACE_GROUP_BDEV) SPDK_TRACE_REGISTER_FN(bdev_trace, "bdev", TRACE_GROUP_BDEV)

View File

@ -103,6 +103,8 @@
spdk_bdev_get_memory_domains; spdk_bdev_get_memory_domains;
spdk_bdev_readv_blocks_ext; spdk_bdev_readv_blocks_ext;
spdk_bdev_writev_blocks_ext; spdk_bdev_writev_blocks_ext;
spdk_bdev_for_each_channel;
spdk_bdev_for_each_channel_continue;
# Public functions in bdev_module.h # Public functions in bdev_module.h
spdk_bdev_register; spdk_bdev_register;