This improves sleeping precision and reduces the possibility of reporting incorrect statistics to the user. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> --- samples/bpf/xdp_redirect_cpu_user.c | 7 ++++++- samples/bpf/xdp_sample_user.c | 27 ++++++++++++++++++++++++++- samples/bpf/xdp_sample_user.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 4c9f32229508..103ac5c24163 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -214,6 +214,9 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, setlocale(LC_NUMERIC, "en_US"); for (;;) { + struct timespec ots, nts; + + clock_gettime(CLOCK_MONOTONIC, &ots); swap(&prev, &record); sample_stats_collect(mask, record); sample_stats_print(mask, record, prev, NULL, interval); @@ -224,7 +227,9 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, if (sample_log_level & LL_DEFAULT) printf("\n"); fflush(stdout); - sleep(interval); + clock_gettime(CLOCK_MONOTONIC, &nts); + sample_calc_timediff(&nts, &ots, interval); + nanosleep(&nts, NULL); if (stress_mode) stress_cpumap(value); sample_reset_mode(); diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 909257ffe54c..96d36c708ee3 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -923,6 +923,26 @@ void sample_stats_print(int mask, struct stats_record *cur, stats_print(prog_name, mask, cur, prev, &out); } +static void calc_timediff(struct timespec *cur, const struct timespec *prev) +{ + if (cur->tv_nsec - prev->tv_nsec < 0) { + cur->tv_sec = cur->tv_sec - prev->tv_sec - 1; + cur->tv_nsec = cur->tv_nsec - prev->tv_nsec + NANOSEC_PER_SEC; + } else { + cur->tv_sec -= prev->tv_sec; + cur->tv_nsec -= prev->tv_nsec; + } +} + +void sample_calc_timediff(struct timespec *cur, const struct timespec *prev, int interval) +{ + struct timespec ts = { .tv_sec = interval }; + + calc_timediff(cur, prev); + calc_timediff(&ts, cur); + *cur = ts; +} + void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators) { struct stats_record *record, *prev; @@ -936,11 +956,16 @@ void sample_stats_poll(int interval, int mask, char *prog_name, int use_separato setlocale(LC_NUMERIC, "en_US"); for (;;) { + struct timespec ots, nts; + + clock_gettime(CLOCK_MONOTONIC, &ots); swap(&prev, &record); sample_stats_collect(mask, record); sample_stats_print(mask, record, prev, prog_name, interval); fflush(stdout); - sleep(interval); + clock_gettime(CLOCK_MONOTONIC, &nts); + sample_calc_timediff(&nts, &ots, interval); + nanosleep(&nts, NULL); sample_reset_mode(); } diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index abe4ec25c310..588bd2f15352 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -161,6 +161,8 @@ void sample_stats_print(int mask, struct stats_record *cur, void sample_stats_collect(int mask, struct stats_record *rec); void sample_summary_update(struct sample_output *out, int interval); void sample_summary_print(void); +void sample_calc_timediff(struct timespec *cur, const struct timespec *prev, + int interval); void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators); void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, -- 2.31.1