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

[v1.13 backport] Three fixes for deadlocks #24814

Merged

Conversation

gandro
Copy link
Member

@gandro gandro commented Apr 11, 2023

Once this PR is merged, you can update the PR labels via:

$ for pr in 24672; do contrib/backporting/set-labels.py $pr done 1.13; done

@gandro gandro added the release-blocker/1.13 This issue will prevent the release of the next version of Cilium. label Apr 11, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added backport/1.13 This PR represents a backport for Cilium 1.13.x of a PR that was merged to main. kind/backports This PR provides functionality previously merged into master. labels Apr 11, 2023
gandro and others added 3 commits April 11, 2023 18:35
[ upstream commit 3067e16 ]

This fixes a deadlock with the IPCache and the endpoint mutex where
writeHeaderfile calls into the proxy to fetch the endpoint's DNSRules
while holding on to the endpoint mutex. That pattern causes a deadlock,
because the proxy code itself then calls into IPCache while the endpoint
mutex is held. This violates the assumed lock ordering, as we require
that the IPCache mutex is always acquired _before_ any endpoint mutex.

We fix this deadlock by hoisting call to update the endpoint's DNSRules
out of writeHeaderfile and into the syncEndpointHeaderFile function,
which is triggered whenever there is a change in DNSRules.

Fixes: cilium#23836
Ref: cilium#20915

Co-authored-by: David Bimmler <david.bimmler@isovalent.com>
Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
Signed-off-by: David Bimmler <david.bimmler@isovalent.com>
[ upstream commit d91219a ]

GetRules held the DNSProxy lock while accessing IPCache. This
established a partial lock order in which DNSProxy > IPCache. (Read
DNSProxy > IPCache as "DNSProxy lock held while attempting to acquire
IPCache lock." We use '>' as a convenient notation as it intuitively
implies transitivity.)

Since we also have IPCache > Endpoint (cf InjectLabels), this
established DNSProxy > Endpoint by transitivity. That, however, is
incompatible with instances where we hold the Endpoint lock while
acquiring the DNSProxy lock (as that establishes Endpoint > DNSProxy).
Having both EP > DNSProxy and DNSProxy > EP is not allowed and leads to
deadlocks. To break the cycle, hoist the IPCache lookups out of the
DNSProxy critical section.

Without DNSProxy > IPCache, Endpoint > DNSProxy is fine, as there's no
more DNSPRoxy > IPCache > Endpoint and wait cycle.

Of course, any other instance where X > IPCache and Endpoint > X can
still result in a deadlock. Somewhat insidiously, these wait chains can
be arbitrarily long, and hence arbitrarily difficult to find.

Suggested-by: Sebastian Wicki <sebastian@isovalent.com>
Suggested-by: Chris Tarazi <chris@isovalent.com>
Suggested-by: Joe Stringer <joe@cilium.io>
Signed-off-by: David Bimmler <david.bimmler@isovalent.com>
Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
[ upstream commit 93cd67f ]

We have a partial lock ordering of IPCache > Endpoint as established in
InjectLabels, where the IPCache lock is held and all endpoint locks are
acquired one by one. On the other hand, GetNamedPorts was called in a
context with the Endpoint lock held (cf *Endpoint.GetNamedPortLocked),
and attempts to acquire the IPCache lock. This would establish EP >
IPCache, which potentially deadlocks with the above.

To fix it, remove the requirement for a write lock on IPCache for
GetNamedPorts. Instead, we always pre-compute the namedPorts map in
Upsert and Delete and simply return it in GetNamedPorts. To ensure
atomicity, we use atomics to load and store read-only pointer to the
namedPorts map and the needNamedPorts flag.

Co-authored-by: Sebastian Wicki <sebastian@isovalent.com>
Signed-off-by: David Bimmler <david.bimmler@isovalent.com>
Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
@gandro gandro force-pushed the pr/gandro/v1.13-three-fixes-for-deadlocks branch from b8e3f84 to 117cc6e Compare April 11, 2023 16:36
@gandro
Copy link
Member Author

gandro commented Apr 11, 2023

/test-backport-1.13

Job 'Cilium-PR-K8s-1.20-kernel-4.9' failed:

Click to show.

Test Name

K8sDatapathConfig MonitorAggregation Checks that monitor aggregation restricts notifications

Failure Output

FAIL: Unable to retrieve DNS pods to scale down, command 'kubectl get deploy -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[*].status.replicas}'': Exitcode: 1 

Jenkins URL: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.20-kernel-4.9/1781/

If it is a flake and a GitHub issue doesn't already exist to track it, comment /mlh new-flake Cilium-PR-K8s-1.20-kernel-4.9 so I can create one.

Job 'Cilium-PR-K8s-1.20-kernel-4.9' failed:

Click to show.

Test Name

K8sDatapathVerifier Runs the kernel verifier against Cilium's BPF datapath

Failure Output

FAIL: Failed to load BPF program bpf_host with datapath configuration:

Jenkins URL: https://jenkins.cilium.io/job/Cilium-PR-K8s-1.20-kernel-4.9/1789/

If it is a flake and a GitHub issue doesn't already exist to track it, comment /mlh new-flake Cilium-PR-K8s-1.20-kernel-4.9 so I can create one.

@gandro gandro marked this pull request as ready for review April 11, 2023 16:37
@gandro gandro requested a review from a team as a code owner April 11, 2023 16:37
@gandro
Copy link
Member Author

gandro commented Apr 12, 2023

/test-1.20-4.9

Created: #24839

@gandro
Copy link
Member Author

gandro commented Apr 12, 2023

test-1.20-4.9 keeps failing with the same error in different tests. Not clear to me if this is due to an unsupported kernel version in the pipeline or if something else is off.

@gandro
Copy link
Member Author

gandro commented Apr 12, 2023

/test-1.20-4.9

Copy link
Member

@dylandreimerink dylandreimerink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@michi-covalent
Copy link
Contributor

how do i trigger ingress-conformance-test? it's marked as required, but it's not getting triggered 👀

@joestringer
Copy link
Member

I wonder if it was renamed?

image

@michi-covalent
Copy link
Contributor

yeah maybe. @joestringer could you check the branch protection roles for v1.13 and see if ingress-conformance-test is listed as required? 🥺

@joestringer
Copy link
Member

I've removed the requirement for ingress-conformance-test from the v1.13 branch. What I find confusing is that I cannot search and find the jobs for these runs: https://github.com/cilium/cilium/actions/runs/4669880410?pr=24814 . cc @sayboras so currently ConformanceIngress is not required for merging v1.13 PRs until we get to the bottom of this.

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Apr 12, 2023
@joestringer joestringer merged commit 5f6860b into cilium:v1.13 Apr 12, 2023
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/1.13 This PR represents a backport for Cilium 1.13.x of a PR that was merged to main. kind/backports This PR provides functionality previously merged into master. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-blocker/1.13 This issue will prevent the release of the next version of Cilium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants