Commit 75815c15 authored by Witold Krecicki's avatar Witold Krecicki Committed by Witold Krecicki
Browse files

Fix a possible deadlock in TCP accepting

Each network thread holds an array of locks, indexed by a hash
of fd. When we accept a connection we hold a lock in accepting thread.
We then generate the thread number and lock bucket for the new
connection socket - if we hit the same thread and lock bucket as
accepting socket we get a deadlock. Avoid this by checking if we're
in the same thread/lock bucket and not locking in this case.
parent 4d498b3d
Pipeline #15020 passed with stages
in 10 minutes and 55 seconds
5238. [bug] Fix a possible deadlock in TCP code. [GL #1046]
5237. [bug] Recurse to find the root server list with 'dig +trace'. 5237. [bug] Recurse to find the root server list with 'dig +trace'.
[GL #1028] [GL #1028]
   
......
...@@ -2977,6 +2977,13 @@ internal_accept(isc__socket_t *sock) { ...@@ -2977,6 +2977,13 @@ internal_accept(isc__socket_t *sock) {
NEWCONNSOCK(dev)->connected = 1; NEWCONNSOCK(dev)->connected = 1;
nthread = &manager->threads[NEWCONNSOCK(dev)->threadid]; nthread = &manager->threads[NEWCONNSOCK(dev)->threadid];
/*
* We already hold a lock on one fdlock in accepting thread,
* we need to make sure that we don't double lock.
*/
bool same_bucket = (sock->threadid == NEWCONNSOCK(dev)->threadid) &&
(FDLOCK_ID(sock->fd) == lockid);
/* /*
* Use minimum mtu if possible. * Use minimum mtu if possible.
*/ */
...@@ -2999,13 +3006,17 @@ internal_accept(isc__socket_t *sock) { ...@@ -2999,13 +3006,17 @@ internal_accept(isc__socket_t *sock) {
NEWCONNSOCK(dev)->active = 1; NEWCONNSOCK(dev)->active = 1;
} }
if (!same_bucket) {
LOCK(&nthread->fdlock[lockid]); LOCK(&nthread->fdlock[lockid]);
}
nthread->fds[fd] = NEWCONNSOCK(dev); nthread->fds[fd] = NEWCONNSOCK(dev);
nthread->fdstate[fd] = MANAGED; nthread->fdstate[fd] = MANAGED;
#if defined(USE_EPOLL) #if defined(USE_EPOLL)
nthread->epoll_events[fd] = 0; nthread->epoll_events[fd] = 0;
#endif #endif
if (!same_bucket) {
UNLOCK(&nthread->fdlock[lockid]); UNLOCK(&nthread->fdlock[lockid]);
}
LOCK(&manager->lock); LOCK(&manager->lock);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment