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

Add BatchLookup support for a pointer to a slice #1290

Open
brycekahle opened this issue Jan 2, 2024 · 8 comments
Open

Add BatchLookup support for a pointer to a slice #1290

brycekahle opened this issue Jan 2, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@brycekahle
Copy link
Contributor

brycekahle commented Jan 2, 2024

BatchLookup claims it doesn't support a pointer to a slice, but sysenc.SyscallOutput does support pointers to slices:

// We're dealing with a pointer to a slice. Dereference and
// handle it like a regular slice.
value = value.Elem()

Could batchCount and sliceLen be updated to support pointer to slices?

@kwakubiney
Copy link
Member

Could it be that it's the intended outcome? I read it as "keysOut" and "valuesOut" must be of type slice. A pointer to a slice or buffer will not work

@brycekahle
Copy link
Contributor Author

You are right, I misread the comment.

That being said, the later functions do work with a pointer to a slice:

// We're dealing with a pointer to a slice. Dereference and
// handle it like a regular slice.
value = value.Elem()

@brycekahle brycekahle added enhancement New feature or request and removed bug Something isn't working labels Jan 3, 2024
@brycekahle brycekahle changed the title BatchLookup returns error if given a pointer to a slice Add BatchLookup support for a pointer to a slice Jan 3, 2024
@brycekahle
Copy link
Contributor Author

Reworded to be a feature request

@brycekahle
Copy link
Contributor Author

brycekahle commented Jan 3, 2024

One of the motivations here is to avoid the 24 byte allocation necessary to pass the slice by value.

@lmb
Copy link
Collaborator

lmb commented Jan 4, 2024

Can you add an example? The idea with BatchLookup is to use PossibleCPU() to create an appropriately sized slice and then reuse that for calls to the method. See #1271 though.

@brycekahle
Copy link
Contributor Author

I think you are talking specifically about per-CPU, but my request applies even for normal maps.

@brycekahle
Copy link
Contributor Author

Example:

// m is *ebpf.Map
keys := make([]uint32, 10)
values := make([]uint32, 10)

// current usage: allocates 24 bytes x 2 for the slice headers, but no more because of sysenc.SyscallOutput and unsafeBackingMemory
m.BatchLookup(keys, values, nil)

// proposed usage with no allocations
m.BatchLookup(&keys, &values, nil)

@lmb
Copy link
Collaborator

lmb commented Jan 8, 2024

Okay, I guess that is because the slice headers need to go onto the heap since we turn them into any. Why are those allocations a problem for you? In my mind

ebpf/map_test.go

Lines 156 to 164 in 394be60

lookupKeys := make([]uint32, n)
lookupValues := make([]uint32, n*possibleCPU)
var cursor BatchCursor
var total int
for {
count, err = m.BatchLookup(&cursor, lookupKeys, lookupValues, nil)
total += count
if errors.Is(err, ErrKeyNotExist) {
will lead to two allocations per entire iteration of the map, which doesn't seem too bad to me. Maybe you can add an example?

The problem with pointer-to-slice for per-CPU maps is that they already have semantics for non-batch lookups. For legacy reasons they will cause the library to allocate the target slice. If we added pointer-to-slice for BatchLookup it would have to match those semantics so that we don't fully descend into madness (I already find it difficult to keep the rules straight). That in turn means it wouldn't be very useful for you due to additional allocations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants