Skip to content

Commit

Permalink
epoll: do not take the nested ep->mtx on EPOLL_CTL_DEL
Browse files Browse the repository at this point in the history
The EPOLL_CTL_DEL path of epoll contains a classic, ab-ba deadlock.
That is, epoll_ctl(a, EPOLL_CTL_DEL, b, x), will deadlock with
epoll_ctl(b, EPOLL_CTL_DEL, a, x).  The deadlock was introduced with
commmit 67347fe ("epoll: do not take global 'epmutex' for simple
topologies").

The acquistion of the ep->mtx for the destination 'ep' was added such
that a concurrent EPOLL_CTL_ADD operation would see the correct state of
the ep (Specifically, the check for '!list_empty(&f.file->f_ep_links')

However, by simply not acquiring the lock, we do not serialize behind
the ep->mtx from the add path, and thus may perform a full path check
when if we had waited a little longer it may not have been necessary.
However, this is a transient state, and performing the full loop
checking in this case is not harmful.

The important point is that we wouldn't miss doing the full loop
checking when required, since EPOLL_CTL_ADD always locks any 'ep's that
its operating upon.  The reason we don't need to do lock ordering in the
add path, is that we are already are holding the global 'epmutex'
whenever we do the double lock.  Further, the original posting of this
patch, which was tested for the intended performance gains, did not
perform this additional locking.

Signed-off-by: Jason Baron <[email protected]>
Cc: Nathan Zimmer <[email protected]>
Cc: Eric Wong <[email protected]>
Cc: Nelson Elhage <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Davide Libenzi <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
almostivan authored and torvalds committed Jan 2, 2014
1 parent ad70b02 commit 4ff36ee
Showing 1 changed file with 0 additions and 4 deletions.
4 changes: 0 additions & 4 deletions fs/eventpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -1907,10 +1907,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
}
}
}
if (op == EPOLL_CTL_DEL && is_file_epoll(tf.file)) {
tep = tf.file->private_data;
mutex_lock_nested(&tep->mtx, 1);
}

/*
* Try to lookup the file inside our RB tree, Since we grabbed "mtx"
Expand Down

0 comments on commit 4ff36ee

Please sign in to comment.