• Heiher's avatar
    fs/epoll: remove unnecessary wakeups of nested epoll · 339ddb53
    Heiher authored
    Take the case where we have:
    
            t0
             | (ew)
            e0
             | (et)
            e1
             | (lt)
            s0
    
    t0: thread 0
    e0: epoll fd 0
    e1: epoll fd 1
    s0: socket fd 0
    ew: epoll_wait
    et: edge-trigger
    lt: level-trigger
    
    We remove unnecessary wakeups to prevent the nested epoll that working in edge-
    triggered mode to waking up continuously.
    
    Test code:
     #include <unistd.h>
     #include <sys/epoll.h>
     #include <sys/socket.h>
    
     int main(int argc, char *argv[])
     {
     	int sfd[2];
     	int efd[2];
     	struct epoll_event e;
    
     	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0)
     		goto out;
    
     	efd[0] = epoll_create(1);
     	if (efd[0] < 0)
     		goto out;
    
     	efd[1] = epoll_create(1);
     	if (efd[1] < 0)
     		goto out;
    
     	e.events = EPOLLIN;
     	if (epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e) < 0)
     		goto out;
    
     	e.events = EPOLLIN | EPOLLET;
     	if (epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e) < 0)
     		goto out;
    
     	if (write(sfd[1], "w", 1) != 1)
     		goto out;
    
     	if (epoll_wait(efd[0], &e, 1, 0) != 1)
     		goto out;
    
     	if (epoll_wait(efd[0], &e, 1, 0) != 0)
     		goto out;
    
     	close(efd[0]);
     	close(efd[1]);
     	close(sfd[0]);
     	close(sfd[1]);
    
     	return 0;
    
     out:
     	return -1;
     }
    
    More tests:
     https://github.com/heiher/epoll-wakeup
    
    Link: http://lkml.kernel.org/r/20191009060516.3577-1-r@hev.ccSigned-off-by: default avatarhev <r@hev.cc>
    Reviewed-by: default avatarRoman Penyaev <rpenyaev@suse.de>
    Cc: Al Viro <viro@ZenIV.linux.org.uk>
    Cc: Davide Libenzi <davidel@xmailserver.org>
    Cc: Davidlohr Bueso <dave@stgolabs.net>
    Cc: Dominik Brodowski <linux@dominikbrodowski.net>
    Cc: Eric Wong <e@80x24.org>
    Cc: Jason Baron <jbaron@akamai.com>
    Cc: Sridhar Samudrala <sridhar.samudrala@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    339ddb53
eventpoll.c 63.8 KB