Commit c7d1c506 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

sock/uring: reorder task cancellations in remove_sock



When removing a socket from a sock_group, the recv_task should be
cancelled last, because it can be sent out while cancelling other tasks
(if POLLERR is received).  Otherwise, we could end up with outstanding
recv requests from a socket removed from a group.

Fixes #2112.

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


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarZiye Yang <ziye.yang@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 57d60b9f
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1409,25 +1409,31 @@ uring_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group,
		}
	}

	if (sock->recv_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		_sock_prep_cancel_task(_sock, &sock->recv_task);
	if (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		_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->recv_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) ||
		while ((sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) ||
		       (sock->cancel_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE)) {
			uring_sock_group_impl_poll(_group, 32, NULL);
		}
	}

	if (sock->pollin_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		_sock_prep_cancel_task(_sock, &sock->pollin_task);
	if (sock->recv_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) {
		_sock_prep_cancel_task(_sock, &sock->recv_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) ||
		while ((sock->recv_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE) ||
		       (sock->cancel_task.status != SPDK_URING_SOCK_TASK_NOT_IN_USE)) {
			uring_sock_group_impl_poll(_group, 32, NULL);
		}
	}

	/* Make sure the cancelling the tasks above didn't cause sending new requests */
	assert(sock->write_task.status == SPDK_URING_SOCK_TASK_NOT_IN_USE);
	assert(sock->pollin_task.status == SPDK_URING_SOCK_TASK_NOT_IN_USE);
	assert(sock->recv_task.status == SPDK_URING_SOCK_TASK_NOT_IN_USE);

	if (sock->pending_recv) {
		TAILQ_REMOVE(&group->pending_recv, sock, link);
		sock->pending_recv = false;