mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
pping: Update README with info on concurrency issues
Also, remove comments about concurrency issues from code in pping_kern.c as it is now documented in README. Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
This commit is contained in:
@@ -265,36 +265,11 @@ int pping_egress(struct __sk_buff *skb)
|
||||
}
|
||||
|
||||
// Check if identfier is new
|
||||
/* The gap between checking and updating last_id may cause concurrency
|
||||
* issues where multiple packets may simultaneously think they are the
|
||||
* first with a new identifier. As long as all of the identifiers are
|
||||
* the same though, only one should be able to create a timestamp entry.
|
||||
|
||||
* A bigger issue is that older identifiers (for example due to
|
||||
* out-of-order packets) may pass this check and update the current
|
||||
* identifier to an old one. This means that both the packet with the
|
||||
* old identifier itself as well the next packet with the current
|
||||
* identifier may be considered packets with new identifiers (even if
|
||||
* both have been seen before). For TCP timestamps this could be
|
||||
* prevented by changing the check to '>=' instead, but it may not be
|
||||
* suitable for other protocols, such as QUIC and its spinbit.
|
||||
*
|
||||
* For now, just hope that the rate limit saves us from creating an
|
||||
* incorrect timestamp. That may however also fail, either due to the
|
||||
* to it happening in a time it's not limited by rate sampling, or
|
||||
* because of rate check failing due to concurrency issues.
|
||||
*/
|
||||
if (f_state->last_id == p_id.identifier)
|
||||
goto out;
|
||||
f_state->last_id = p_id.identifier;
|
||||
|
||||
// Check rate-limit
|
||||
/*
|
||||
* The window between checking and updating last_timestamp may cause
|
||||
* concurrency issues, where multiple packets simultaneously pass the
|
||||
* rate limit. However, as long as they have the same identifier, only
|
||||
* a single timestamp entry should successfully be created.
|
||||
*/
|
||||
p_ts = bpf_ktime_get_ns(); // or bpf_ktime_get_boot_ns
|
||||
if (p_ts < f_state->last_timestamp ||
|
||||
p_ts - f_state->last_timestamp < config.rate_limit)
|
||||
@@ -341,14 +316,11 @@ int pping_ingress(struct xdp_md *ctx)
|
||||
|
||||
event.rtt = now - *p_ts;
|
||||
event.timestamp = now;
|
||||
/*
|
||||
* Attempt to delete timestamp entry as soon as RTT is calculated.
|
||||
* But could have potential concurrency issue where multiple packets
|
||||
* manage to match against the identifier before it can be deleted.
|
||||
*/
|
||||
|
||||
// Delete timestamp entry as soon as RTT is calculated
|
||||
bpf_map_delete_elem(&packet_ts, &p_id);
|
||||
|
||||
// Update flow's min-RTT, may have concurrency issues
|
||||
// Update flow's min-RTT
|
||||
f_state = bpf_map_lookup_elem(&flow_state, &p_id.flow);
|
||||
if (!f_state)
|
||||
goto validflow_out;
|
||||
@@ -358,6 +330,7 @@ int pping_ingress(struct xdp_md *ctx)
|
||||
|
||||
event.min_rtt = f_state->min_rtt;
|
||||
|
||||
// Push event to perf-buffer
|
||||
__builtin_memcpy(&event.flow, &p_id.flow, sizeof(struct network_tuple));
|
||||
bpf_perf_event_output(ctx, &rtt_events, BPF_F_CURRENT_CPU, &event,
|
||||
sizeof(event));
|
||||
|
||||
Reference in New Issue
Block a user