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

maps: switch maglev to cilium/ebpf package #15546

Merged
merged 1 commit into from Jun 21, 2021
Merged

Conversation

jibi
Copy link
Member

@jibi jibi commented Apr 2, 2021

No description provided.

@jibi jibi added sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. dont-merge/wait-until-release Freeze window for current release is blocking non-bugfix PRs release-note/misc This PR makes changes that have no direct user impact. labels Apr 2, 2021
@maintainer-s-little-helper maintainer-s-little-helper bot added this to In progress in 1.10.0 Apr 2, 2021
@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch 4 times, most recently from 311393d to 084f15d Compare April 2, 2021 13:53
@aditighag
Copy link
Member

Nice! Fyi - you can drop the first commit - #15386 (comment).

@brb
Copy link
Member

brb commented Apr 2, 2021

cc @christarazi (Chris has a WIP to make inner maps of a different size).

@jibi
Copy link
Member Author

jibi commented Apr 2, 2021

Nice! Fyi - you can drop the first commit - #15386 (comment).

Thanks for the headsup @aditighag 🙌
I actually do need v0.4.0 as I'm using the new Unpin() method (but I'll keep an eye on your PR and rebase once that's sorted)

@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch 6 times, most recently from 332e25a to eafd50c Compare April 6, 2021 15:22
@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch 3 times, most recently from 56216e3 to af21d5c Compare May 17, 2021 14:36
@jibi jibi marked this pull request as ready for review May 17, 2021 14:36
@jibi jibi requested a review from a team May 17, 2021 14:36
@jibi jibi requested a review from a team as a code owner May 17, 2021 14:36
@jibi jibi requested review from jrfastab and twpayne May 17, 2021 14:36
Copy link
Contributor

@twpayne twpayne left a comment

Choose a reason for hiding this comment

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

LGTM, just a couple of nits, feel free to ignore them.

cilium/cmd/bpf_lb_maglev_list.go Show resolved Hide resolved
pkg/maps/lbmap/maglev.go Outdated Show resolved Hide resolved
pkg/maps/lbmap/maglev.go Outdated Show resolved Hide resolved
pkg/maps/lbmap/maglev_outer_map.go Outdated Show resolved Hide resolved
pkg/maps/lbmap/maglev_inner_map.go Show resolved Hide resolved
pkg/maps/lbmap/maglev_inner_map.go Show resolved Hide resolved
@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch from c32b28e to b90d982 Compare June 3, 2021 14:59
@jibi jibi closed this Jun 3, 2021
@jibi jibi reopened this Jun 3, 2021
@jibi
Copy link
Member Author

jibi commented Jun 3, 2021

@brb @christarazi while doing another round of tests I realized that whenever we need to access an existing maglev map from the cilium bpf lb maglev {list,get} commands we should just open the pinned map from its FD rather than using (m *ebpf.Map) OpenOrCreate(), which expects a map's spec and tries to create the map if it doesn't exist.

Therefore I added a new function to the ebpf package, OpenMap() (which mimics the OpenMap() function from the bpf package) and updated lbmap.MaybeInitMaglevMaps() to use that.

@jibi jibi marked this pull request as ready for review June 3, 2021 19:16
Copy link
Member

@christarazi christarazi left a comment

Choose a reason for hiding this comment

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

LGTM re: the new changes. It should be compatible with #15019, which I'll rebase on top of this PR soon.

pkg/maps/lbmap/maglev.go Show resolved Hide resolved
pkg/maps/lbmap/maglev_inner_map.go Outdated Show resolved Hide resolved
@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch 3 times, most recently from 8ae21dd to 96f95f5 Compare June 4, 2021 08:58
@jibi
Copy link
Member Author

jibi commented Jun 4, 2021

test-me-please

@christarazi
Copy link
Member

christarazi commented Jun 17, 2021

@jibi I finally got around to rebasing my PR (#15019) on top of this and I ran into an issue.

The summary is that when you specify an InnerMap inside a MapSpec, then cilium/ebpf will create / open this inner map automatically. Whereas in the previous code, we created the inner map manually. In this PR, we are still creating the inner map manually, but we're also specifying the InnerMap field for the outer map, which causes cilium/ebpf to create a new inner map, eventually causing mismatching FDs because the original FD was just overwritten. This conflicting FD is the FD of the inner map stored inside the MaglevOuterVal. The consequence of this is that when you update the outer map, you get an "invalid argument" errno returned, obviously because the wrong FD was used.

I've worked around this manually by changing the NewMaglevInnerMap constructor to only return the MapSpec and not to create the inner map. Inside updateMaglevTable, I then create / open the map.

Here's the diff:

diff --git a/pkg/maps/lbmap/maglev.go b/pkg/maps/lbmap/maglev.go
index 286aa078c..8760b94bb 100644
--- a/pkg/maps/lbmap/maglev.go
+++ b/pkg/maps/lbmap/maglev.go
@@ -42,12 +42,9 @@ var (
 
 // InitMaglevMaps inits the ipv4 and/or ipv6 maglev outer and inner maps.
 func InitMaglevMaps(ipv4, ipv6 bool, tableSize uint32) error {
-	dummyInnerMap, dummyInnerMapSpec, err := NewMaglevInnerMap("cilium_lb_maglev_dummy", tableSize)
-	if err != nil {
-		return err
-	}
-	defer dummyInnerMap.Close()
+	dummyInnerMapSpec := NewMaglevInnerMap("cilium_lb_maglev_dummy", tableSize)
 
+	var err error
 	// Always try to delete old maps with the wrong M parameter, otherwise
 	// we may end up in a case where there are 2 maps (one for IPv4 and
 	// one for IPv6), one of which is not used, with 2 different table
@@ -173,12 +170,18 @@ func updateMaglevTable(ipv6 bool, revNATID uint16, backendIDs []uint16, tableSiz
 		innerMapName = MaglevInner6MapName
 	}
 
-	innerMap, _, err := NewMaglevInnerMap(innerMapName, uint32(tableSize))
+	innerMapSpec := NewMaglevInnerMap(innerMapName, uint32(tableSize))
+	m := ebpf.NewMap(innerMapSpec)
+	err := m.OpenOrCreate()
 	if err != nil {
 		return err
 	}
-	defer innerMap.Close()
+	defer m.Close()
 
+	innerMap := &maglevInnerMap{
+		Map:       m,
+		tableSize: uint32(tableSize),
+	}
 	if err := updateMaglevInnerMap(innerMap, backendIDs); err != nil {
 		return err
 	}
diff --git a/pkg/maps/lbmap/maglev_inner_map.go b/pkg/maps/lbmap/maglev_inner_map.go
index 5a9680a72..a497507ce 100644
--- a/pkg/maps/lbmap/maglev_inner_map.go
+++ b/pkg/maps/lbmap/maglev_inner_map.go
@@ -79,8 +79,8 @@ func (m maglevInnerVals) MarshalBinary() ([]byte, error) {
 }
 
 // NewMaglevInnerMap returns a new object representing a maglev inner map.
-func NewMaglevInnerMap(name string, tableSize uint32) (*maglevInnerMap, *ebpf.MapSpec, error) {
-	spec := &ebpf.MapSpec{
+func NewMaglevInnerMap(name string, tableSize uint32) *ebpf.MapSpec {
+	return &ebpf.MapSpec{
 		Name:       name,
 		Type:       ebpf.Array,
 		KeySize:    uint32(unsafe.Sizeof(MaglevInnerKey{})),
@@ -88,16 +88,6 @@ func NewMaglevInnerMap(name string, tableSize uint32) (*maglevInnerMap, *ebpf.Ma
 		MaxEntries: tableSizeToMaxEntries(tableSize),
 		Flags:      unix.BPF_F_INNER_MAP,
 	}
-
-	m := ebpf.NewMap(spec)
-	if err := m.OpenOrCreate(); err != nil {
-		return nil, nil, err
-	}
-
-	return &maglevInnerMap{
-		Map:       m,
-		tableSize: tableSize,
-	}, spec, nil
 }
 
 // MaglevInnerMapFromID returns a new object representing the maglev inner map

@christarazi
Copy link
Member

As mentioned offline, it seems that my code is working without the patch provided above for some reason. My best guess is that my local kernel must have gotten into some bad / weird state with regards to the inner map, as that's what I was developing on 🤷.

Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
@jibi jibi force-pushed the pr/jibi/switch-maglev-to-ebpf branch from 96f95f5 to 2a1fc5b Compare June 18, 2021 07:05
@jibi
Copy link
Member Author

jibi commented Jun 18, 2021

test-me-please

@jibi jibi requested a review from brb June 18, 2021 07:05
@jibi
Copy link
Member Author

jibi commented Jun 18, 2021

retest-netnext

@jibi
Copy link
Member Author

jibi commented Jun 21, 2021

Last week I saw K8sServicesTest Checks service across nodes Tests NodePort BPF Tests with vxlan Tests NodePort with Maglev Tests Maglev backend selection failing once (which might be related to the changes) but I haven't been able to reproduce it locally after quite a few test runs, so I think it's fine to merge the PR in the current state. I'll keep an eye on the CI in case the failure happens again

Copy link
Member

@brb brb left a comment

Choose a reason for hiding this comment

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

🚀

@jibi jibi added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Jun 21, 2021
@jibi jibi merged commit 879f9eb into master Jun 21, 2021
@jibi jibi deleted the pr/jibi/switch-maglev-to-ebpf branch June 21, 2021 11:52
1.10.0 automation moved this from In progress to Done Jun 21, 2021
christarazi added a commit to christarazi/ebpf that referenced this pull request Jun 21, 2021
Introduced in
torvalds/linux@4a8f87e.

In Cilium, following the merge of cilium/cilium#15546, we need to add
this feature test as Maglev mode uses inner maps (map-in-map).

Signed-off-by: Chris Tarazi <chris@isovalent.com>
christarazi added a commit to christarazi/ebpf that referenced this pull request Jun 22, 2021
Introduced in
torvalds/linux@4a8f87e.

In Cilium, following the merge of cilium/cilium#15546, we need to add
this feature test as Maglev mode uses inner maps (map-in-map).

Signed-off-by: Chris Tarazi <chris@isovalent.com>
lmb pushed a commit to cilium/ebpf that referenced this pull request Jun 23, 2021
Introduced in
torvalds/linux@4a8f87e.

In Cilium, following the merge of cilium/cilium#15546, we need to add
this feature test as Maglev mode uses inner maps (map-in-map).

Signed-off-by: Chris Tarazi <chris@isovalent.com>
psanford pushed a commit to psanford/btf that referenced this pull request Feb 21, 2022
Introduced in
torvalds/linux@4a8f87e.

In Cilium, following the merge of cilium/cilium#15546, we need to add
this feature test as Maglev mode uses inner maps (map-in-map).

Signed-off-by: Chris Tarazi <chris@isovalent.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/misc This PR makes changes that have no direct user impact. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages.
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

7 participants