linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/3] Per epoll context busy poll support
@ 2024-01-25 22:56 Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 1/3] eventpoll: support busy poll per epoll instance Joe Damato
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-25 22:56 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: chuck.lever, jlayton, linux-api, brauner, edumazet, davem,
	alexander.duyck, sridhar.samudrala, kuba, willemdebruijn.kernel,
	weiwan, Joe Damato, Alexander Viro, Andrew Waterman,
	Arnd Bergmann, Dominik Brodowski, Greg Kroah-Hartman, Jan Kara,
	Jiri Slaby, Jonathan Corbet, Julien Panis,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure),
	Michael Ellerman, Nathan Lynch, Palmer Dabbelt, Steve French,
	Thomas Huth, Thomas Zimmermann

Greetings:

Welcome to v3. Cover letter updated from v2 to explain why ioctl and
adjusted my cc_cmd to try to get the correct people in addition to folks
who were added in v1 & v2. Labeled as net-next because it seems networking
related to me even though it is fs code.

TL;DR This builds on commit bf3b9f6372c4 ("epoll: Add busy poll support to
epoll with socket fds.") by allowing user applications to enable
epoll-based busy polling and set a busy poll packet budget on a per epoll
context basis.

This makes epoll-based busy polling much more usable for user
applications than the current system-wide sysctl and hardcoded budget.

To allow for this, two ioctls have been added for epoll contexts for
getting and setting a new struct, struct epoll_params.

ioctl was chosen vs a new syscall after reviewing a suggestion by Willem
de Bruijn [1]. I am open to using a new syscall instead of an ioctl, but it
seemed that: 
  - Busy poll affects all existing epoll_wait and epoll_pwait variants in
    the same way, so new verions of many syscalls might be needed. It
    seems much simpler for users to use the correct
    epoll_wait/epoll_pwait for their app and add a call to ioctl to enable
    or disable busy poll as needed. This also probably means less work to
    get an existing epoll app using busy poll.

  - previously added epoll_pwait2 helped to bring epoll closer to
    existing syscalls (like pselect and ppoll) and this busy poll change
    reflected as a new syscall would not have the same effect.

Note: patch 1/4 uses an xor so that busy poll is only enabled if the
per-context busy poll usecs is set or the system-wide sysctl. If both are
enabled, busy polling does not happen. Calling this out specifically incase
there are strong feelings about this one; I felt one xor the other made
sense, but I am open to changing it.

Longer explanation:

Presently epoll has support for a very useful form of busy poll based on
the incoming NAPI ID (see also: SO_INCOMING_NAPI_ID [2]).

This form of busy poll allows epoll_wait to drive NAPI packet processing
which allows for a few interesting user application designs which can
reduce latency and also potentially improve L2/L3 cache hit rates by
deferring NAPI until userland has finished its work.

The documentation available on this is, IMHO, a bit confusing so please
allow me to explain how one might use this:

1. Ensure each application thread has its own epoll instance mapping
1-to-1 with NIC RX queues. An n-tuple filter would likely be used to
direct connections with specific dest ports to these queues.

2. Optionally: Setup IRQ coalescing for the NIC RX queues where busy
polling will occur. This can help avoid the userland app from being
pre-empted by a hard IRQ while userland is running. Note this means that
userland must take care to call epoll_wait and not take too long in
userland since it now drives NAPI via epoll_wait.

3. Optionally: Consider using napi_defer_hard_irqs and gro_flush_timeout to
further restrict IRQ generation from the NIC. These settings are
system-wide so their impact must be carefully weighed against the running
applications.

4. Ensure that all incoming connections added to an epoll instance
have the same NAPI ID. This can be done with a BPF filter when
SO_REUSEPORT is used or getsockopt + SO_INCOMING_NAPI_ID when a single
accept thread is used which dispatches incoming connections to threads.

5. Lastly, busy poll must be enabled via a sysctl
(/proc/sys/net/core/busy_poll).

Please see Eric Dumazet's paper about busy polling [3] and a recent
academic paper about measured performance improvements of busy polling [4]
(albeit with a modification that is not currently present in the kernel)
for additional context.

The unfortunate part about step 5 above is that this enables busy poll
system-wide which affects all user applications on the system,
including epoll-based network applications which were not intended to
be used this way or applications where increased CPU usage for lower
latency network processing is unnecessary or not desirable.

If the user wants to run one low latency epoll-based server application
with epoll-based busy poll, but would like to run the rest of the
applications on the system (which may also use epoll) without busy poll,
this system-wide sysctl presents a significant problem.

This change preserves the system-wide sysctl, but adds a mechanism (via
ioctl) to enable or disable busy poll for epoll contexts as needed by
individual applications, making epoll-based busy poll more usable. Note
that this change includes an xor allowing only the per-context busy poll or
the system wide sysctl, not both. If both are enabled, busy polling does
not happen. Calling this out specifically incase there are strong feelings
about this one; I felt one xor the other made sense, but I am open to
changing it.

Thanks,
Joe

v2 -> v3:
  - cover letter updated to mention why ioctl seems (to me) like a better
    choice vs a new syscall.

  - patch 3/4 was modified in 3 ways:
    - when an unknown ioctl is received, -ENOIOCTLCMD is returned instead
      of -EINVAL as the ioctl documentation requires.
    - epoll_params.busy_poll_budget can only be set to a value larger than
      NAPI_POLL_WEIGHT if code is run by privileged (CAP_NET_ADMIN) users.
      Otherwise, -EPERM is returned.
    - busy poll specific ioctl code moved out to its own function. On
      kernels without busy poll support, -EOPNOTSUPP is returned. This also
      makes the kernel build robot happier without littering the code with
      more #ifdefs.

  - dropped patch 4/4 after Eric Dumazet's review of it when it was sent
    independently to the list [5].

v1 -> v2:
  - cover letter updated to make a mention of napi_defer_hard_irqs and
    gro_flush_timeout as an added step 3 and to cite both Eric Dumazet's
    busy polling paper and a paper from University of Waterloo for
    additional context. Specifically calling out the xor in patch 1/4
    incase it is missed by reviewers.

  - Patch 2/4 has its commit message updated, but no functional changes.
    Commit message now describes that allowing for a settable budget helps
    to improve throughput and is more consistent with other busy poll
    mechanisms that allow a settable budget via SO_BUSY_POLL_BUDGET.

  - Patch 3/4 was modified to check if the epoll_params.busy_poll_budget
    exceeds NAPI_POLL_WEIGHT. The larger value is allowed, but an error is
    printed. This was done for consistency with netif_napi_add_weight,
    which does the same.

  - Patch 3/4 the struct epoll_params was updated to fix the type of the
    data field; it was uint8_t and was changed to u8.

  - Patch 4/4 added to check if SO_BUSY_POLL_BUDGET exceeds
    NAPI_POLL_WEIGHT. The larger value is allowed, but an error is
    printed. This was done for consistency with netif_napi_add_weight,
    which does the same.

[1]: https://lore.kernel.org/lkml/65b1cb7f73a6a_250560294bd@willemb.c.googlers.com.notmuch/
[2]: https://lore.kernel.org/lkml/20170324170836.15226.87178.stgit@localhost.localdomain/
[3]: https://netdevconf.info/2.1/papers/BusyPollingNextGen.pdf
[4]: https://dl.acm.org/doi/pdf/10.1145/3626780
[5]: https://lore.kernel.org/lkml/CANn89i+uXsdSVFiQT9fDfGw+h_5QOcuHwPdWi9J=5U6oLXkQTA@mail.gmail.com/

Joe Damato (3):
  eventpoll: support busy poll per epoll instance
  eventpoll: Add per-epoll busy poll packet budget
  eventpoll: Add epoll ioctl for epoll_params

 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 fs/eventpoll.c                                | 122 +++++++++++++++++-
 include/uapi/linux/eventpoll.h                |  12 ++
 3 files changed, 130 insertions(+), 5 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH net-next v3 1/3] eventpoll: support busy poll per epoll instance
  2024-01-25 22:56 [PATCH net-next v3 0/3] Per epoll context busy poll support Joe Damato
@ 2024-01-25 22:56 ` Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 2/3] eventpoll: Add per-epoll busy poll packet budget Joe Damato
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-25 22:56 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: chuck.lever, jlayton, linux-api, brauner, edumazet, davem,
	alexander.duyck, sridhar.samudrala, kuba, willemdebruijn.kernel,
	weiwan, Joe Damato, Alexander Viro, Jan Kara,
	open list:FILESYSTEMS (VFS and infrastructure)

Allow busy polling on a per-epoll context basis. The per-epoll context
usec timeout value is preferred, but the pre-existing system wide sysctl
value is still supported if it specified.

Note that this change uses an xor: either per epoll instance busy polling
is enabled on the epoll instance or system wide epoll is enabled. Enabling
both is disallowed.

Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 fs/eventpoll.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 3534d36a1474..4503fec01278 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -227,6 +227,8 @@ struct eventpoll {
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	/* used to track busy poll napi_id */
 	unsigned int napi_id;
+	/* busy poll timeout */
+	u64 busy_poll_usecs;
 #endif
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -386,12 +388,44 @@ static inline int ep_events_available(struct eventpoll *ep)
 		READ_ONCE(ep->ovflist) != EP_UNACTIVE_PTR;
 }
 
+/**
+ * busy_loop_ep_timeout - check if busy poll has timed out. The timeout value
+ * from the epoll instance ep is preferred, but if it is not set fallback to
+ * the system-wide global via busy_loop_timeout.
+ *
+ * @start_time: The start time used to compute the remaining time until timeout.
+ * @ep: Pointer to the eventpoll context.
+ *
+ * Return: true if the timeout has expired, false otherwise.
+ */
+static inline bool busy_loop_ep_timeout(unsigned long start_time, struct eventpoll *ep)
+{
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	unsigned long bp_usec = READ_ONCE(ep->busy_poll_usecs);
+
+	if (bp_usec) {
+		unsigned long end_time = start_time + bp_usec;
+		unsigned long now = busy_loop_current_time();
+
+		return time_after(now, end_time);
+	} else {
+		return busy_loop_timeout(start_time);
+	}
+#endif
+	return true;
+}
+
 #ifdef CONFIG_NET_RX_BUSY_POLL
+static bool ep_busy_loop_on(struct eventpoll *ep)
+{
+	return !!ep->busy_poll_usecs ^ net_busy_loop_on();
+}
+
 static bool ep_busy_loop_end(void *p, unsigned long start_time)
 {
 	struct eventpoll *ep = p;
 
-	return ep_events_available(ep) || busy_loop_timeout(start_time);
+	return ep_events_available(ep) || busy_loop_ep_timeout(start_time, ep);
 }
 
 /*
@@ -404,7 +438,7 @@ static bool ep_busy_loop(struct eventpoll *ep, int nonblock)
 {
 	unsigned int napi_id = READ_ONCE(ep->napi_id);
 
-	if ((napi_id >= MIN_NAPI_ID) && net_busy_loop_on()) {
+	if ((napi_id >= MIN_NAPI_ID) && ep_busy_loop_on(ep)) {
 		napi_busy_loop(napi_id, nonblock ? NULL : ep_busy_loop_end, ep, false,
 			       BUSY_POLL_BUDGET);
 		if (ep_events_available(ep))
@@ -430,7 +464,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 	struct socket *sock;
 	struct sock *sk;
 
-	if (!net_busy_loop_on())
+	ep = epi->ep;
+	if (!ep_busy_loop_on(ep))
 		return;
 
 	sock = sock_from_file(epi->ffd.file);
@@ -442,7 +477,6 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 		return;
 
 	napi_id = READ_ONCE(sk->sk_napi_id);
-	ep = epi->ep;
 
 	/* Non-NAPI IDs can be rejected
 	 *	or
@@ -466,6 +500,10 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 {
 }
 
+static inline bool ep_busy_loop_on(struct eventpoll *ep)
+{
+	return false;
+}
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 
 /*
@@ -2058,6 +2096,9 @@ static int do_epoll_create(int flags)
 		error = PTR_ERR(file);
 		goto out_free_fd;
 	}
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	ep->busy_poll_usecs = 0;
+#endif
 	ep->file = file;
 	fd_install(fd, file);
 	return fd;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v3 2/3] eventpoll: Add per-epoll busy poll packet budget
  2024-01-25 22:56 [PATCH net-next v3 0/3] Per epoll context busy poll support Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 1/3] eventpoll: support busy poll per epoll instance Joe Damato
@ 2024-01-25 22:56 ` Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
  2024-01-27 16:20 ` [PATCH net-next v3 0/3] Per epoll context busy poll support Willem de Bruijn
  3 siblings, 0 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-25 22:56 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: chuck.lever, jlayton, linux-api, brauner, edumazet, davem,
	alexander.duyck, sridhar.samudrala, kuba, willemdebruijn.kernel,
	weiwan, Joe Damato, Alexander Viro, Jan Kara,
	open list:FILESYSTEMS (VFS and infrastructure)

When using epoll-based busy poll, the packet budget is hardcoded to
BUSY_POLL_BUDGET (8). Users may desire larger busy poll budgets, which
can potentially increase throughput when busy polling under high network
load.

Other busy poll methods allow setting the busy poll budget via
SO_BUSY_POLL_BUDGET, but epoll-based busy polling uses a hardcoded
value.

Fix this edge case by adding support for a per-epoll context busy poll
packet budget. If not specified, the default value (BUSY_POLL_BUDGET) is
used.

Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 fs/eventpoll.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 4503fec01278..40bd97477b91 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -229,6 +229,8 @@ struct eventpoll {
 	unsigned int napi_id;
 	/* busy poll timeout */
 	u64 busy_poll_usecs;
+	/* busy poll packet budget */
+	u16 busy_poll_budget;
 #endif
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -437,10 +439,14 @@ static bool ep_busy_loop_end(void *p, unsigned long start_time)
 static bool ep_busy_loop(struct eventpoll *ep, int nonblock)
 {
 	unsigned int napi_id = READ_ONCE(ep->napi_id);
+	u16 budget = READ_ONCE(ep->busy_poll_budget);
+
+	if (!budget)
+		budget = BUSY_POLL_BUDGET;
 
 	if ((napi_id >= MIN_NAPI_ID) && ep_busy_loop_on(ep)) {
 		napi_busy_loop(napi_id, nonblock ? NULL : ep_busy_loop_end, ep, false,
-			       BUSY_POLL_BUDGET);
+			       budget);
 		if (ep_events_available(ep))
 			return true;
 		/*
@@ -2098,6 +2104,7 @@ static int do_epoll_create(int flags)
 	}
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	ep->busy_poll_usecs = 0;
+	ep->busy_poll_budget = 0;
 #endif
 	ep->file = file;
 	fd_install(fd, file);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 22:56 [PATCH net-next v3 0/3] Per epoll context busy poll support Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 1/3] eventpoll: support busy poll per epoll instance Joe Damato
  2024-01-25 22:56 ` [PATCH net-next v3 2/3] eventpoll: Add per-epoll busy poll packet budget Joe Damato
@ 2024-01-25 22:56 ` Joe Damato
  2024-01-25 23:20   ` Greg Kroah-Hartman
                     ` (3 more replies)
  2024-01-27 16:20 ` [PATCH net-next v3 0/3] Per epoll context busy poll support Willem de Bruijn
  3 siblings, 4 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-25 22:56 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: chuck.lever, jlayton, linux-api, brauner, edumazet, davem,
	alexander.duyck, sridhar.samudrala, kuba, willemdebruijn.kernel,
	weiwan, Joe Damato, Jonathan Corbet, Alexander Viro, Jan Kara,
	Michael Ellerman, Greg Kroah-Hartman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

Add an ioctl for getting and setting epoll_params. User programs can use
this ioctl to get and set the busy poll usec time or packet budget
params for a specific epoll context.

Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 .../userspace-api/ioctl/ioctl-number.rst      |  1 +
 fs/eventpoll.c                                | 64 +++++++++++++++++++
 include/uapi/linux/eventpoll.h                | 12 ++++
 3 files changed, 77 insertions(+)

diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 457e16f06e04..b33918232f78 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -309,6 +309,7 @@ Code  Seq#    Include File                                           Comments
 0x89  0B-DF  linux/sockios.h
 0x89  E0-EF  linux/sockios.h                                         SIOCPROTOPRIVATE range
 0x89  F0-FF  linux/sockios.h                                         SIOCDEVPRIVATE range
+0x8A  00-1F  linux/eventpoll.h
 0x8B  all    linux/wireless.h
 0x8C  00-3F                                                          WiNRADiO driver
                                                                      <http://www.winradio.com.au/>
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 40bd97477b91..73ae886efb8a 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -6,6 +6,8 @@
  *  Davide Libenzi <davidel@xmailserver.org>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched/signal.h>
@@ -37,6 +39,7 @@
 #include <linux/seq_file.h>
 #include <linux/compat.h>
 #include <linux/rculist.h>
+#include <linux/capability.h>
 #include <net/busy_poll.h>
 
 /*
@@ -495,6 +498,39 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 	ep->napi_id = napi_id;
 }
 
+static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	struct eventpoll *ep;
+	struct epoll_params epoll_params;
+	void __user *uarg = (void __user *) arg;
+
+	ep = file->private_data;
+
+	switch (cmd) {
+	case EPIOCSPARAMS:
+		if (copy_from_user(&epoll_params, uarg, sizeof(epoll_params)))
+			return -EFAULT;
+
+		if (epoll_params.busy_poll_budget > NAPI_POLL_WEIGHT &&
+		    !capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		ep->busy_poll_usecs = epoll_params.busy_poll_usecs;
+		ep->busy_poll_budget = epoll_params.busy_poll_budget;
+		return 0;
+	case EPIOCGPARAMS:
+		memset(&epoll_params, 0, sizeof(epoll_params));
+		epoll_params.busy_poll_usecs = ep->busy_poll_usecs;
+		epoll_params.busy_poll_budget = ep->busy_poll_budget;
+		if (copy_to_user(uarg, &epoll_params, sizeof(epoll_params)))
+			return -EFAULT;
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 #else
 
 static inline bool ep_busy_loop(struct eventpoll *ep, int nonblock)
@@ -510,6 +546,12 @@ static inline bool ep_busy_loop_on(struct eventpoll *ep)
 {
 	return false;
 }
+
+static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 
 /*
@@ -869,6 +911,26 @@ static void ep_clear_and_put(struct eventpoll *ep)
 		ep_free(ep);
 }
 
+static long ep_eventpoll_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int ret;
+
+	if (!is_file_epoll(file))
+		return -EINVAL;
+
+	switch (cmd) {
+	case EPIOCSPARAMS:
+	case EPIOCGPARAMS:
+		ret = ep_eventpoll_bp_ioctl(file, cmd, arg);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 static int ep_eventpoll_release(struct inode *inode, struct file *file)
 {
 	struct eventpoll *ep = file->private_data;
@@ -975,6 +1037,8 @@ static const struct file_operations eventpoll_fops = {
 	.release	= ep_eventpoll_release,
 	.poll		= ep_eventpoll_poll,
 	.llseek		= noop_llseek,
+	.unlocked_ioctl	= ep_eventpoll_ioctl,
+	.compat_ioctl   = compat_ptr_ioctl,
 };
 
 /*
diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
index cfbcc4cc49ac..8eb0fdbce995 100644
--- a/include/uapi/linux/eventpoll.h
+++ b/include/uapi/linux/eventpoll.h
@@ -85,4 +85,16 @@ struct epoll_event {
 	__u64 data;
 } EPOLL_PACKED;
 
+struct epoll_params {
+	u64 busy_poll_usecs;
+	u16 busy_poll_budget;
+
+	/* for future fields */
+	u8 data[118];
+} EPOLL_PACKED;
+
+#define EPOLL_IOC_TYPE 0x8A
+#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
+#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
+
 #endif /* _UAPI_LINUX_EVENTPOLL_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
@ 2024-01-25 23:20   ` Greg Kroah-Hartman
  2024-01-26  0:04     ` Joe Damato
  2024-01-25 23:21   ` Greg Kroah-Hartman
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 20+ messages in thread
From: Greg Kroah-Hartman @ 2024-01-25 23:20 UTC (permalink / raw)
  To: Joe Damato
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> --- a/fs/eventpoll.c
> +++ b/fs/eventpoll.c
> @@ -6,6 +6,8 @@
>   *  Davide Libenzi <davidel@xmailserver.org>
>   */
>  
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +

Why this addition?  You do not add any pr_*() calls in this patch at all
that I can see.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
  2024-01-25 23:20   ` Greg Kroah-Hartman
@ 2024-01-25 23:21   ` Greg Kroah-Hartman
  2024-01-26  0:11     ` Joe Damato
  2024-01-25 23:22   ` Greg Kroah-Hartman
  2024-01-28 11:24   ` kernel test robot
  3 siblings, 1 reply; 20+ messages in thread
From: Greg Kroah-Hartman @ 2024-01-25 23:21 UTC (permalink / raw)
  To: Joe Damato
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> +struct epoll_params {
> +	u64 busy_poll_usecs;
> +	u16 busy_poll_budget;
> +
> +	/* for future fields */
> +	u8 data[118];
> +} EPOLL_PACKED;

variables that cross the user/kernel boundry need to be __u64, __u16,
and __u8 here.

And why 118?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
  2024-01-25 23:20   ` Greg Kroah-Hartman
  2024-01-25 23:21   ` Greg Kroah-Hartman
@ 2024-01-25 23:22   ` Greg Kroah-Hartman
  2024-01-26  0:07     ` Joe Damato
  2024-01-28 11:24   ` kernel test robot
  3 siblings, 1 reply; 20+ messages in thread
From: Greg Kroah-Hartman @ 2024-01-25 23:22 UTC (permalink / raw)
  To: Joe Damato
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> Add an ioctl for getting and setting epoll_params. User programs can use
> this ioctl to get and set the busy poll usec time or packet budget
> params for a specific epoll context.
> 
> Signed-off-by: Joe Damato <jdamato@fastly.com>
> ---
>  .../userspace-api/ioctl/ioctl-number.rst      |  1 +
>  fs/eventpoll.c                                | 64 +++++++++++++++++++
>  include/uapi/linux/eventpoll.h                | 12 ++++
>  3 files changed, 77 insertions(+)
> 
> diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
> index 457e16f06e04..b33918232f78 100644
> --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
> +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
> @@ -309,6 +309,7 @@ Code  Seq#    Include File                                           Comments
>  0x89  0B-DF  linux/sockios.h
>  0x89  E0-EF  linux/sockios.h                                         SIOCPROTOPRIVATE range
>  0x89  F0-FF  linux/sockios.h                                         SIOCDEVPRIVATE range
> +0x8A  00-1F  linux/eventpoll.h
>  0x8B  all    linux/wireless.h
>  0x8C  00-3F                                                          WiNRADiO driver
>                                                                       <http://www.winradio.com.au/>
> diff --git a/fs/eventpoll.c b/fs/eventpoll.c
> index 40bd97477b91..73ae886efb8a 100644
> --- a/fs/eventpoll.c
> +++ b/fs/eventpoll.c
> @@ -6,6 +6,8 @@
>   *  Davide Libenzi <davidel@xmailserver.org>
>   */
>  
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
>  #include <linux/init.h>
>  #include <linux/kernel.h>
>  #include <linux/sched/signal.h>
> @@ -37,6 +39,7 @@
>  #include <linux/seq_file.h>
>  #include <linux/compat.h>
>  #include <linux/rculist.h>
> +#include <linux/capability.h>
>  #include <net/busy_poll.h>
>  
>  /*
> @@ -495,6 +498,39 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
>  	ep->napi_id = napi_id;
>  }
>  
> +static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
> +				  unsigned long arg)
> +{
> +	struct eventpoll *ep;
> +	struct epoll_params epoll_params;
> +	void __user *uarg = (void __user *) arg;
> +
> +	ep = file->private_data;
> +
> +	switch (cmd) {
> +	case EPIOCSPARAMS:
> +		if (copy_from_user(&epoll_params, uarg, sizeof(epoll_params)))
> +			return -EFAULT;
> +
> +		if (epoll_params.busy_poll_budget > NAPI_POLL_WEIGHT &&
> +		    !capable(CAP_NET_ADMIN))
> +			return -EPERM;
> +
> +		ep->busy_poll_usecs = epoll_params.busy_poll_usecs;
> +		ep->busy_poll_budget = epoll_params.busy_poll_budget;
> +		return 0;
> +	case EPIOCGPARAMS:
> +		memset(&epoll_params, 0, sizeof(epoll_params));
> +		epoll_params.busy_poll_usecs = ep->busy_poll_usecs;
> +		epoll_params.busy_poll_budget = ep->busy_poll_budget;
> +		if (copy_to_user(uarg, &epoll_params, sizeof(epoll_params)))
> +			return -EFAULT;
> +		return 0;
> +	default:
> +		return -ENOIOCTLCMD;
> +	}
> +}
> +
>  #else
>  
>  static inline bool ep_busy_loop(struct eventpoll *ep, int nonblock)
> @@ -510,6 +546,12 @@ static inline bool ep_busy_loop_on(struct eventpoll *ep)
>  {
>  	return false;
>  }
> +
> +static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
> +				  unsigned long arg)
> +{
> +	return -EOPNOTSUPP;
> +}
>  #endif /* CONFIG_NET_RX_BUSY_POLL */
>  
>  /*
> @@ -869,6 +911,26 @@ static void ep_clear_and_put(struct eventpoll *ep)
>  		ep_free(ep);
>  }
>  
> +static long ep_eventpoll_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	int ret;
> +
> +	if (!is_file_epoll(file))
> +		return -EINVAL;
> +
> +	switch (cmd) {
> +	case EPIOCSPARAMS:
> +	case EPIOCGPARAMS:
> +		ret = ep_eventpoll_bp_ioctl(file, cmd, arg);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
>  static int ep_eventpoll_release(struct inode *inode, struct file *file)
>  {
>  	struct eventpoll *ep = file->private_data;
> @@ -975,6 +1037,8 @@ static const struct file_operations eventpoll_fops = {
>  	.release	= ep_eventpoll_release,
>  	.poll		= ep_eventpoll_poll,
>  	.llseek		= noop_llseek,
> +	.unlocked_ioctl	= ep_eventpoll_ioctl,
> +	.compat_ioctl   = compat_ptr_ioctl,
>  };
>  
>  /*
> diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
> index cfbcc4cc49ac..8eb0fdbce995 100644
> --- a/include/uapi/linux/eventpoll.h
> +++ b/include/uapi/linux/eventpoll.h
> @@ -85,4 +85,16 @@ struct epoll_event {
>  	__u64 data;
>  } EPOLL_PACKED;
>  
> +struct epoll_params {
> +	u64 busy_poll_usecs;
> +	u16 busy_poll_budget;
> +
> +	/* for future fields */
> +	u8 data[118];

You forgot to validate that "data" is set to 0, which means that this
would be useless.  Why have this at all?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 23:20   ` Greg Kroah-Hartman
@ 2024-01-26  0:04     ` Joe Damato
  0 siblings, 0 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-26  0:04 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 03:20:37PM -0800, Greg Kroah-Hartman wrote:
> On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > --- a/fs/eventpoll.c
> > +++ b/fs/eventpoll.c
> > @@ -6,6 +6,8 @@
> >   *  Davide Libenzi <davidel@xmailserver.org>
> >   */
> >  
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> 
> Why this addition?  You do not add any pr_*() calls in this patch at all
> that I can see.

Thanks, I've removed this for the next version. It was a remnant from a
previous version.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 23:22   ` Greg Kroah-Hartman
@ 2024-01-26  0:07     ` Joe Damato
  0 siblings, 0 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-26  0:07 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 03:22:34PM -0800, Greg Kroah-Hartman wrote:
> On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > Add an ioctl for getting and setting epoll_params. User programs can use
> > this ioctl to get and set the busy poll usec time or packet budget
> > params for a specific epoll context.
> > 
> > Signed-off-by: Joe Damato <jdamato@fastly.com>
> > ---
> >  .../userspace-api/ioctl/ioctl-number.rst      |  1 +
> >  fs/eventpoll.c                                | 64 +++++++++++++++++++
> >  include/uapi/linux/eventpoll.h                | 12 ++++
> >  3 files changed, 77 insertions(+)
> > 
> > diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
> > index 457e16f06e04..b33918232f78 100644
> > --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
> > +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
> > @@ -309,6 +309,7 @@ Code  Seq#    Include File                                           Comments
> >  0x89  0B-DF  linux/sockios.h
> >  0x89  E0-EF  linux/sockios.h                                         SIOCPROTOPRIVATE range
> >  0x89  F0-FF  linux/sockios.h                                         SIOCDEVPRIVATE range
> > +0x8A  00-1F  linux/eventpoll.h
> >  0x8B  all    linux/wireless.h
> >  0x8C  00-3F                                                          WiNRADiO driver
> >                                                                       <http://www.winradio.com.au/>
> > diff --git a/fs/eventpoll.c b/fs/eventpoll.c
> > index 40bd97477b91..73ae886efb8a 100644
> > --- a/fs/eventpoll.c
> > +++ b/fs/eventpoll.c
> > @@ -6,6 +6,8 @@
> >   *  Davide Libenzi <davidel@xmailserver.org>
> >   */
> >  
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> >  #include <linux/init.h>
> >  #include <linux/kernel.h>
> >  #include <linux/sched/signal.h>
> > @@ -37,6 +39,7 @@
> >  #include <linux/seq_file.h>
> >  #include <linux/compat.h>
> >  #include <linux/rculist.h>
> > +#include <linux/capability.h>
> >  #include <net/busy_poll.h>
> >  
> >  /*
> > @@ -495,6 +498,39 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
> >  	ep->napi_id = napi_id;
> >  }
> >  
> > +static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
> > +				  unsigned long arg)
> > +{
> > +	struct eventpoll *ep;
> > +	struct epoll_params epoll_params;
> > +	void __user *uarg = (void __user *) arg;
> > +
> > +	ep = file->private_data;
> > +
> > +	switch (cmd) {
> > +	case EPIOCSPARAMS:
> > +		if (copy_from_user(&epoll_params, uarg, sizeof(epoll_params)))
> > +			return -EFAULT;
> > +
> > +		if (epoll_params.busy_poll_budget > NAPI_POLL_WEIGHT &&
> > +		    !capable(CAP_NET_ADMIN))
> > +			return -EPERM;
> > +
> > +		ep->busy_poll_usecs = epoll_params.busy_poll_usecs;
> > +		ep->busy_poll_budget = epoll_params.busy_poll_budget;
> > +		return 0;
> > +	case EPIOCGPARAMS:
> > +		memset(&epoll_params, 0, sizeof(epoll_params));
> > +		epoll_params.busy_poll_usecs = ep->busy_poll_usecs;
> > +		epoll_params.busy_poll_budget = ep->busy_poll_budget;
> > +		if (copy_to_user(uarg, &epoll_params, sizeof(epoll_params)))
> > +			return -EFAULT;
> > +		return 0;
> > +	default:
> > +		return -ENOIOCTLCMD;
> > +	}
> > +}
> > +
> >  #else
> >  
> >  static inline bool ep_busy_loop(struct eventpoll *ep, int nonblock)
> > @@ -510,6 +546,12 @@ static inline bool ep_busy_loop_on(struct eventpoll *ep)
> >  {
> >  	return false;
> >  }
> > +
> > +static long ep_eventpoll_bp_ioctl(struct file *file, unsigned int cmd,
> > +				  unsigned long arg)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> >  #endif /* CONFIG_NET_RX_BUSY_POLL */
> >  
> >  /*
> > @@ -869,6 +911,26 @@ static void ep_clear_and_put(struct eventpoll *ep)
> >  		ep_free(ep);
> >  }
> >  
> > +static long ep_eventpoll_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> > +{
> > +	int ret;
> > +
> > +	if (!is_file_epoll(file))
> > +		return -EINVAL;
> > +
> > +	switch (cmd) {
> > +	case EPIOCSPARAMS:
> > +	case EPIOCGPARAMS:
> > +		ret = ep_eventpoll_bp_ioctl(file, cmd, arg);
> > +		break;
> > +	default:
> > +		ret = -EINVAL;
> > +		break;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> >  static int ep_eventpoll_release(struct inode *inode, struct file *file)
> >  {
> >  	struct eventpoll *ep = file->private_data;
> > @@ -975,6 +1037,8 @@ static const struct file_operations eventpoll_fops = {
> >  	.release	= ep_eventpoll_release,
> >  	.poll		= ep_eventpoll_poll,
> >  	.llseek		= noop_llseek,
> > +	.unlocked_ioctl	= ep_eventpoll_ioctl,
> > +	.compat_ioctl   = compat_ptr_ioctl,
> >  };
> >  
> >  /*
> > diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
> > index cfbcc4cc49ac..8eb0fdbce995 100644
> > --- a/include/uapi/linux/eventpoll.h
> > +++ b/include/uapi/linux/eventpoll.h
> > @@ -85,4 +85,16 @@ struct epoll_event {
> >  	__u64 data;
> >  } EPOLL_PACKED;
> >  
> > +struct epoll_params {
> > +	u64 busy_poll_usecs;
> > +	u16 busy_poll_budget;
> > +
> > +	/* for future fields */
> > +	u8 data[118];
> 
> You forgot to validate that "data" is set to 0, which means that this
> would be useless.  Why have this at all?

I included this because I (probably incorrectly) thought that there should
be some extra space in the struct for future additions if needed.

I am not sure if that is a recommended practice for this sort of thing or
not, but if it is I can add some validation.

Thanks for your time and effort in reviewing my code.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 23:21   ` Greg Kroah-Hartman
@ 2024-01-26  0:11     ` Joe Damato
  2024-01-26  0:23       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 20+ messages in thread
From: Joe Damato @ 2024-01-26  0:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > +struct epoll_params {
> > +	u64 busy_poll_usecs;
> > +	u16 busy_poll_budget;
> > +
> > +	/* for future fields */
> > +	u8 data[118];
> > +} EPOLL_PACKED;
> 
> variables that cross the user/kernel boundry need to be __u64, __u16,
> and __u8 here.

I'll make that change for the next version, thank you.

> And why 118?

I chose this arbitrarily. I figured that a 128 byte struct would support 16
u64s in the event that other fields needed to be added in the future. 118
is what was left after the existing fields. There's almost certainly a
better way to do this - or perhaps it is unnecessary as per your other
message.

I am not sure if leaving extra space in the struct is a recommended
practice for ioctls or not - I thought I noticed some code that did and
some that didn't in the kernel so I err'd on the side of leaving the space
and probably did it in the worst way possible.

Thanks,
Joe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26  0:11     ` Joe Damato
@ 2024-01-26  0:23       ` Greg Kroah-Hartman
  2024-01-26  2:36         ` Joe Damato
  0 siblings, 1 reply; 20+ messages in thread
From: Greg Kroah-Hartman @ 2024-01-26  0:23 UTC (permalink / raw)
  To: Joe Damato
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
> On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > > +struct epoll_params {
> > > +	u64 busy_poll_usecs;
> > > +	u16 busy_poll_budget;
> > > +
> > > +	/* for future fields */
> > > +	u8 data[118];
> > > +} EPOLL_PACKED;
> > 
> > variables that cross the user/kernel boundry need to be __u64, __u16,
> > and __u8 here.
> 
> I'll make that change for the next version, thank you.
> 
> > And why 118?
> 
> I chose this arbitrarily. I figured that a 128 byte struct would support 16
> u64s in the event that other fields needed to be added in the future. 118
> is what was left after the existing fields. There's almost certainly a
> better way to do this - or perhaps it is unnecessary as per your other
> message.
> 
> I am not sure if leaving extra space in the struct is a recommended
> practice for ioctls or not - I thought I noticed some code that did and
> some that didn't in the kernel so I err'd on the side of leaving the space
> and probably did it in the worst way possible.

It's not really a good idea unless you know exactly what you are going
to do with it.  Why not just have a new ioctl if you need new
information in the future?  That's simpler, right?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26  0:23       ` Greg Kroah-Hartman
@ 2024-01-26  2:36         ` Joe Damato
  2024-01-26  6:16           ` Arnd Bergmann
  2024-01-26 10:07           ` Christian Brauner
  0 siblings, 2 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-26  2:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Arnd Bergmann,
	Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 04:23:58PM -0800, Greg Kroah-Hartman wrote:
> On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
> > On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> > > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > > > +struct epoll_params {
> > > > +	u64 busy_poll_usecs;
> > > > +	u16 busy_poll_budget;
> > > > +
> > > > +	/* for future fields */
> > > > +	u8 data[118];
> > > > +} EPOLL_PACKED;
> > > 
> > > variables that cross the user/kernel boundry need to be __u64, __u16,
> > > and __u8 here.
> > 
> > I'll make that change for the next version, thank you.
> > 
> > > And why 118?
> > 
> > I chose this arbitrarily. I figured that a 128 byte struct would support 16
> > u64s in the event that other fields needed to be added in the future. 118
> > is what was left after the existing fields. There's almost certainly a
> > better way to do this - or perhaps it is unnecessary as per your other
> > message.
> > 
> > I am not sure if leaving extra space in the struct is a recommended
> > practice for ioctls or not - I thought I noticed some code that did and
> > some that didn't in the kernel so I err'd on the side of leaving the space
> > and probably did it in the worst way possible.
> 
> It's not really a good idea unless you know exactly what you are going
> to do with it.  Why not just have a new ioctl if you need new
> information in the future?  That's simpler, right?

Sure, that makes sense to me. I'll remove it in the v4 alongside the other
changes you've requested.

Thanks for your time and patience reviewing my code. I greatly appreciate
your helpful comments and feedback.

Thanks,
Joe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26  2:36         ` Joe Damato
@ 2024-01-26  6:16           ` Arnd Bergmann
  2024-01-27 14:51             ` David Laight
  2024-01-26 10:07           ` Christian Brauner
  1 sibling, 1 reply; 20+ messages in thread
From: Arnd Bergmann @ 2024-01-26  6:16 UTC (permalink / raw)
  To: Joe Damato, Greg Kroah-Hartman
  Cc: linux-kernel, Netdev, Chuck Lever, Jeff Layton, linux-api,
	Christian Brauner, Eric Dumazet, David S . Miller,
	alexander.duyck, Sridhar Samudrala, Jakub Kicinski,
	Willem de Bruijn, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Andrew Waterman,
	Thomas Huth, Palmer Dabbelt, open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Fri, Jan 26, 2024, at 03:36, Joe Damato wrote:
> On Thu, Jan 25, 2024 at 04:23:58PM -0800, Greg Kroah-Hartman wrote:
>> On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
>> > On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
>> > > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
>> > > > +struct epoll_params {
>> > > > +	u64 busy_poll_usecs;
>> > > > +	u16 busy_poll_budget;
>> > > > +
>> > > > +	/* for future fields */
>> > > > +	u8 data[118];
>> > > > +} EPOLL_PACKED;
>> > > 
>
> Sure, that makes sense to me. I'll remove it in the v4 alongside the other
> changes you've requested.
>
> Thanks for your time and patience reviewing my code. I greatly appreciate
> your helpful comments and feedback.

Note that you should still pad the structure to its normal
alignment. On non-x86 targets this would currently mean a
multiple of 64 bits.

I would suggest dropping the EPOLL_PACKED here entirely and
just using a fully aligned structure on all architectures, like

struct epoll_params {
      __aligned_u64 busy_poll_usecs;
      __u16 busy_poll_budget;
      __u8 __pad[6];
};

The explicit padding can help avoid leaking stack data when
a structure is copied back from kernel to userspace, so I would
just always use it in ioctl data structures.

      Arnd

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26  2:36         ` Joe Damato
  2024-01-26  6:16           ` Arnd Bergmann
@ 2024-01-26 10:07           ` Christian Brauner
  2024-01-26 16:52             ` Joe Damato
  1 sibling, 1 reply; 20+ messages in thread
From: Christian Brauner @ 2024-01-26 10:07 UTC (permalink / raw)
  To: Joe Damato
  Cc: Greg Kroah-Hartman, linux-kernel, netdev, chuck.lever, jlayton,
	linux-api, edumazet, davem, alexander.duyck, sridhar.samudrala,
	kuba, willemdebruijn.kernel, weiwan, Jonathan Corbet,
	Alexander Viro, Jan Kara, Michael Ellerman, Nathan Lynch,
	Steve French, Thomas Zimmermann, Jiri Slaby, Julien Panis,
	Arnd Bergmann, Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Thu, Jan 25, 2024 at 06:36:30PM -0800, Joe Damato wrote:
> On Thu, Jan 25, 2024 at 04:23:58PM -0800, Greg Kroah-Hartman wrote:
> > On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
> > > On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> > > > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > > > > +struct epoll_params {
> > > > > +	u64 busy_poll_usecs;
> > > > > +	u16 busy_poll_budget;
> > > > > +
> > > > > +	/* for future fields */
> > > > > +	u8 data[118];
> > > > > +} EPOLL_PACKED;
> > > > 
> > > > variables that cross the user/kernel boundry need to be __u64, __u16,
> > > > and __u8 here.
> > > 
> > > I'll make that change for the next version, thank you.
> > > 
> > > > And why 118?
> > > 
> > > I chose this arbitrarily. I figured that a 128 byte struct would support 16
> > > u64s in the event that other fields needed to be added in the future. 118
> > > is what was left after the existing fields. There's almost certainly a
> > > better way to do this - or perhaps it is unnecessary as per your other
> > > message.
> > > 
> > > I am not sure if leaving extra space in the struct is a recommended
> > > practice for ioctls or not - I thought I noticed some code that did and
> > > some that didn't in the kernel so I err'd on the side of leaving the space
> > > and probably did it in the worst way possible.
> > 
> > It's not really a good idea unless you know exactly what you are going
> > to do with it.  Why not just have a new ioctl if you need new
> > information in the future?  That's simpler, right?
> 
> Sure, that makes sense to me. I'll remove it in the v4 alongside the other
> changes you've requested.

Fwiw, we do support extensible ioctls since they encode the size. Take a
look at kernel/seccomp.c. It's a clean extensible interface built on top
of the copy_struct_from_user() pattern we added for system calls
(openat(), clone3() etc.):

static long seccomp_notify_ioctl(struct file *file, unsigned int cmd,
                                 unsigned long arg)
{
        struct seccomp_filter *filter = file->private_data;
        void __user *buf = (void __user *)arg;

        /* Fixed-size ioctls */
        switch (cmd) {
        case SECCOMP_IOCTL_NOTIF_RECV:
                return seccomp_notify_recv(filter, buf);
        case SECCOMP_IOCTL_NOTIF_SEND:
                return seccomp_notify_send(filter, buf);
        case SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR:
        case SECCOMP_IOCTL_NOTIF_ID_VALID:
                return seccomp_notify_id_valid(filter, buf);
        case SECCOMP_IOCTL_NOTIF_SET_FLAGS:
                return seccomp_notify_set_flags(filter, arg);
        }

        /* Extensible Argument ioctls */
#define EA_IOCTL(cmd)   ((cmd) & ~(IOC_INOUT | IOCSIZE_MASK))
        switch (EA_IOCTL(cmd)) {
        case EA_IOCTL(SECCOMP_IOCTL_NOTIF_ADDFD):
                return seccomp_notify_addfd(filter, buf, _IOC_SIZE(cmd));
        default:
                return -EINVAL;
        }
}

static long seccomp_notify_addfd(struct seccomp_filter *filter,
                                 struct seccomp_notif_addfd __user *uaddfd,
                                 unsigned int size)
{
        struct seccomp_notif_addfd addfd;
        struct seccomp_knotif *knotif;
        struct seccomp_kaddfd kaddfd;
        int ret;

        BUILD_BUG_ON(sizeof(addfd) < SECCOMP_NOTIFY_ADDFD_SIZE_VER0);
        BUILD_BUG_ON(sizeof(addfd) != SECCOMP_NOTIFY_ADDFD_SIZE_LATEST);

        if (size < SECCOMP_NOTIFY_ADDFD_SIZE_VER0 || size >= PAGE_SIZE)
                return -EINVAL;

        ret = copy_struct_from_user(&addfd, sizeof(addfd), uaddfd, size);
        if (ret)
                return ret;





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26 10:07           ` Christian Brauner
@ 2024-01-26 16:52             ` Joe Damato
  0 siblings, 0 replies; 20+ messages in thread
From: Joe Damato @ 2024-01-26 16:52 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Greg Kroah-Hartman, linux-kernel, netdev, chuck.lever, jlayton,
	linux-api, edumazet, davem, alexander.duyck, sridhar.samudrala,
	kuba, willemdebruijn.kernel, weiwan, Jonathan Corbet,
	Alexander Viro, Jan Kara, Michael Ellerman, Nathan Lynch,
	Steve French, Thomas Zimmermann, Jiri Slaby, Julien Panis,
	Arnd Bergmann, Andrew Waterman, Thomas Huth, Palmer Dabbelt,
	open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

On Fri, Jan 26, 2024 at 11:07:36AM +0100, Christian Brauner wrote:
> On Thu, Jan 25, 2024 at 06:36:30PM -0800, Joe Damato wrote:
> > On Thu, Jan 25, 2024 at 04:23:58PM -0800, Greg Kroah-Hartman wrote:
> > > On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
> > > > On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> > > > > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> > > > > > +struct epoll_params {
> > > > > > +	u64 busy_poll_usecs;
> > > > > > +	u16 busy_poll_budget;
> > > > > > +
> > > > > > +	/* for future fields */
> > > > > > +	u8 data[118];
> > > > > > +} EPOLL_PACKED;
> > > > > 
> > > > > variables that cross the user/kernel boundry need to be __u64, __u16,
> > > > > and __u8 here.
> > > > 
> > > > I'll make that change for the next version, thank you.
> > > > 
> > > > > And why 118?
> > > > 
> > > > I chose this arbitrarily. I figured that a 128 byte struct would support 16
> > > > u64s in the event that other fields needed to be added in the future. 118
> > > > is what was left after the existing fields. There's almost certainly a
> > > > better way to do this - or perhaps it is unnecessary as per your other
> > > > message.
> > > > 
> > > > I am not sure if leaving extra space in the struct is a recommended
> > > > practice for ioctls or not - I thought I noticed some code that did and
> > > > some that didn't in the kernel so I err'd on the side of leaving the space
> > > > and probably did it in the worst way possible.
> > > 
> > > It's not really a good idea unless you know exactly what you are going
> > > to do with it.  Why not just have a new ioctl if you need new
> > > information in the future?  That's simpler, right?
> > 
> > Sure, that makes sense to me. I'll remove it in the v4 alongside the other
> > changes you've requested.
> 
> Fwiw, we do support extensible ioctls since they encode the size. Take a
> look at kernel/seccomp.c. It's a clean extensible interface built on top
> of the copy_struct_from_user() pattern we added for system calls
> (openat(), clone3() etc.):
> 
> static long seccomp_notify_ioctl(struct file *file, unsigned int cmd,
>                                  unsigned long arg)
> {
>         struct seccomp_filter *filter = file->private_data;
>         void __user *buf = (void __user *)arg;
> 
>         /* Fixed-size ioctls */
>         switch (cmd) {
>         case SECCOMP_IOCTL_NOTIF_RECV:
>                 return seccomp_notify_recv(filter, buf);
>         case SECCOMP_IOCTL_NOTIF_SEND:
>                 return seccomp_notify_send(filter, buf);
>         case SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR:
>         case SECCOMP_IOCTL_NOTIF_ID_VALID:
>                 return seccomp_notify_id_valid(filter, buf);
>         case SECCOMP_IOCTL_NOTIF_SET_FLAGS:
>                 return seccomp_notify_set_flags(filter, arg);
>         }
> 
>         /* Extensible Argument ioctls */
> #define EA_IOCTL(cmd)   ((cmd) & ~(IOC_INOUT | IOCSIZE_MASK))
>         switch (EA_IOCTL(cmd)) {
>         case EA_IOCTL(SECCOMP_IOCTL_NOTIF_ADDFD):
>                 return seccomp_notify_addfd(filter, buf, _IOC_SIZE(cmd));
>         default:
>                 return -EINVAL;
>         }
> }
> 
> static long seccomp_notify_addfd(struct seccomp_filter *filter,
>                                  struct seccomp_notif_addfd __user *uaddfd,
>                                  unsigned int size)
> {
>         struct seccomp_notif_addfd addfd;
>         struct seccomp_knotif *knotif;
>         struct seccomp_kaddfd kaddfd;
>         int ret;
> 
>         BUILD_BUG_ON(sizeof(addfd) < SECCOMP_NOTIFY_ADDFD_SIZE_VER0);
>         BUILD_BUG_ON(sizeof(addfd) != SECCOMP_NOTIFY_ADDFD_SIZE_LATEST);
> 
>         if (size < SECCOMP_NOTIFY_ADDFD_SIZE_VER0 || size >= PAGE_SIZE)
>                 return -EINVAL;
> 
>         ret = copy_struct_from_user(&addfd, sizeof(addfd), uaddfd, size);
>         if (ret)
>                 return ret;

Thanks; that's a really helpful note and example.

I'm inclined to believe that new fields probably won't be needed for a
while, but if they are: an extensible ioctl could be added in the future
to deal with that problem at that point.

Thanks,
Joe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-26  6:16           ` Arnd Bergmann
@ 2024-01-27 14:51             ` David Laight
  0 siblings, 0 replies; 20+ messages in thread
From: David Laight @ 2024-01-27 14:51 UTC (permalink / raw)
  To: 'Arnd Bergmann', Joe Damato, Greg Kroah-Hartman
  Cc: linux-kernel, Netdev, Chuck Lever, Jeff Layton, linux-api,
	Christian Brauner, Eric Dumazet, David S . Miller,
	alexander.duyck, Sridhar Samudrala, Jakub Kicinski,
	Willem de Bruijn, weiwan, Jonathan Corbet, Alexander Viro,
	Jan Kara, Michael Ellerman, Nathan Lynch, Steve French,
	Thomas Zimmermann, Jiri Slaby, Julien Panis, Andrew Waterman,
	Thomas Huth, Palmer Dabbelt, open list:DOCUMENTATION,
	open list:FILESYSTEMS (VFS and infrastructure)

From: Arnd Bergmann
> Sent: 26 January 2024 06:16
> 
> On Fri, Jan 26, 2024, at 03:36, Joe Damato wrote:
> > On Thu, Jan 25, 2024 at 04:23:58PM -0800, Greg Kroah-Hartman wrote:
> >> On Thu, Jan 25, 2024 at 04:11:28PM -0800, Joe Damato wrote:
> >> > On Thu, Jan 25, 2024 at 03:21:46PM -0800, Greg Kroah-Hartman wrote:
> >> > > On Thu, Jan 25, 2024 at 10:56:59PM +0000, Joe Damato wrote:
> >> > > > +struct epoll_params {
> >> > > > +	u64 busy_poll_usecs;
> >> > > > +	u16 busy_poll_budget;
> >> > > > +
> >> > > > +	/* for future fields */
> >> > > > +	u8 data[118];
> >> > > > +} EPOLL_PACKED;
> >> > >
> >
> > Sure, that makes sense to me. I'll remove it in the v4 alongside the other
> > changes you've requested.
> >
> > Thanks for your time and patience reviewing my code. I greatly appreciate
> > your helpful comments and feedback.
> 
> Note that you should still pad the structure to its normal
> alignment. On non-x86 targets this would currently mean a
> multiple of 64 bits.
> 
> I would suggest dropping the EPOLL_PACKED here entirely and
> just using a fully aligned structure on all architectures, like
> 
> struct epoll_params {
>       __aligned_u64 busy_poll_usecs;
>       __u16 busy_poll_budget;
>       __u8 __pad[6];
> };
> 
> The explicit padding can help avoid leaking stack data when
> a structure is copied back from kernel to userspace, so I would
> just always use it in ioctl data structures.

Or just use 32bit types for both fields.
Both values need erroring before they get that large.
32bit of usec is about 20 seconds.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 0/3] Per epoll context busy poll support
  2024-01-25 22:56 [PATCH net-next v3 0/3] Per epoll context busy poll support Joe Damato
                   ` (2 preceding siblings ...)
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
@ 2024-01-27 16:20 ` Willem de Bruijn
  2024-01-29 19:09   ` Joe Damato
  3 siblings, 1 reply; 20+ messages in thread
