Commit 1212b53f authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

bdev: Add spdk_bdev_for_each_bdev_io() to execute function for each bdev_io



Some use cases want to abort every bdev_io submitted to the bdev by
traversing the bdev channels.

However, struct spdk_bdev_channel is private in lib/bdev/bdev.c.

Hence, add a helper function spdk_bdev_for_each_bdev_io() to execute
the function on the appropriate thread for every bdev_io submitted
to the bdev.

This function should be used only from the bdev module and it should
be ensured that the bdev is not unregistered during execution.

We keep this function as generic as possible because we may have
other use cases in future.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: Ic0209361bd1228ea8d4cb3241d0df07106be58d9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12751


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
parent 3851a64f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ an object with an array named "subsystems".

New RPCs `bdev_xnvme_create` and `bdev_xnvme_delete` were added to support the xNVMe bdev.

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.

### sock

Added new `ssl` based socket implementation, the code is located in module/sock/posix.
+20 −0
Original line number Diff line number Diff line
@@ -1293,6 +1293,26 @@ int spdk_bdev_push_media_events(struct spdk_bdev *bdev, const struct spdk_bdev_m
 */
void spdk_bdev_notify_media_management(struct spdk_bdev *bdev);

typedef int (*spdk_bdev_io_fn)(void *ctx, struct spdk_bdev_io *bdev_io);
typedef void (*spdk_bdev_for_each_io_cb)(void *ctx, int rc);

/**
 * Call the provided function on the appropriate thread for each bdev_io submitted
 * to the provided bdev.
 *
 * Note: This function should be used only in the bdev module and it should be
 * ensured that the bdev is not unregistered while executing the function.
 * Both fn and cb are required to specify.
 *
 * \param bdev Block device to query.
 * \param ctx Context passed to the function for each bdev_io and the completion
 * callback function.
 * \param fn Called on the appropriate thread for each bdev_io submitted to the bdev.
 * \param cb Called when this operation completes.
 */
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);

/*
 *  Macro used to register module for later initialization.
 */
+60 −0
Original line number Diff line number Diff line
@@ -7739,6 +7739,66 @@ spdk_bdev_get_memory_domains(struct spdk_bdev *bdev, struct spdk_memory_domain *
	return 0;
}

struct spdk_bdev_for_each_io_ctx {
	void *ctx;
	spdk_bdev_io_fn fn;
	spdk_bdev_for_each_io_cb cb;
};

static void
bdev_channel_for_each_io(struct spdk_io_channel_iter *i)
{
	struct spdk_bdev_for_each_io_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);
	struct spdk_bdev_io *bdev_io;
	int rc = 0;

	TAILQ_FOREACH(bdev_io, &bdev_ch->io_submitted, internal.ch_link) {
		rc = ctx->fn(ctx->ctx, bdev_io);
		if (rc != 0) {
			break;
		}
	}

	spdk_for_each_channel_continue(i, rc);
}

static void
bdev_for_each_io_done(struct spdk_io_channel_iter *i, int status)
{
	struct spdk_bdev_for_each_io_ctx *ctx = spdk_io_channel_iter_get_ctx(i);

	ctx->cb(ctx->ctx, status);

	free(ctx);
}

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)
{
	struct spdk_bdev_for_each_io_ctx *ctx;

	assert(fn != NULL && cb != NULL);

	ctx = calloc(1, sizeof(*ctx));
	if (ctx == NULL) {
		SPDK_ERRLOG("Failed to allocate context.\n");
		cb(_ctx, -ENOMEM);
		return;
	}

	ctx->ctx = _ctx;
	ctx->fn = fn;
	ctx->cb = cb;

	spdk_for_each_channel(__bdev_to_io_dev(bdev),
			      bdev_channel_for_each_io,
			      ctx,
			      bdev_for_each_io_done);
}

SPDK_LOG_REGISTER_COMPONENT(bdev)

SPDK_TRACE_REGISTER_FN(bdev_trace, "bdev", TRACE_GROUP_BDEV)
+1 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@
	spdk_bdev_part_get_offset_blocks;
	spdk_bdev_push_media_events;
	spdk_bdev_notify_media_management;
	spdk_bdev_for_each_bdev_io;

	# Public functions in bdev_zone.h
	spdk_bdev_get_zone_size;