-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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.14] Always migrate cilium_calls_* during ELF load #28830
Conversation
[ upstream commit 9420217 ] See code comments, as the change is subtle. This sets things up for subsequent commits. As a minor benefit, make the code slightly less unreadable. Signed-off-by: Timo Beckers <timo@isovalent.com>
/test-backport-1.14 |
[ upstream commit 94ec45a ] Note: this is obviously a hack. There's a long-standing issue with Cilium's loader infrastructure where program arrays like cilium_calls_* are reused if the map's properties in the ELF are compatible with the pinned version present on the system. This has been the case since the early iproute2 days, and ebpf-go has the same behaviour by default. This is unsound, but doesn't always cause issues in practice. However, as Cilium's eBPF code base grew, along with its contributor base, increasing code churn and the need to backport fixes, this method started falling apart. Pinned tail call maps are actively used for handling traffic, and should be considered fixed, as they are an integral part of the program's control flow. When another BPF object needs to be attached to a kernel hook, it's incorrect to replace entries in an existing program array used by a prior version of the BPF object, since logic in some tail calls may have been enabled or disabled in the new one, or may have been removed altogether. A prog array's contents cannot be replaced atomically, meaning that while the prog array is being repopulated by a new ELF, a packet may be processed by a chain of programs that are partially old and partially new. This is bad. This patch fixes the specific case of cilium_calls_*, since it's the only prog array across all ELFs that consistently acts as the central tail call map. The main motivation for this approach is backportability as far back as 1.12, since we're seeing increased connectivity interruptions (leading to test flakes) during up/downgrades and restarts in that branch. This is caused by other backports creating code churn, as well as the stark difference in the contents of tail calls between major Cilium versions. This code will be replaced by a 'commit' system that does away with the re- pinning behaviour and keeps new map fd's in memory; only committing them to bpffs when the necessary endpoint prog(s) were successfully replaced. Fixes: cilium#20691 Signed-off-by: Timo Beckers <timo@isovalent.com>
fd9f5a5
to
49860e4
Compare
Marking as "Don't merge", we'll let the changes bake in main for a few days to check that they are safe. |
/test-backport-1.14 |
Can we get this one merged? This would allow to see if it makes things better with the upgrade/downgrade from main test. |
@@ -90,35 +92,52 @@ func repinMap(bpffsPath string, name string, spec *ebpf.MapSpec) error { | |||
if err != nil { | |||
return fmt.Errorf("map not found at path %s: %v", name, err) | |||
} | |||
defer pinned.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that closing a pinned map FD doesn't cause any side-effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this Close() should've always been there. Without it, the GC closes the fd.
|
||
if pinned.Type() == spec.Type && | ||
pinned.KeySize() == spec.KeySize && | ||
pinned.ValueSize() == spec.ValueSize && | ||
pinned.Flags() == spec.Flags && | ||
pinned.MaxEntries() == spec.MaxEntries { | ||
return nil | ||
// cilium_calls_xdp is shared between XDP interfaces and should only be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you create a GH issue to document the fact that the cilium_calls_xdp
is shared among all XDP progs. I think it's a ticking bomb once we move more functionality to the XDP layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM. Minor comments. I will ACK once #29045 has passed (ci-ipsec-upgrade: this PR branch -> main -> this PR branch).
Since [1] got merged, we can re-enable the check. [1]: #28830. Signed-off-by: Martynas Pumputis <m@lambda.lt>
Manual backport of #28740.