Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

socket: fix deadlock in rpc_reconnect_requeue #127

Merged
merged 1 commit into from
Sep 6, 2015

Conversation

plieven
Copy link
Contributor

@plieven plieven commented Aug 28, 2015

the requeueing code is broken because we access pdu->next
after we mangled it in rpc_return_to_queue.

This leads to losing of waitqueue elements and more severe
a deadlock as soon as more than one waitpdu queue has elements.

Reason for that is that the first elements of the first
two queues are linked to each other.

Example:
waitpdu[0]->head = pduA ; pduA->next = pduB; pduB->next = NULL;
waitpdu[1]->head = pduC ; pduC->next = NULL;
outqueue->head = NULL;

After the for loop for waitpdu[0] queue the outqueue looks like

outqueue->head = pduA; pduA->next = NULL;

At this point pduB is lost!

In the for loop for waitpdu[1] queue the outqueue looks like this
after the first iteration:

outqueue->head = pduC; pduC->next = pduA; pduA->next = NULL;

We now fetch pdu->next of pduC which is pduA.

In the next iteration we put pduA in front of pduC. pduA->next
is then pduC and pduC->next is pduA. => Deadlock.

Signed-off-by: Peter Lieven pl@kamp.de

the requeueing code is broken because we access pdu->next
after we mangled it in rpc_return_to_queue.

This leads to losing of waitqueue elements and more severe
a deadlock as soon as more than one waitpdu queue has elements.

Reason for that is that the first elements of the first
two queues are linked to each other.

Example:
waitpdu[0]->head = pduA ; pduA->next = pduB; pduB->next = NULL;
waitpdu[1]->head = pduC ; pduC->next = NULL;
outqueue->head = NULL;

After the for loop for waitpdu[0] queue the outqueue looks like

outqueue->head = pduA; pduA->next = NULL;

At this point pduB is lost!

In the for loop for waitpdu[1] queue the outqueue looks like this
after the first iteration:

outqueue->head = pduC; pduC->next = pduA; pduA->next = NULL;

We now fetch pdu->next of pduC which is pduA.

In the next iteration we put pduA in front of pduC. pduA->next
is then pduC and pduC->next is pduA. => Deadlock.

Signed-off-by: Peter Lieven <pl@kamp.de>
sahlberg added a commit that referenced this pull request Sep 6, 2015
socket: fix deadlock in rpc_reconnect_requeue
@sahlberg sahlberg merged commit 96142f9 into sahlberg:master Sep 6, 2015
@sahlberg
Copy link
Owner

sahlberg commented Sep 6, 2015

Merged, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants