summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/link/pipe
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-01-16 02:31:32 +0000
committergVisor bot <gvisor-bot@google.com>2021-01-16 02:31:32 +0000
commit1a5ad08a03f35c80f1ed18d7775e6322d8ba80ca (patch)
tree5158696d6cf7dcdf555e91471aa6f3260015b0a3 /pkg/tcpip/link/pipe
parenta22726e7b37507e88a2146509477ef5d400df23e (diff)
parent2814a032be7b34e4cc0c0607dba8030e74e11208 (diff)
Merge release-20210112.0-39-g2814a032b (automated)
Diffstat (limited to 'pkg/tcpip/link/pipe')
-rw-r--r--pkg/tcpip/link/pipe/pipe.go17
1 files changed, 16 insertions, 1 deletions
diff --git a/pkg/tcpip/link/pipe/pipe.go b/pkg/tcpip/link/pipe/pipe.go
index 12e246e21..d6e83a414 100644
--- a/pkg/tcpip/link/pipe/pipe.go
+++ b/pkg/tcpip/link/pipe/pipe.go
@@ -55,7 +55,22 @@ func (e *Endpoint) WritePacket(r stack.RouteInfo, _ *stack.GSO, proto tcpip.Netw
// remote address from the perspective of the other end of the pipe
// (e.linked). Similarly, the remote address from the perspective of this
// endpoint is the local address on the other end.
- e.linked.dispatcher.DeliverNetworkPacket(r.LocalLinkAddress /* remote */, r.RemoteLinkAddress /* local */, proto, stack.NewPacketBuffer(stack.PacketBufferOptions{
+ //
+ // Deliver the packet in a new goroutine to escape this goroutine's stack and
+ // avoid a deadlock when a packet triggers a response which leads the stack to
+ // try and take a lock it already holds.
+ //
+ // As of writing, a deadlock may occur when performing link resolution as the
+ // neighbor table will send a solicitation while holding a lock and the
+ // response advertisement will be sent in the same stack that sent the
+ // solictation. When the response is received, the stack attempts to take the
+ // same lock it already took before sending the solicitation, leading to a
+ // deadlock. Basically, we attempt to lock the same lock twice in the same
+ // call stack.
+ //
+ // TODO(gvisor.dev/issue/5289): don't use a new goroutine once we support send
+ // and receive queues.
+ go e.linked.dispatcher.DeliverNetworkPacket(r.LocalLinkAddress /* remote */, r.RemoteLinkAddress /* local */, proto, stack.NewPacketBuffer(stack.PacketBufferOptions{
Data: buffer.NewVectorisedView(pkt.Size(), pkt.Views()),
}))