Commit f5d63dfa authored by Ziye Yang's avatar Ziye Yang Committed by Tomasz Zawadzki
Browse files

uring: Add the feature to cancel the active pollin task.



We should add the cancel task feature in uring if
sock is removed from the group.

This issue is detected after the group polling
feature is added in NVMe tcp initiatator side. Before
the patch, SPDK NVMe initiator side will not use
group polling feature. After the group polling
feature added in the iniatiator side, we should add this
patch.

Signed-off-by: default avatarZiye Yang <ziye.yang@intel.com>
Change-Id: I012b403a9f57a5a8ee96c83471b775f0d99b9eb6
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2049


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>
parent a3e5b5d0
Loading
Loading
Loading
Loading
+47 −8
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@
enum spdk_sock_task_type {
	SPDK_SOCK_TASK_POLLIN = 0,
	SPDK_SOCK_TASK_WRITE,
	SPDK_SOCK_TASK_CANCEL,
};

enum spdk_uring_sock_task_status {
@@ -82,6 +83,7 @@ struct spdk_uring_sock {
	struct spdk_uring_sock_group_impl	*group;
	struct spdk_uring_task			write_task;
	struct spdk_uring_task			pollin_task;
	struct spdk_uring_task			cancel_task;
	int					outstanding_io;
	struct spdk_pipe			*recv_pipe;
	void					*recv_buf;
@@ -858,6 +860,26 @@ _sock_prep_pollin(struct spdk_sock *_sock)
	task->status = SPDK_URING_SOCK_TASK_IN_PROCESS;
}

static void
_sock_prep_cancel_task(struct spdk_sock *_sock, void *user_data)
{
	struct spdk_uring_sock *sock = __uring_sock(_sock);
	struct spdk_uring_task *task = &sock->cancel_task;
	struct io_uring_sqe *sqe;

	if (task->status == SPDK_URING_SOCK_TASK_IN_PROCESS) {
		return;
	}

	assert(sock->group != NULL);
	sock->group->io_queued++;

	sqe = io_uring_get_sqe(&sock->group->uring);
	io_uring_prep_cancel(sqe, user_data, 0);
	io_uring_sqe_set_data(sqe, task);
	task->status = SPDK_URING_SOCK_TASK_IN_PROCESS;
}

static int
spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, int max_read_events,
			   struct spdk_sock **socks)
@@ -919,7 +941,6 @@ spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, in
			if (spdk_unlikely(task->sock->outstanding_io > 0 &&
					  TAILQ_EMPTY(&sock->base.pending_reqs))) {
				if (--sock->outstanding_io == 0) {
					sock->group = NULL;
					/* Just for sock close case */
					if (sock->base.flags.closed) {
						spdk_uring_sock_close(&sock->base);
@@ -927,6 +948,11 @@ spdk_sock_uring_group_reap(struct spdk_uring_sock_group_impl *group, int max, in
				}
			}

			break;
		case SPDK_SOCK_TASK_CANCEL:
			if ((status == 0) && (sock->outstanding_io > 0)) {
				sock->outstanding_io--;
			}
			break;
		default:
			SPDK_UNREACHABLE();
@@ -1151,6 +1177,9 @@ spdk_uring_sock_group_impl_add_sock(struct spdk_sock_group_impl *_group,
	sock->pollin_task.sock = sock;
	sock->pollin_task.type = SPDK_SOCK_TASK_POLLIN;

	sock->cancel_task.sock = sock;
	sock->cancel_task.type = SPDK_SOCK_TASK_CANCEL;

	/* switched from another polling group due to scheduling */
	if (spdk_unlikely(sock->recv_pipe != NULL &&
			  (spdk_pipe_reader_bytes_available(sock->recv_pipe) > 0))) {
@@ -1207,13 +1236,21 @@ spdk_uring_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group,
	struct spdk_uring_sock *sock = __uring_sock(_sock);
	struct spdk_uring_sock_group_impl *group = __uring_group_impl(_group);


	if (sock->write_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		/* For write, we do not need to cancel it */
		sock->outstanding_io++;
	}

	if (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		sock->outstanding_io++;
		_sock_prep_cancel_task(_sock, &sock->pollin_task);
	}


	/* Since spdk_sock_group_remove_sock is not asynchronous interface, so
	 * currently can use a while loop here. */
	while (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		spdk_uring_sock_group_impl_poll(_group, 32, NULL);
	}

	if (sock->recv_pipe != NULL) {
@@ -1223,11 +1260,7 @@ spdk_uring_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group,
		}
		assert(sock->pending_recv == false);
	}

	if (!sock->outstanding_io) {
	sock->group = NULL;
	}

	return 0;
}

@@ -1253,9 +1286,15 @@ spdk_uring_sock_group_impl_close(struct spdk_sock_group_impl *_group)
static int
spdk_uring_sock_flush(struct spdk_sock *_sock)
{
	struct spdk_uring_sock *sock = __uring_sock(_sock);

	if (!sock->group) {
		return _sock_flush_client(_sock);
	}

	return 0;
}

static struct spdk_net_impl g_uring_net_impl = {
	.name		= "uring",
	.getaddr	= spdk_uring_sock_getaddr,