[LTP] [PATCH v2] epoll_ctl06: Fix BPF map on old kernels
Martin Doucha
mdoucha@suse.cz
Wed Sep 30 15:45:35 CEST 2026
Hi,
look good to me.
Reviewed-by: Martin Doucha <mdoucha@suse.cz>
On 9/30/26 09:23, Andrea Cervesato wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> BPF map file descriptors gained a poll callback in upstream kernel
> 5.8. Without that callback, EPOLL_CTL_ADD fails with EPERM, while the
> test expected it to succeed.
>
> Detect BPF map poll support at runtime so that older kernels with
> backported support are handled correctly as well.
>
> Fixes: c4c0ca4c749e ("syscalls: Add epoll_ctl06")
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> tst_tmpdir.c:309: TINFO: Using /var/tmp/LTP_epoXsyHnT as tmpdir (btrfs filesystem)
> tst_test.c:2067: TINFO: LTP version: 20260529
> tst_test.c:2070: TINFO: Tested kernel: 4.4.140-491.1.TDC.gedc1884-default #1 SMP Wed Sep 23 11:06:41 UTC 2026 (edc1884) x86_64
> tst_kconfig.c:90: TINFO: Parsing kernel config '/proc/config.gz'
> tst_kconfig.c:760: TINFO: CONFIG_FAULT_INJECTION kernel option detected which might slow the execution
> tst_test.c:1897: TINFO: Overall timeout per run is 0h 02m 00s
> epoll_ctl06.c:57: TPASS: epoll_ctl() on file : EPERM (1)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on O_PATH file : EBADF (9)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on directory : EPERM (1)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on /dev/zero : EPERM (1)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on /proc/self/maps : EPERM (1)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on pipe read end passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on pipe write end passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on unix socket passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on inet socket passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on epoll passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on eventfd passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on signalfd passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on timerfd passed
> tst_fd.c:144: TCONF: pidfd_open(): ENOSYS (38)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on fanotify passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on inotify passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on userfaultfd passed
> epoll_ctl06.c:57: TPASS: epoll_ctl() on perf event passed
> tst_fd.c:200: TCONF: Skipping io uring: ENOSYS (38)
> epoll_ctl06.c:57: TFAIL: epoll_ctl() on bpf map failed: EPERM (1)
> tst_fd.c:225: TCONF: Skipping fsopen: ENOSYS (38)
> tst_fd.c:234: TCONF: Skipping fspick: ENOSYS (38)
> tst_fd.c:243: TCONF: Skipping open_tree: ENOSYS (38)
> epoll_ctl06.c:57: TPASS: epoll_ctl() on memfd : EPERM (1)
> tst_fd.c:261: TCONF: Skipping memfd secret: ENOSYS (38)
>
> Summary:
> passed 18
> failed 1
> broken 0
> skipped 6
> warnings 0
> ---
> Changes in v2:
> - skip after 5.8 kernel
> - Link to v1: https://lore.kernel.org/20260929-fix_epoll_bpf-v1-1-39b19ab043c7@suse.com
> ---
> testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
> index 69321582f..9c6cd2460 100644
> --- a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
> +++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
> @@ -12,19 +12,23 @@
> * poll file operation are expected to succeed. The rest must fail with:
> *
> * - EPERM for fds that are valid but lack poll support (regular files,
> - * directories, /dev/zero, /proc files, memfd).
> + * directories, /dev/zero, /proc files, memfd and BPF maps on kernels
> + * without BPF map poll support).
> * - EBADF for fds that are not usable for I/O (O_PATH, open_tree).
> */
>
> +#include <poll.h>
> #include <sys/epoll.h>
>
> #include "tst_test.h"
> #include "tst_epoll.h"
> #include "tst_fd.h"
>
> -static int exp_errno(enum tst_fd_type type)
> +static int exp_errno(struct tst_fd *fd)
> {
> - switch (type) {
> + struct pollfd pfd = {.fd = fd->fd, .events = POLLIN};
> +
> + switch (fd->type) {
> case TST_FD_FILE:
> case TST_FD_DIR:
> case TST_FD_DEV_ZERO:
> @@ -37,6 +41,16 @@ static int exp_errno(enum tst_fd_type type)
> case TST_FD_PATH:
> case TST_FD_OPEN_TREE:
> return EBADF;
> + case TST_FD_BPF_MAP:
> + if (tst_kvercmp(5, 8, 0) >= 0)
> + return 0;
> +
> + /*
> + * The BPF poll callback returns POLLERR for array maps. Without
> + * the callback, poll() returns the default readiness mask.
> + */
> + SAFE_POLL(&pfd, 1, 0);
> + return pfd.revents & POLLERR ? 0 : EPERM;
> default:
> return 0;
> }
> @@ -50,7 +64,7 @@ static void run(void)
> TST_FD_FOREACH(fd) {
> efd = SAFE_EPOLL_CREATE1(0);
> ev.data.fd = fd.fd;
> - err = exp_errno(fd.type);
> + err = exp_errno(&fd);
>
> TST_EXP_PASS_OR_FAIL(epoll_ctl(efd, EPOLL_CTL_ADD,
> fd.fd, &ev), err,
>
> ---
> base-commit: 1cbe713ca9d55bed7e4d52c6f2216ba3e2089346
> change-id: 20260929-fix_epoll_bpf-5e472da8e63c
>
> Best regards,
> --
> Andrea Cervesato <andrea.cervesato@suse.com>
>
>
--
Martin Doucha mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic
More information about the ltp
mailing list