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

Make maps implementation be cross-platform #21

Closed
dthaler opened this issue Apr 16, 2021 · 14 comments
Closed

Make maps implementation be cross-platform #21

dthaler opened this issue Apr 16, 2021 · 14 comments
Labels
blocked Blocked on another issue that must be done first enhancement New feature or request help wanted Extra attention is needed triaged Discussed in a triage meeting
Milestone

Comments

@dthaler
Copy link
Collaborator

dthaler commented Apr 16, 2021

This is to track making the core maps implementation in src/ebpf/libs/maps/ebpf_maps.c not be Windows specific, so the same code can be used on Windows, Linux, etc. This might entail upstreaming it to the generic-ebpf project for example.

@dthaler dthaler added enhancement New feature or request help wanted Extra attention is needed labels Apr 16, 2021
@dthaler
Copy link
Collaborator Author

dthaler commented Apr 16, 2021

In PR #15, @Alan-Jowett states:

Long term goal would be to switch to using generic-ebpf library, but due to generic-ebpf dependency on concurrency kit (which only builds with GCC), we can't use generic-ebpf yet.

@Alan-Jowett
Copy link
Member

Goal of this project is to only support Windows. Any code that could be generic should be moved to a more generic project and pulled in via a sub-module.

@YutaroHayakawa
Copy link

Hi, here's the author of generic-ebpf. Let me left some comments based on my implementation experience. I’m appreciate if it can help you.

@YutaroHayakawa
Copy link

YutaroHayakawa commented May 12, 2021

Seems like current map implementation is using in-place spinlock to get map element.

https://github.com/microsoft/ebpf-for-windows/blame/2b2ea62deee534ecee1bcf2a72bdc6b5964f681f/libs/execution_context/ebpf_maps.c#L251-L255

Is there any plan to move this on to RCU or EBR/QSBR implementation? Otherwide I think it will cause the use-after-free with some scenario like this.

// In eBPF program
elem = bpf_map_lookup_elem(&k);  // hash map
// User space program or other eBPF program deletes the element in here
elem->counter++;  // use after free

Actually, I did exactly the same thing before. Linux eBPF program is basically assumed to be run inside the RCU critical section, so they can delay the reclamation of the memory to after all of the eBPF program finish using it. This is why the generic-ebpf kernel implementations depend on the Epoch or RCU.

@Alan-Jowett
Copy link
Member

We had planned on using generic-ebpf, but the issue is that concurrency kit depends on a lot of GCC specific compiler features that aren't present in the MSVC compiler. Porting concurrencykit seems too risky.

Our map implementation relies on our own version of epoch tracking:

retval = ebpf_hash_table_create(

Which then uses:

ebpf_epoch_free(void* memory)

Our epoch tracker works like this:

  1. Every thread and/or CPU captures the epoch it's executing in.
  2. On free, memory is tagged with the epoch it was freed in.
  3. Memory is released back to the system when there are no more threads or CPU's on that epoch.

@Alan-Jowett
Copy link
Member

Description of how the epoch tracker works is here:

// Brief summary of how epoch tracking works.

@YutaroHayakawa
Copy link

Ah, sorry I was missing that code. Thanks for your explanation!

@YutaroHayakawa
Copy link

Do you have any plan to implement per-cpu variants of the maps? If yes, I'm interested in how you guys trying to implement it in user space (I couldn't come up with the way to implement it in preemptable environment).

@Alan-Jowett
Copy link
Member

Yes, we are planning to add per-cpu variants. Our goal is to maintain parity with the libbpf API's, so we are planning to match the behavior of bpf_map_lookup_elem.

Do you happen to know what bpf_map_lookup_elem does for per-CPU maps?

@YutaroHayakawa
Copy link

YutaroHayakawa commented May 12, 2021

Yes, in Linux, from bpf(2), it fetches all elements for each CPUs at once.

What I was mentioning here is the case the eBPF program running on userspace calls the bpf_map_lookup_elem helper. Maybe it is out of the scope of this project?

@Alan-Jowett
Copy link
Member

I think the current plan would be to have our API return the value for each CPU as well then.

@Alan-Jowett
Copy link
Member

@YutaroHayakawa do you happen to have any contact with the ConcurrencyKit team? If we could get a port of CK to Windows/Visual Studio, then I think we can get closer to adopting generic-ebpf map implementation.

@YutaroHayakawa
Copy link

Unfortunately, I don't have...

@dthaler
Copy link
Collaborator Author

dthaler commented Jul 26, 2023

Closing for now due to no progress or immediate way to make progress on this.
Fine to reopen if/when a possible way forward is known.

@dthaler dthaler closed this as completed Jul 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked on another issue that must be done first enhancement New feature or request help wanted Extra attention is needed triaged Discussed in a triage meeting
Projects
None yet
Development

No branches or pull requests

3 participants