Skip to content

Commit 2cd7c02

Browse files
committed
natstacklat: Initialize the TAI-offset from user space
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]>
1 parent cef1957 commit 2cd7c02

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

netstacklat/netstacklat.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

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

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

1616
/* Helpers in maps.bpf.h require any histogram key to be a struct with a bucket member */
1717
struct hist_key {

netstacklat/netstacklat.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ static const char *__doc__ =
1414
#include <sys/timerfd.h>
1515
#include <sys/epoll.h>
1616
#include <sys/socket.h>
17+
#include <sys/timex.h>
1718

1819
#include <bpf/bpf.h>
1920
#include <bpf/libbpf.h>
@@ -454,6 +455,14 @@ static int enable_sw_rx_tstamps(void)
454455
return err;
455456
}
456457

458+
static long get_tai_offset(void)
459+
{
460+
struct ntptimeval ntpt;
461+
462+
ntp_gettimex(&ntpt);
463+
return ntpt.tai;
464+
}
465+
457466
static int init_signalfd(void)
458467
{
459468
sigset_t mask;
@@ -639,14 +648,23 @@ int main(int argc, char *argv[])
639648
return err;
640649
}
641650

642-
obj = netstacklat_bpf__open_and_load();
651+
obj = netstacklat_bpf__open();
643652
if (!obj) {
644653
err = libbpf_get_error(obj);
645654
libbpf_strerror(err, errmsg, sizeof(errmsg));
646-
fprintf(stderr, "Failed loading eBPF programs: %s\n", errmsg);
655+
fprintf(stderr, "Failed opening eBPF object file: %s\n", errmsg);
647656
goto exit_sockfd;
648657
}
649658

659+
obj->rodata->TAI_OFFSET = (signed long long)get_tai_offset() * NS_PER_S;
660+
661+
err = netstacklat_bpf__load(obj);
662+
if (err) {
663+
libbpf_strerror(err, errmsg, sizeof(errmsg));
664+
fprintf(stderr, "Failed loading eBPF programs: %s\n", errmsg);
665+
goto exit_destroy_bpf;
666+
}
667+
650668
err = netstacklat_bpf__attach(obj);
651669
if (err) {
652670
libbpf_strerror(err, errmsg, sizeof(errmsg));

0 commit comments

Comments
 (0)