Commit f0494649 authored by GangCao's avatar GangCao Committed by Tomasz Zawadzki
Browse files

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: default avatarGangCao <gang.cao@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14614


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Community-CI: Mellanox Build Bot
parent 6a5ecb32
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+54 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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
+67 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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;