[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