Skip to content

bpf2c array map lookup optimization.#5127

Open
saxena-anurag wants to merge 20 commits intomicrosoft:mainfrom
saxena-anurag:user/anusa/bpf2c_direct_map_lookup_array_map
Open

bpf2c array map lookup optimization.#5127
saxena-anurag wants to merge 20 commits intomicrosoft:mainfrom
saxena-anurag:user/anusa/bpf2c_direct_map_lookup_array_map

Conversation

@saxena-anurag
Copy link
Copy Markdown
Contributor

@saxena-anurag saxena-anurag commented Mar 20, 2026

Fixes #5177

Description

This pull request introduces a verifier-assisted optimization to enable bpf2c to inline array map lookups for BPF_MAP_TYPE_ARRAY maps, eliminating unnecessary indirect helper calls when the verifier can prove which map is being accessed. It achieves this by extracting precise per-instruction map annotations from the PREVAIL verifier and extending runtime support for direct array data access. The changes include new APIs, data structure extensions, runtime loader logic, and documentation.

Verifier and API Enhancements:

  • Added a new API function ebpf_get_map_annotations_from_verifier and its export, which provides per-instruction map annotations (map identity, type, name, etc.) from the verifier for use by bpf2c and other consumers. (include/ebpf_api.h, ebpfapi/Source.def, libs/api_common/api_common.cpp) [1] [2] [3] [4] [5] [6]

bpf2c and Loader Runtime Support:

  • Extended the map_data_t structure to include a direct pointer to array map data (array_data) and bumped the version for compatibility; updated size/version tables accordingly. (include/bpf2c.h, libs/shared/shared_common.c) [1] [2] [3]
  • Modified the native loader to populate the new array_data field for array maps using ebpf_map_get_value_address, enabling inlined lookups at runtime. (libs/execution_context/ebpf_native.c) [1] [2]

Verifier-Assisted Optimization Logic:

  • Implemented extraction and storage of per-instruction map annotations after verification, using the PREVAIL verifier's abstract domain to prove map identity and type; annotations are stored in thread-local storage for later use by bpf2c. (libs/api_common/api_common.cpp)

Documentation:

  • Added a comprehensive design document (docs/VerifierAssistedMapOptimization.md) detailing the problem, approach, architecture, runtime support, and correctness guarantees for this optimization.

These changes together enable safer and more efficient code generation for array map lookups, with clear fallback to standard helper calls when the verifier cannot prove map identity.

Testing

Existing CICD tests.

Perf numbers:
There is ~40% improvement in array map read numbers.

Before

2026-04-16T17:52:36-0800,BPF_MAP_TYPE_ARRAY read,51,48,51,55,55,53,52,47,51

After

2026-04-16T17:52:46-0800,BPF_MAP_TYPE_ARRAY read,30,28,32,29,31,31,30,30,30

Do any existing tests cover this change? Are new tests needed?

If new tests were added:

  • Unit tests are added.
  • Driver tests are added.

Documentation

Is there any documentation impact for this change?

Installation

Is there any installer impact for this change?

@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@saxena-anurag saxena-anurag force-pushed the user/anusa/bpf2c_direct_map_lookup_array_map branch from 1703f65 to fcc6d15 Compare March 20, 2026 19:09
@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

2 similar comments
@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request isn't linked to any GitHub issue. Please reference an issue with a keyword such as Fixes #123, Closes #456, etc., so the work can be tracked.

Copy link
Copy Markdown
Member

@Alan-Jowett Alan-Jowett left a comment

Choose a reason for hiding this comment

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

Thanks for the detailed design doc and implementation! I have a few concerns — one blocker and two correctness issues.

Comment thread .gitmodules Outdated
[submodule "external/ebpf-verifier"]
path = external/ebpf-verifier
url = https://github.com/vbpf/ebpf-verifier.git
url = https://github.com/saxena-anurag/ebpf-verifier.git
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Blocker: This changes the ebpf-verifier submodule URL from the upstream vbpf/ebpf-verifier.git to a personal fork (saxena-anurag/ebpf-verifier.git). This PR cannot merge with this change — it would make the entire repo depend on a personal fork.

The new verifier APIs (get_map_fd_range, get_map_type, Call::is_map_lookup) need to be upstreamed to vbpf/ebpf-verifier first, and this submodule should continue pointing to the upstream repo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. Was waiting for prevails PRs to be merged.

if (annotations != nullptr) {
for (size_t i = 0; i < count; i++) {
_map_annotations[annotations[i].instruction_offset] = annotations[i];
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Correctness concern — annotation offset collision with BPF-to-BPF subprograms

_map_annotations is keyed solely by instruction_offset and is shared across all programs in the generator. In extract_program(), subprograms are recursively extracted and each calls generate() — all sharing the same _map_annotations map.

Subprogram instruction offsets restart at 0 (see extract_program line 398: uint32_t offset = 0), while the annotations contain main program offsets (also starting at 0). If a subprogram has a bpf_map_lookup_elem call at the same local offset as an annotated call in the main program, it would incorrectly match the main program's annotation and inline the wrong map.

Suggested fix: key annotations by (program_name, instruction_offset) pair, or scope the annotation map per-program rather than sharing it globally.

@@ -0,0 +1,49 @@
// Copyright (c) eBPF for Windows contributors
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Missing test coverage for the optimized (inline) path

This test validates the fallback (ambiguous map → no inline), which is great. But I don't see a targeted runtime test that validates the optimized inline path end-to-end:

  1. Create an array map and write a known value
  2. Load a native program that uses the inline array_data lookup path
  3. Verify the correct value is returned

The existing map tests provide some indirect coverage, but a test that specifically exercises the map_data[idx].array_data + key * value_size code path would catch regressions in the array_data pointer population (e.g., if ebpf_map_get_value_address returns a wrong pointer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize array map lookup for native modules

2 participants