From: Willem de Bruijn @ 2024-01-27 16:20 UTC (permalink / raw)
  To: Joe Damato, linux-kernel, netdev
  Cc: chuck.lever, jlayton, linux-api, brauner, edumazet, davem,
	alexander.duyck, sridhar.samudrala, kuba, willemdebruijn.kernel,
	weiwan, Joe Damato, Alexander Viro, Andrew Waterman,
	Arnd Bergmann, Dominik Brodowski, Greg Kroah-Hartman, Jan Kara,
	Jiri Slaby, Jonathan Corbet, Julien Panis,
	open list:DOCUMENTATION,
	(open list:FILESYSTEMS \(VFS and infrastructure\)),
	Michael Ellerman, Nathan Lynch, Palmer Dabbelt, Steve French,
	Thomas Huth, Thomas Zimmermann

Joe Damato wrote:
> Greetings:
> 
> Welcome to v3. Cover letter updated from v2 to explain why ioctl and
> adjusted my cc_cmd to try to get the correct people in addition to folks
> who were added in v1 & v2. Labeled as net-next because it seems networking
> related to me even though it is fs code.
> 
> TL;DR This builds on commit bf3b9f6372c4 ("epoll: Add busy poll support to
> epoll with socket fds.") by allowing user applications to enable
> epoll-based busy polling and set a busy poll packet budget on a per epoll
> context basis.
> 
> This makes epoll-based busy polling much more usable for user
> applications than the current system-wide sysctl and hardcoded budget.
> 
> To allow for this, two ioctls have been added for epoll contexts for
> getting and setting a new struct, struct epoll_params.
> 
> ioctl was chosen vs a new syscall after reviewing a suggestion by Willem
> de Bruijn [1]. I am open to using a new syscall instead of an ioctl, but it
> seemed that: 
>   - Busy poll affects all existing epoll_wait and epoll_pwait variants in
>     the same way, so new verions of many syscalls might be needed. It

There is no need to support a new feature on legacy calls. Applications have
to be upgraded to the new ioctl, so they can also be upgraded to the latest
epoll_wait variant.

epoll_pwait extends epoll_wait with a sigmask.
epoll_pwait2 extends extends epoll_pwait with nsec resolution timespec.
Since they are supersets, nothing is lots by limiting to the most recent API.

In the discussion of epoll_pwait2 the addition of a forward looking flags
argument was discussed, but eventually dropped. Based on the argument that
adding a syscall is not a big task and does not warrant preemptive code.
This decision did receive a suitably snarky comment from Jonathan Corbet [1].

It is definitely more boilerplate, but essentially it is as feasible to add an
epoll_pwait3 that takes an optional busy poll argument. In which case, I also
believe that it makes more sense to configure the behavior of the syscall
directly, than through another syscall and state stored in the kernel.

I don't think that the usec fine grain busy poll argument is all that useful.
Documentation always suggests setting it to 50us or 100us, based on limited
data. Main point is to set it to exceed the round-trip delay of whatever the
process is trying to wait on. Overestimating is not costly, as the call
returns as soon as the condition is met. An epoll_pwait3 flag EPOLL_BUSY_POLL
with default 100us might be sufficient.

[1] https://lwn.net/Articles/837816/


>     seems much simpler for users to use the correct
>     epoll_wait/epoll_pwait for their app and add a call to ioctl to enable
>     or disable busy poll as needed. This also probably means less work to
>     get an existing epoll app using busy poll.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
  2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
                     ` (2 preceding siblings ...)
  2024-01-25 23:22   ` Greg Kroah-Hartman
@ 2024-01-28 11:24   ` kernel test robot
  3 siblings, 0 replies; 20+ messages in thread
From: kernel test robot @ 2024-01-28 11:24 UTC (permalink / raw)
  To: Joe Damato, linux-kernel, netdev
  Cc: oe-kbuild-all, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	willemdebruijn.kernel, weiwan, Joe Damato, Jonathan Corbet,
	Alexander Viro, Jan Kara, Michael Ellerman, Greg Kroah-Hartman,
	Nathan Lynch, Steve French, Thomas Zimmermann, Jiri Slaby,
	Julien Panis, Arnd Bergmann, Andrew Waterman, Thomas Huth,
	Palmer Dabbelt, linux-doc,
	(open list:FILESYSTEMS (VFS and infrastructure))

Hi Joe,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Joe-Damato/eventpoll-support-busy-poll-per-epoll-instance/20240126-070250
base:   net-next/main
patch link:    https://lore.kernel.org/r/20240125225704.12781-4-jdamato%40fastly.com
patch subject: [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params
config: i386-buildonly-randconfig-002-20240127 (https://download.01.org/0day-ci/archive/20240128/202401281917.WeFbZE56-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240128/202401281917.WeFbZE56-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401281917.WeFbZE56-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from <command-line>:
>> ./usr/include/linux/eventpoll.h:89:9: error: unknown type name 'u64'
      89 |         u64 busy_poll_usecs;
         |         ^~~
>> ./usr/include/linux/eventpoll.h:90:9: error: unknown type name 'u16'
      90 |         u16 busy_poll_budget;
         |         ^~~
>> ./usr/include/linux/eventpoll.h:93:9: error: unknown type name 'u8'
      93 |         u8 data[118];
         |         ^~

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 0/3] Per epoll context busy poll support
  2024-01-27 16:20 ` [PATCH net-next v3 0/3] Per epoll context busy poll support Willem de Bruijn
@ 2024-01-29 19:09   ` Joe Damato
  2024-01-30 20:33     ` Willem de Bruijn
  0 siblings, 1 reply; 20+ messages in thread
From: Joe Damato @ 2024-01-29 19:09 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	weiwan, Alexander Viro, Andrew Waterman, Arnd Bergmann,
	Dominik Brodowski, Greg Kroah-Hartman, Jan Kara, Jiri Slaby,
	Jonathan Corbet, Julien Panis, open list:DOCUMENTATION,
	(open list:FILESYSTEMS \(VFS and infrastructure\)),
	Michael Ellerman, Nathan Lynch, Palmer Dabbelt, Steve French,
	Thomas Huth, Thomas Zimmermann

On Sat, Jan 27, 2024 at 11:20:51AM -0500, Willem de Bruijn wrote:
> Joe Damato wrote:
> > Greetings:
> > 
> > Welcome to v3. Cover letter updated from v2 to explain why ioctl and
> > adjusted my cc_cmd to try to get the correct people in addition to folks
> > who were added in v1 & v2. Labeled as net-next because it seems networking
> > related to me even though it is fs code.
> > 
> > TL;DR This builds on commit bf3b9f6372c4 ("epoll: Add busy poll support to
> > epoll with socket fds.") by allowing user applications to enable
> > epoll-based busy polling and set a busy poll packet budget on a per epoll
> > context basis.
> > 
> > This makes epoll-based busy polling much more usable for user
> > applications than the current system-wide sysctl and hardcoded budget.
> > 
> > To allow for this, two ioctls have been added for epoll contexts for
> > getting and setting a new struct, struct epoll_params.
> > 
> > ioctl was chosen vs a new syscall after reviewing a suggestion by Willem
> > de Bruijn [1]. I am open to using a new syscall instead of an ioctl, but it
> > seemed that: 
> >   - Busy poll affects all existing epoll_wait and epoll_pwait variants in
> >     the same way, so new verions of many syscalls might be needed. It
> 
> There is no need to support a new feature on legacy calls. Applications have
> to be upgraded to the new ioctl, so they can also be upgraded to the latest
> epoll_wait variant.

Sure, that's a fair point. I think we could probably make reasonable
arguments in both directions about the pros/cons of each approach.

It's still not clear to me that a new syscall is the best way to go on
this, and IMO it does not offer a clear advantage. I understand that part
of the premise of your argument is that ioctls are not recommended, but in
this particular case it seems like a good use case and there have been
new ioctls added recently (at least according to git log).

This makes me think that while their use is not recommended, they can serve
a purpose in specific use cases. To me, this use case seems very fitting.

More of a joke and I hate to mention this, but this setting is changing how
io is done and it seems fitting that this done via an ioctl ;)

> epoll_pwait extends epoll_wait with a sigmask.
> epoll_pwait2 extends extends epoll_pwait with nsec resolution timespec.
> Since they are supersets, nothing is lots by limiting to the most recent API.
> 
> In the discussion of epoll_pwait2 the addition of a forward looking flags
> argument was discussed, but eventually dropped. Based on the argument that
> adding a syscall is not a big task and does not warrant preemptive code.
> This decision did receive a suitably snarky comment from Jonathan Corbet [1].
> 
> It is definitely more boilerplate, but essentially it is as feasible to add an
> epoll_pwait3 that takes an optional busy poll argument. In which case, I also
> believe that it makes more sense to configure the behavior of the syscall
> directly, than through another syscall and state stored in the kernel.

I definitely hear what you are saying; I think I'm still not convinced, but
I am thinking it through.

In my mind, all of the other busy poll settings are configured by setting
options on the sockets using various SO_* options, which modify some state
in the kernel. The existing system-wide busy poll sysctl also does this. It
feels strange to me to diverge from that pattern just for epoll.

In the case of epoll_pwait2 the addition of a new syscall is an approach
that I think makes a lot of sense. The new system call is also probably
better from an end-user usability perspective, as well. For busy poll, I
don't see a clear reasoning why a new system call is better, but maybe I am
still missing something.

> I don't think that the usec fine grain busy poll argument is all that useful.
> Documentation always suggests setting it to 50us or 100us, based on limited
> data. Main point is to set it to exceed the round-trip delay of whatever the
> process is trying to wait on. Overestimating is not costly, as the call
> returns as soon as the condition is met. An epoll_pwait3 flag EPOLL_BUSY_POLL
> with default 100us might be sufficient.
> 
> [1] https://lwn.net/Articles/837816/

Perhaps I am misunderstanding what you are suggesting, but I am opposed to
hardcoding a value. If it is currently configurable system-wide and via
SO_* options for other forms of busy poll, I think it should similarly be
configurable for epoll busy poll.

I may yet be convinced by the new syscall argument, but I don't think I'd
agree on imposing a default. The value can be modified by other forms of
busy poll and the goal of my changes are to:
  - make epoll-based busy poll per context
  - allow applications to configure (within reason) how epoll-based busy
    poll behaves, like they can do now with the existing SO_* options for
    other busy poll methods.

> >     seems much simpler for users to use the correct
> >     epoll_wait/epoll_pwait for their app and add a call to ioctl to enable
> >     or disable busy poll as needed. This also probably means less work to
> >     get an existing epoll app using busy poll.
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v3 0/3] Per epoll context busy poll support
  2024-01-29 19:09   ` Joe Damato
@ 2024-01-30 20:33     ` Willem de Bruijn
  0 siblings, 0 replies; 20+ messages in thread
