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

Use bpf_ktime_get_boot_ns instead #211

Merged
merged 3 commits into from
Nov 7, 2024

Conversation

nicholasberlin
Copy link
Contributor

@nicholasberlin nicholasberlin commented Nov 5, 2024

bpf_ktime_get_ns does not include suspension time, but we would like hdr.ts to represent real world time. Switching the helper function achieves that. The helper was introduced in 5.8 which is earlier than our current support range, 5.10

Update:
Add a new member variable instead and leave hdr.ts alone.

bpf_ktime_get_ns does not include suspension time, but we would like
ts to represent real world time. Switching the helper function
achieves that. The helper was introduced in 5.8 which is earlier
than our current support range, 5.10
@nicholasberlin nicholasberlin requested a review from a team as a code owner November 5, 2024 19:26
@haesbaert
Copy link
Contributor

So does that mean we have to move all userland comparisons to use CLOCK_BOOTIME on clock_gettime(3)? I'm guessing yes.
I've tested on RHEL8 and it works (4.18).
I'd prefer if we could fallback to the old one and also tell userland which one is being used, I can do that in a later step though.

@nicholasberlin
Copy link
Contributor Author

I'd prefer if we could fallback to the old one and also tell userland which one is being used, I can do that in a later step though.

How would you feel about adding a new member to the header instead?

struct ebpf_event_header {
    uint64_t ts;
    uint64_t ts_boot;
    uint64_t type;
} __attribute__((packed));

@nicholasberlin
Copy link
Contributor Author

I spent a little time trying to figure out how to check at runtime for helper functions, but couldn't get there. Our current logic is around disabling probes based on features. Wasn't sure how to avoid loading ebpf code that called unsupported helper functions. Seems doable, but I gave up once I realized that the new helper function is within our support range, and has apparently been backported.

@haesbaert
Copy link
Contributor

I'd prefer if we could fallback to the old one and also tell userland which one is being used, I can do that in a later step though.

How would you feel about adding a new member to the header instead?

struct ebpf_event_header {
    uint64_t ts;
    uint64_t ts_boot;
    uint64_t type;
} __attribute__((packed));

I don't think it belongs there, since it's a one time thing, we could stash it under stats, and userland is responsible for querying it once.

@haesbaert
Copy link
Contributor

I spent a little time trying to figure out how to check at runtime for helper functions, but couldn't get there. Our current logic is around disabling probes based on features. Wasn't sure how to avoid loading ebpf code that called unsupported helper functions. Seems doable, but I gave up once I realized that the new helper function is within our support range, and has apparently been backported.

I think the way to do is to test for BPF_FUNC_KTIME_GET...., something like:

if (bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_ringbuf_reserve)) {
    /* use bpf_ringbuf_reserve() safely */
} else {
    /* fall back to using bpf_perf_event_output() */
}

from: https://nakryiko.com/posts/bpf-core-reference-guide/

I'm happy to work on this in the future

Add a new event header member, ts_boot, and conditionally
set it with bpf_ktime_get_boot_ns() based on the helper's existence
@nicholasberlin
Copy link
Contributor Author

After reading this:

It's worth reiterating that such code is correctly detected by BPF verifier as a dead code, and so is never validated. This means that such code can use kernel and BPF functionality (e.g., new BPF helpers) that do not exist on the host kernel without worrying about BPF verification failures. E.g., if the first branch above were to use bpf_get_attach_cookie() helper for the BPF cookie feature, the program would be validated properly on older kernels that don't yet have that helper.

this PR was changed to add a new member to the header file. This way users of ts will not have to adjust. And the new member, ts_boot is set conditionally based on the helper function's existence.

@haesbaert
Copy link
Contributor

me gusta!

@nicholasberlin nicholasberlin merged commit 923ba94 into main Nov 7, 2024
26 checks passed
@nicholasberlin nicholasberlin deleted the nberlin/use_bpf_ktime_get_boot_ns branch November 7, 2024 16:16
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.

3 participants