Skip to content

Commit

Permalink
natstacklat: Initialize the TAI-offset from user space
Browse files Browse the repository at this point in the history
Make the user space loader calculate the TAI-offset at startup and set
it as a constant for the eBPF programs. Split the open and loading
stages of the eBPF programs apart to enable setting constants in the
eBPF programs.

Note that on some systems (e.g. most debian systems by default), the
TAI offset may (incorrectly) be 0, so that CLOCK_TAI becomes identical
to CLOCK_REALTIME. While this is principly incorrect, it does not pose
an issue for netstacklat, as it only needs the TAI offset to translate
CLOCK_TAI to CLOCK_REALTIME (which skb->tstamp is assumed to use as
clock basis). Therefore, netstacklat will (from this commit) work
correctly even if the TAI offset is not correctly set on the system.

Limitation: The TAI offset is only set once the program is first
loaded, and is not dynamically updated in case the TAI offset
changes. So if the program is running while a leap second occurs, the
recorded latencies may be off with one second. Furthermore, as the TAI
offset is set from user space, it will not work when just using the
eBPF portion together with ebpf-exporter.

Signed-off-by: Simon Sundberg <[email protected]>
  • Loading branch information
simosund committed Jan 27, 2025
1 parent 7e178df commit 0e1087f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
2 changes: 1 addition & 1 deletion netstacklat/netstacklat.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

char LICENSE[] SEC("license") = "GPL";

static volatile const u64 TAI_OFFSET = (37UL * NS_PER_S);
volatile const signed long long TAI_OFFSET = (37LL * NS_PER_S);

/* Helpers in maps.bpf.h require any histogram key to be a struct with a bucket member */
struct hist_key {
Expand Down
22 changes: 20 additions & 2 deletions netstacklat/netstacklat.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static const char *__doc__ =
#include <sys/timerfd.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/timex.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>
Expand Down Expand Up @@ -445,6 +446,14 @@ static int enable_sw_rx_tstamps(void)
return err;
}

static long get_tai_offset(void)
{
struct ntptimeval ntpt;

ntp_gettimex(&ntpt);
return ntpt.tai;
}

static int init_signalfd(void)
{
sigset_t mask;
Expand Down Expand Up @@ -630,14 +639,23 @@ int main(int argc, char *argv[])
return err;
}

obj = netstacklat_bpf__open_and_load();
obj = netstacklat_bpf__open();
if (!obj) {
err = libbpf_get_error(obj);
libbpf_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Failed loading eBPF programs: %s\n", errmsg);
fprintf(stderr, "Failed opening eBPF object file: %s\n", errmsg);
goto exit_sockfd;
}

obj->rodata->TAI_OFFSET = (signed long long)get_tai_offset() * NS_PER_S;

err = netstacklat_bpf__load(obj);
if (err) {
libbpf_strerror(err, errmsg, sizeof(errmsg));
fprintf(stderr, "Failed loading eBPF programs: %s\n", errmsg);
goto exit_destroy_bpf;
}

err = netstacklat_bpf__attach(obj);
if (err) {
libbpf_strerror(err, errmsg, sizeof(errmsg));
Expand Down

0 comments on commit 0e1087f

Please sign in to comment.