From: Willem de Bruijn @ 2024-01-30 20:33 UTC (permalink / raw)
  To: Joe Damato, Willem de Bruijn
  Cc: linux-kernel, netdev, chuck.lever, jlayton, linux-api, brauner,
	edumazet, davem, alexander.duyck, sridhar.samudrala, kuba,
	weiwan, Alexander Viro, Andrew Waterman, Arnd Bergmann,
	Dominik Brodowski, Greg Kroah-Hartman, Jan Kara, Jiri Slaby,
	Jonathan Corbet, Julien Panis, open list:DOCUMENTATION,
	(open list:FILESYSTEMS \(VFS and infrastructure\)),
	Michael Ellerman, Nathan Lynch, Palmer Dabbelt, Steve French,
	Thomas Huth, Thomas Zimmermann

Joe Damato wrote:
> On Sat, Jan 27, 2024 at 11:20:51AM -0500, Willem de Bruijn wrote:
> > Joe Damato wrote:
> > > Greetings:
> > > 
> > > Welcome to v3. Cover letter updated from v2 to explain why ioctl and
> > > adjusted my cc_cmd to try to get the correct people in addition to folks
> > > who were added in v1 & v2. Labeled as net-next because it seems networking
> > > related to me even though it is fs code.
> > > 
> > > TL;DR This builds on commit bf3b9f6372c4 ("epoll: Add busy poll support to
> > > epoll with socket fds.") by allowing user applications to enable
> > > epoll-based busy polling and set a busy poll packet budget on a per epoll
> > > context basis.
> > > 
> > > This makes epoll-based busy polling much more usable for user
> > > applications than the current system-wide sysctl and hardcoded budget.
> > > 
> > > To allow for this, two ioctls have been added for epoll contexts for
> > > getting and setting a new struct, struct epoll_params.
> > > 
> > > ioctl was chosen vs a new syscall after reviewing a suggestion by Willem
> > > de Bruijn [1]. I am open to using a new syscall instead of an ioctl, but it
> > > seemed that: 
> > >   - Busy poll affects all existing epoll_wait and epoll_pwait variants in
> > >     the same way, so new verions of many syscalls might be needed. It
> > 
> > There is no need to support a new feature on legacy calls. Applications have
> > to be upgraded to the new ioctl, so they can also be upgraded to the latest
> > epoll_wait variant.
> 
> Sure, that's a fair point. I think we could probably make reasonable
> arguments in both directions about the pros/cons of each approach.
> 
> It's still not clear to me that a new syscall is the best way to go on
> this, and IMO it does not offer a clear advantage. I understand that part
> of the premise of your argument is that ioctls are not recommended, but in
> this particular case it seems like a good use case and there have been
> new ioctls added recently (at least according to git log).
> 
> This makes me think that while their use is not recommended, they can serve
> a purpose in specific use cases. To me, this use case seems very fitting.
> 
> More of a joke and I hate to mention this, but this setting is changing how
> io is done and it seems fitting that this done via an ioctl ;)
> 
> > epoll_pwait extends epoll_wait with a sigmask.
> > epoll_pwait2 extends extends epoll_pwait with nsec resolution timespec.
> > Since they are supersets, nothing is lots by limiting to the most recent API.
> > 
> > In the discussion of epoll_pwait2 the addition of a forward looking flags
> > argument was discussed, but eventually dropped. Based on the argument that
> > adding a syscall is not a big task and does not warrant preemptive code.
> > This decision did receive a suitably snarky comment from Jonathan Corbet [1].
> > 
> > It is definitely more boilerplate, but essentially it is as feasible to add an
> > epoll_pwait3 that takes an optional busy poll argument. In which case, I also
> > believe that it makes more sense to configure the behavior of the syscall
> > directly, than through another syscall and state stored in the kernel.
> 
> I definitely hear what you are saying; I think I'm still not convinced, but
> I am thinking it through.
> 
> In my mind, all of the other busy poll settings are configured by setting
> options on the sockets using various SO_* options, which modify some state
> in the kernel. The existing system-wide busy poll sysctl also does this. It
> feels strange to me to diverge from that pattern just for epoll.

