Commit 8a6de262 authored by Martin Karsten's avatar Martin Karsten Committed by Jakub Kicinski
Browse files

eventpoll: Control irq suspension for prefer_busy_poll



When events are reported to userland and prefer_busy_poll is set, irqs
are temporarily suspended using napi_suspend_irqs.

If no events are found and ep_poll would go to sleep, irq suspension is
cancelled using napi_resume_irqs.

Signed-off-by: default avatarMartin Karsten <mkarsten@uwaterloo.ca>
Co-developed-by: default avatarJoe Damato <jdamato@fastly.com>
Signed-off-by: default avatarJoe Damato <jdamato@fastly.com>
Tested-by: default avatarJoe Damato <jdamato@fastly.com>
Tested-by: default avatarMartin Karsten <mkarsten@uwaterloo.ca>
Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Reviewed-by: default avatarSridhar Samudrala <sridhar.samudrala@intel.com>
Link: https://patch.msgid.link/20241109050245.191288-5-jdamato@fastly.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ab5b28b0
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -457,6 +457,8 @@ static bool ep_busy_loop(struct eventpoll *ep, int nonblock)
		 * it back in when we have moved a socket with a valid NAPI
		 * ID onto the ready list.
		 */
		if (prefer_busy_poll)
			napi_resume_irqs(napi_id);
		ep->napi_id = 0;
		return false;
	}
@@ -540,6 +542,22 @@ static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
	}
}

static void ep_suspend_napi_irqs(struct eventpoll *ep)
{
	unsigned int napi_id = READ_ONCE(ep->napi_id);

	if (napi_id >= MIN_NAPI_ID && READ_ONCE(ep->prefer_busy_poll))
		napi_suspend_irqs(napi_id);
}

static void ep_resume_napi_irqs(struct eventpoll *ep)
{
	unsigned int napi_id = READ_ONCE(ep->napi_id);

	if (napi_id >= MIN_NAPI_ID && READ_ONCE(ep->prefer_busy_poll))
		napi_resume_irqs(napi_id);
}

#else

static inline bool ep_busy_loop(struct eventpoll *ep, int nonblock)
@@ -557,6 +575,14 @@ static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
	return -EOPNOTSUPP;
}

static void ep_suspend_napi_irqs(struct eventpoll *ep)
{
}

static void ep_resume_napi_irqs(struct eventpoll *ep)
{
}

#endif /* CONFIG_NET_RX_BUSY_POLL */

/*
@@ -788,6 +814,7 @@ static bool ep_refcount_dec_and_test(struct eventpoll *ep)

static void ep_free(struct eventpoll *ep)
{
	ep_resume_napi_irqs(ep);
	mutex_destroy(&ep->mtx);
	free_uid(ep->user);
	wakeup_source_unregister(ep->ws);
@@ -2005,9 +2032,12 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
			 * trying again in search of more luck.
			 */
			res = ep_send_events(ep, events, maxevents);
			if (res)
			if (res) {
				if (res > 0)
					ep_suspend_napi_irqs(ep);
				return res;
			}
		}

		if (timed_out)
			return 0;