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:
Simon Sundberg
2021-05-06 17:54:31 +02:00
parent d92109b3c8
commit fb454cd716
2 changed files with 100 additions and 35 deletions

View File

@@ -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));