I think the stateful approach for read is because there we do want
to support all variants: read, readv, recv, recvfrom, recvmsg,
recvmmsg. So there is no way to pass it directly.

That said, I don't mean to argue strenously for this API or against
yours. Want to make sure the option space is explored. There does not
seem to be much other feedback. I don't hold a strong opinion either.

> In the case of epoll_pwait2 the addition of a new syscall is an approach
> that I think makes a lot of sense. The new system call is also probably
> better from an end-user usability perspective, as well. For busy poll, I
> don't see a clear reasoning why a new system call is better, but maybe I am
> still missing something.
>
> > I don't think that the usec fine grain busy poll argument is all that useful.
> > Documentation always suggests setting it to 50us or 100us, based on limited
> > data. Main point is to set it to exceed the round-trip delay of whatever the
> > process is trying to wait on. Overestimating is not costly, as the call
> > returns as soon as the condition is met. An epoll_pwait3 flag EPOLL_BUSY_POLL
> > with default 100us might be sufficient.
> > 
> > [1] https://lwn.net/Articles/837816/
> 
> Perhaps I am misunderstanding what you are suggesting, but I am opposed to
> hardcoding a value. If it is currently configurable system-wide and via
> SO_* options for other forms of busy poll, I think it should similarly be
> configurable for epoll busy poll.
> 
> I may yet be convinced by the new syscall argument, but I don't think I'd
> agree on imposing a default. The value can be modified by other forms of
> busy poll and the goal of my changes are to:
>   - make epoll-based busy poll per context
>   - allow applications to configure (within reason) how epoll-based busy
>     poll behaves, like they can do now with the existing SO_* options for
>     other busy poll methods.

Okay. I expected some push back. Was curious if people would come back
with examples of where the full range is actually being used.

> > >     seems much simpler for users to use the correct
> > >     epoll_wait/epoll_pwait for their app and add a call to ioctl to enable
> > >     or disable busy poll as needed. This also probably means less work to
> > >     get an existing epoll app using busy poll.
> > 



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-01-30 20:33 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-25 22:56 [PATCH net-next v3 0/3] Per epoll context busy poll support Joe Damato
2024-01-25 22:56 ` [PATCH net-next v3 1/3] eventpoll: support busy poll per epoll instance Joe Damato
2024-01-25 22:56 ` [PATCH net-next v3 2/3] eventpoll: Add per-epoll busy poll packet budget Joe Damato
2024-01-25 22:56 ` [PATCH net-next v3 3/3] eventpoll: Add epoll ioctl for epoll_params Joe Damato
2024-01-25 23:20   ` Greg Kroah-Hartman
2024-01-26  0:04     ` Joe Damato
2024-01-25 23:21   ` Greg Kroah-Hartman
2024-01-26  0:11     ` Joe Damato
2024-01-26  0:23       ` Greg Kroah-Hartman
2024-01-26  2:36         ` Joe Damato
2024-01-26  6:16           ` Arnd Bergmann
2024-01-27 14:51             ` David Laight
2024-01-26 10:07           ` Christian Brauner
2024-01-26 16:52             ` Joe Damato
2024-01-25 23:22   ` Greg Kroah-Hartman
2024-01-26  0:07     ` Joe Damato
2024-01-28 11:24   ` kernel test robot
2024-01-27 16:20 ` [PATCH net-next v3 0/3] Per epoll context busy poll support Willem de Bruijn
2024-01-29 19:09   ` Joe Damato
2024-01-30 20:33     ` Willem de Bruijn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).