kern_event socket deadlock
kern_event socket deadlock
- Subject: kern_event socket deadlock
- From: Matt Darland <email@hidden>
- Date: Tue, 19 Dec 2006 11:30:36 -0600
I think I've found a deadlock condition between kern_event sockets
disposal and data posting, but I want to make sure my theory passes
muster with the Darwin kernel guys before filing a radar. Once this
happens, the whole system goes unstable in various ways. I can
reproduce this condition reliably.
From kern_event.c (with my notes prefixed with MTD):
static int
kev_detach(struct socket *so)
{
// MTD: kev_detach caller has sock_locked(so).
struct kern_event_pcb *ev_pcb = (struct kern_event_pcb *) so-
>so_pcb;
if (ev_pcb != 0) {
// MTD If someone is posting a message, then we have to wait here.
lck_mtx_lock(evt_mutex);
// MTD: But we're still on the list ?!? What if kev_post_msg() tries
to append data to this socket?
LIST_REMOVE(ev_pcb, ev_link);
lck_mtx_unlock(evt_mutex);
FREE(ev_pcb, M_PCB);
so->so_pcb = 0;
so->so_flags |= SOF_PCBCLEARING;
}
return 0;
}
int kev_post_msg(struct kev_msg *event_msg)
{
// ...
// MTD: Non-pertinent code. Removed.
lck_mtx_lock(evt_mutex);
// MTD: Now kev_detach() has to wait for this mutex to be unlocked.
for (ev_pcb = LIST_FIRST(&kern_event_head);
ev_pcb;
ev_pcb = LIST_NEXT(ev_pcb, ev_link)) {
if (ev_pcb->vendor_code_filter != KEV_ANY_VENDOR) {
if (ev_pcb->vendor_code_filter != ev->vendor_code)
continue;
if (ev_pcb->class_filter != KEV_ANY_CLASS) {
if (ev_pcb->class_filter != ev->kev_class)
continue;
if ((ev_pcb->subclass_filter != KEV_ANY_SUBCLASS) &&
(ev_pcb->subclass_filter != ev->kev_subclass))
continue;
}
}
m2 = m_copym(m, 0, m->m_len, M_NOWAIT);
if (m2 == 0) {
m_free(m);
lck_mtx_unlock(evt_mutex);
return ENOBUFS;
}
// MTD: Oh oh, this socket is locked down, in kev_detach(). Now we're
hung.
socket_lock(ev_pcb->ev_socket, 1);
if (sbappendrecord(&ev_pcb->ev_socket->so_rcv, m2))
sorwakeup(ev_pcb->ev_socket);
socket_unlock(ev_pcb->ev_socket, 1);
}
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden