Commit 1ae735a5 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

nvme: add poll_group interrupt callback



In interrupt mode, IO completions are processed when waiting on
poll_group's fd_group.  But there are some events (qpair disconnection)
that require extra handling.  Normally, this happens in
spdk_nvme_poll_group_wait(), but when manually doing a
spdk_fd_group_wait() on poll_group's fd_group, we need a notification to
get this done.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I08979e42ff57b53f0c97670e9996b0ce6dad713e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25468


Reviewed-by: default avatarAnkit Kumar <ankit.kumar@samsung.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
parent f8047163
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -3065,6 +3065,22 @@ int spdk_nvme_poll_group_get_fd(struct spdk_nvme_poll_group *group);
 */
struct spdk_fd_group *spdk_nvme_poll_group_get_fd_group(struct spdk_nvme_poll_group *group);

typedef void (*spdk_nvme_poll_group_interrupt_cb)(struct spdk_nvme_poll_group *group, void *ctx);

/**
 * Register a callback to notify that a poll group needs to be polled when in interrupt mode.  This
 * isn't required to poll IO completions, but is necessary to process some events, e.g. qpair
 * disconnection.
 *
 * \param group Poll group.
 * \param cb_fn Callback to be executed when the poll group needs to be polled.
 * \param cb_ctx Callback's context.
 *
 * \return 0 on success or negative errno otherwise.
 */
int spdk_nvme_poll_group_set_interrupt_callback(struct spdk_nvme_poll_group *group,
		spdk_nvme_poll_group_interrupt_cb cb_fn, void *cb_ctx);

/**
 * Destroy an empty poll group.
 *
+4 −0
Original line number Diff line number Diff line
@@ -541,6 +541,10 @@ struct spdk_nvme_poll_group {
	bool						enable_interrupts_is_valid;
	int						disconnect_qpair_fd;
	struct spdk_fd_group				*fgrp;
	struct {
		spdk_nvme_poll_group_interrupt_cb	cb_fn;
		void					*cb_ctx;
	} interrupt;
};

struct spdk_nvme_transport_poll_group {
+23 −1
Original line number Diff line number Diff line
@@ -95,6 +95,20 @@ spdk_nvme_poll_group_get_fd_group(struct spdk_nvme_poll_group *group)
	return group->fgrp;
}

int
spdk_nvme_poll_group_set_interrupt_callback(struct spdk_nvme_poll_group *group,
		spdk_nvme_poll_group_interrupt_cb cb_fn, void *cb_ctx)
{
	if (group->interrupt.cb_fn != NULL && cb_fn != NULL) {
		return -EEXIST;
	}

	group->interrupt.cb_fn = cb_fn;
	group->interrupt.cb_ctx = cb_ctx;

	return 0;
}

struct spdk_nvme_poll_group *
spdk_nvme_qpair_get_optimal_poll_group(struct spdk_nvme_qpair *qpair)
{
@@ -113,6 +127,12 @@ spdk_nvme_qpair_get_optimal_poll_group(struct spdk_nvme_qpair *qpair)
static int
nvme_poll_group_read_disconnect_qpair_fd(void *arg)
{
	struct spdk_nvme_poll_group *group = arg;

	if (group->interrupt.cb_fn != NULL) {
		group->interrupt.cb_fn(group, group->interrupt.cb_ctx);
	}

	return 0;
}

@@ -127,7 +147,9 @@ nvme_poll_group_write_disconnect_qpair_fd(struct spdk_nvme_poll_group *group)
	}

	/* Write to the disconnect qpair fd. This will generate event on the epoll fd of poll
	 * group. We then check for disconnected qpairs in spdk_nvme_poll_group_wait() */
	 * group. We then check for disconnected qpairs either in spdk_nvme_poll_group_wait() or
	 * in transport's poll_group_process_completions() callback.
	 */
	rc = write(group->disconnect_qpair_fd, &notify, sizeof(notify));
	if (rc < 0) {
		SPDK_ERRLOG("failed to write the disconnect qpair fd: %s.\n", strerror(errno));
+1 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@
	spdk_nvme_poll_group_wait;
	spdk_nvme_poll_group_get_fd;
	spdk_nvme_poll_group_get_fd_group;
	spdk_nvme_poll_group_set_interrupt_callback;

	spdk_nvme_ns_get_data;
	spdk_nvme_ns_get_id;