Re: deadlock in epoll (found by lockdep)
From: Davide Libenzi
Date: Thu Jun 01 2006 - 11:52:11 EST
On Thu, 1 Jun 2006, Arjan van de Ven wrote:
in ep_poll() (fs/eventpoll.c) the code does
write_lock_irqsave(&ep->lock, flags);
res = 0;
if (list_empty(&ep->rdllist)) {
/*
* We don't have any available event to return to the caller.
* We need to sleep here, and we will be wake up by
* ep_poll_callback() when events will become available.
*/
init_waitqueue_entry(&wait, current);
add_wait_queue(&ep->wq, &wait);
eg we first take ep->lock and then call add_wait_queue which takes
spin_lock_irqsave(&q->lock, flags);
for obvious reasons.
this would mean that ep->lock would be the outer lock, and q->lock the
HOWEVER, __wake_up does this:
void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, void *key)
{
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
__wake_up_common(q, mode, nr_exclusive, 0, key);
spin_unlock_irqrestore(&q->lock, flags);
}
where __wake_up_common calls into ep_poll_callback, which in term does
write_lock_irqsave(&ep->lock, flags);
as one of the first things.
... which implies that q->lock is the outer lock, and ep->lock is the
inner lock....
can you explain which order is right, and if/why this is not an AB-BA
deadlock??
Just woke up and still dangerously low on caffeine, but that would happen
if and only if the wake up target of the epoll fd #N is the epoll fd #N,
and this is explicitly denied in epoll_ctl(ADD). I'll take a deeper look
once I get in the office with my venti latte ;)
- Davide
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/