From: Eric Dumazet <dada1@cosmosbay.com>
To: Tony Battersby <tonyb@cybernetics.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Davide Libenzi <davidel@xmailserver.org>,
Jonathan Corbet <corbet@lwn.net>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/6] [2.6.29] epoll: fix for epoll_wait sometimes returning events on closed fds
Date: Tue, 24 Feb 2009 19:12:13 +0100 [thread overview]
Message-ID: <49A4387D.2020801@cosmosbay.com> (raw)
In-Reply-To: <49A42DDE.8060605@cybernetics.com>
Tony Battersby a écrit :
>>From the epoll manpage:
> Q: Will closing a file descriptor cause it to be removed from all
> epoll sets automatically?
> A: Yes
>
> sys_close() calls filp_close(), which calls fput(). If no one else
> holds a reference to the file, then fput() calls __fput(), and __fput()
> calls eventpoll_release(), which prevents epoll_wait() from returning
> events on the fd to userspace. In the rare case that sys_close()
> doesn't call __fput() because someone else has a reference to the file,
> a subsequent epoll_wait() may still unexpectedly return events on the
> fd after it has been closed. This can end up confusing or crashing
> a userspace program that doesn't do epoll_ctl(EPOLL_CTL_DEL) before
> closing the fd. I have reports of this actually happening under
> heavy load with a program using epoll with network sockets on 2.6.27.
>
> This patch fixes the problem by calling eventpoll_release_file()
> from filp_close() instead of from __fput().
>
> The locking in eventpoll_release() and eventpoll_release_file() needs
> to be changed because previously it relied on the fact that no one
> else could have a reference to the file when called from __fput(),
> and this is no longer true. The new locking is admittedly ugly,
> but I believe it works.
>
> ep_insert() now also needs to check if the file has been closed
> to avoid races in multi-threaded programs where one thread is doing
> epoll_ctl(EPOLL_CTL_ADD) and another thread is closing the fd. This is
> done by checking that fget_light still returns the same struct file *
> as before.
>
> Note that the list_del_init(&epi->fllink) previously done in
> eventpoll_release_file() was unnecessary because it is also done
> by ep_remove().
>
> Userspace programs that might run on kernels with this bug can work
> around the problem by doing epoll_ctl(EPOLL_CTL_DEL) before close().
>
> Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
> CC: <stable@kernel.org>
Your patch may solve part of the problem. In your programs, maybe you
have one thread doing all epoll_wait() and close() syscalls, but what
of other programs ?
What prevents a thread doing close(fd) right after an other thread
got this fd from epoll_wait() ?
Nothing, and application may strangely react.
The moment you have several threads doing read()/write()/close() syscalls
on the same fd at the same time, you obviously get problems, not
only with epoll.
In a typical epoll driven application, with a pool of N worker threads all doing :
while (1) {
fd = epoll_wait(epoll_fd);
work_on_fd(fd); /* possibly calling close(fd); */
}
Then, you must be prepared to get a *false* event, ie an fd that another worker
already closed (and eventually reopened)
next prev parent reply other threads:[~2009-02-24 18:12 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-24 17:26 [PATCH 1/6] [2.6.29] epoll: fix for epoll_wait sometimes returning events on closed fds Tony Battersby
2009-02-24 18:12 ` Eric Dumazet [this message]
2009-02-24 18:44 ` Tony Battersby
2009-02-24 19:52 ` Eric Dumazet
2009-02-24 20:36 ` Tony Battersby
2009-02-24 20:45 ` Davide Libenzi
2009-02-24 20:52 ` Tony Battersby
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49A4387D.2020801@cosmosbay.com \
--to=dada1@cosmosbay.com \
--cc=akpm@linux-foundation.org \
--cc=corbet@lwn.net \
--cc=davidel@xmailserver.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tonyb@cybernetics.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.