Commit fc551b3a authored by Ben Walker's avatar Ben Walker Committed by Tomasz Zawadzki
Browse files

sock/posix: Make pending_recv shuffle more efficient



Instead of iterating the list, we can just manipulate the list
in a single step.

Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Change-Id: I0172cdbce9af35a62d62dbccfac573e5d723f43a
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6747


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Community-CI: Mellanox Build Bot
parent 1649217a
Loading
Loading
Loading
Loading
+34 −9
Original line number Diff line number Diff line
@@ -75,10 +75,12 @@ struct spdk_posix_sock {
	TAILQ_ENTRY(spdk_posix_sock)	link;
};

TAILQ_HEAD(spdk_pending_recv_list, spdk_posix_sock);

struct spdk_posix_sock_group_impl {
	struct spdk_sock_group_impl	base;
	int				fd;
	TAILQ_HEAD(, spdk_posix_sock)	pending_recv;
	struct spdk_pending_recv_list	pending_recv;
};

static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = {
@@ -1242,6 +1244,8 @@ posix_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_events,
		}
	}

	assert(max_events > 0);

#if defined(SPDK_EPOLL)
	num_events = epoll_wait(group->fd, events, max_events, 0);
#elif defined(SPDK_KEVENT)
@@ -1314,14 +1318,35 @@ posix_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_events,
	}

	/* Cycle the pending_recv list so that each time we poll things aren't
	 * in the same order.
	 * TODO: This could be done with a single operation because psock points
	 * to the last node that needs to get cycled already. */
	for (i = 0; i < num_events; i++) {
		psock = __posix_sock(socks[i]);

		TAILQ_REMOVE(&group->pending_recv, psock, link);
		TAILQ_INSERT_TAIL(&group->pending_recv, psock, link);
	 * in the same order. Say we have 6 sockets in the list, named as follows:
	 * A B C D E F
	 * And all 6 sockets had epoll events, but max_events is only 3. That means
	 * psock currently points at D. We want to rearrange the list to the following:
	 * D E F A B C
	 *
	 * The variables below are named according to this example to make it easier to
	 * follow the swaps.
	 */
	if (psock != NULL) {
		struct spdk_posix_sock *pa, *pc, *pd, *pf;

		/* Capture pointers to the elements we need */
		pd = psock;
		pc = TAILQ_PREV(pd, spdk_pending_recv_list, link);
		pa = TAILQ_FIRST(&group->pending_recv);
		pf = TAILQ_LAST(&group->pending_recv, spdk_pending_recv_list);

		/* Break the link between C and D */
		pc->link.tqe_next = NULL;
		pd->link.tqe_prev = NULL;

		/* Connect F to A */
		pf->link.tqe_next = pa;
		pa->link.tqe_prev = &pf->link.tqe_next;

		/* Fix up the list first/last pointers */
		group->pending_recv.tqh_first = pd;
		group->pending_recv.tqh_last = &pc->link.tqe_next;
	}

	return num_events;