From: Niklas Söderlund niklas.soderlund@corigine.com
[ Upstream commit 8fa42d78f6354bb96ad3a079dcbef528ca9fa9e0 ]
When running xdpsock for a fix duration of time before terminating using --duration=<n>, there is a race condition that may cause xdpsock to terminate immediately.
When running for a fixed duration of time the check to determine when to terminate execution is in is_benchmark_done() and is being executed in the context of the poller thread,
if (opt_duration > 0) { unsigned long dt = (get_nsecs() - start_time);
if (dt >= opt_duration) benchmark_done = true; }
However start_time is only set after the poller thread have been created. This leaves a small window when the poller thread is starting and calls is_benchmark_done() for the first time that start_time is not yet set. In that case start_time have its initial value of 0 and the duration check fails as it do not correlate correctly for the applications start time and immediately sets benchmark_done which in turn terminates the xdpsock application.
Fix this by setting start_time before creating the poller thread.
Fixes: d3f11b018f6c ("samples/bpf: xdpsock: Add duration option to specify how long to run") Signed-off-by: Niklas Söderlund niklas.soderlund@corigine.com Signed-off-by: Simon Horman simon.horman@corigine.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220315102948.466436-1-niklas.soderlund@corigin... Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdpsock_user.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index 2e4508a6cb3a..cf5b0a895225 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -1520,14 +1520,15 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
+ prev_time = get_nsecs(); + start_time = prev_time; + if (!opt_quiet) { ret = pthread_create(&pt, NULL, poller, NULL); if (ret) exit_with_error(ret); }
- prev_time = get_nsecs(); - start_time = prev_time;
if (opt_bench == BENCH_RXDROP) rx_drop_all();