[lkml]   [2008]   [Oct]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[patch] epoll avoid double-inserts in case of EFAULT

    First Episode:

    Thomas found that there is an unnecessary (always true) test in
    ep_send_events(). The callback never inserts into ->rdllink while the
    send loop is performed, and also does the ~EP_PRIVATE_BITS test. Given
    we're holding the mutex during this time, the conditions tested inside the
    loop are always true.
    This patch drops the test done inside the re-insertion loop.

    Second Episode:

    The test "!ep_is_linked(&epi->rdllink)" wasn't there because we inserts
    into ->rdllink, but because the send-events loop might terminate before
    the whole list is scanned (-EFAULT). In such cases, when the loop
    terminates early, and when a (leftover) file received an event while we're
    performing the lockless loop, we need such test to avoid to double insert
    the epoll items. The list_splice() done a few steps below, will correctly
    re-insert the ones that were left on "txlist".
    This should be the reason for the thread "2.6.27-05178-g2e532d6: list_add
    corruption" from Alexander Beregalov.

    Signed-off-by: Davide Libenzi <>

    - Davide

    fs/eventpoll.c | 11 +++++++++--
    1 file changed, 9 insertions(+), 2 deletions(-)

    Index: linux-2.6.mod/fs/eventpoll.c
    --- linux-2.6.mod.orig/fs/eventpoll.c 2008-10-17 15:51:09.000000000 -0700
    +++ linux-2.6.mod/fs/eventpoll.c 2008-10-17 15:54:14.000000000 -0700
    @@ -930,8 +930,15 @@
    * inside the main ready-list here.
    for (nepi = ep->ovflist; (epi = nepi) != NULL;
    - nepi = epi->next, epi->next = EP_UNACTIVE_PTR)
    - list_add_tail(&epi->rdllink, &ep->rdllist);
    + nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
    + /*
    + * If the above loop quit with errors, the epoll item might still
    + * be linked to "txlist", and the list_splice() done below will
    + * take care of those cases.
    + */
    + if (!ep_is_linked(&epi->rdllink))
    + list_add_tail(&epi->rdllink, &ep->rdllist);
    + }
    * We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
    * releasing the lock, events will be queued in the normal way inside

     \ /
      Last update: 2008-10-18 01:21    [W:0.021 / U:9.084 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site