-
Notifications
You must be signed in to change notification settings - Fork 765
bpf: Enable per-CPU map support for BatchOps #229
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
Conversation
BatchOps have already been enabled for this library. However per-CPU map support was deffered for the purposes of having a distinct debate about what the interface for the per-CPU maps should look like. This commit adds support for per-CPU maps but does fundamentally very little to add the support, taking the libbpb approach of having the user of library add dittographic lists (in golang, slices) as the "values" argument of Lookup (in that case empty) or Update. Signed-off-by: Nate Sweet <[email protected]>
@lmb I am very hesitant about changing the interface for per-CPU maps. The only changes needed would be to the Lookup calls and/or to the Update call. I think we should stick to the libbpf approach and have the add long lists. That will provide the most amount of flexibility to the end-user. |
The current API to interact with per-CPU maps looks like this:
Lookup takes a pointer instead of just a plain slice because it means that the function can be used by code that is completely oblivious to the number of CPUs, like so:
As a consequence Point 1: I'd like to use this opportunity to allow Next, your proposed batch API looks like this:
The "natural" API would be
I think in this case libbpf doesn't really have any other option besides taking a long list (which needs additional magic like In the meantime, here is a snippet that shows the two hypothetical APIs:
nestedSlices is marginally nicer to use but also creates a bunch more allocations plus overhead for slice headers. unrolledSlice isn't that difficult either, brownie points for a lot less allocations. Is there some sugar that could make unrolledSlice nicer to use? Regardless of what API we end up on, do you mind adding an example that shows how to use BatchLookup with per CPU maps? And the documentation needs updating as well. |
@@ -646,7 +655,7 @@ func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, va | |||
return 0, err | |||
} | |||
} | |||
nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize)) | |||
nextPtr, nextBuf := makeBuffer(startKey, int(m.keySize)) |
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.
Is this on purpose?
@@ -174,7 +174,7 @@ func TestStats(t *testing.T) { | |||
|
|||
disableStats, err := EnableStats(uint32(unix.BPF_STATS_RUN_TIME)) | |||
if err != nil { | |||
t.Errorf("failed to enable stats: %v", err) | |||
t.Fatalf("failed to enable stats: %v", err) |
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.
Good catch, can you move this to a separate PR?
@@ -897,9 +925,9 @@ func (m *Map) unmarshalKey(data interface{}, buf []byte) error { | |||
return unmarshalBytes(data, buf) | |||
} | |||
|
|||
func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) { | |||
func (m *Map) marshalValue(data interface{}, batch bool) (internal.Pointer, error) { |
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 think it would be nicer if this took an int instead, which allows removing some duplication from lookup and update. Functions taking bool are also hard to read.
func marshalValues(data interface{}, n int) (...) {
if perCPU {
marshalPerCPU(data, valueSize, n)
}
if *Map && n != 1 {
return an error
}
...
return marshalPtr(data, n*int(m.valueSize))
}
The batch methods then call m.marshalValues(data, keysValue.Len())
and the count != n * possibleCPUs
check is done in marshalPerCPUValue.
@lorenz I'm going to close this PR. We don't need per-CPU maps yet. I do favor the rawest approach possible, but we can defer until someone else wants it. |
BatchOps have already been enabled for this library.
However, per-CPU map support was deferred for the purposes
of having a distinct debate about what the interface for
the per-CPU maps should look like.
This commit adds support for per-CPU maps but does
fundamentally very little to add the support, taking
the libbpf approach of having the user of the library
add dittographic lists (in golang, slices) as the
"values" argument of Lookup (in that case empty)
or Update.
This commit also make a small change to the stats
tests so that they don't panic the tests when they fail on
a local machine that doesn't support them, but rather
just fail.
Signed-off-by: Nate Sweet [email protected]