-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NETOBSERV-1268: handle concurrency issues between kernel and userspace #172
NETOBSERV-1268: handle concurrency issues between kernel and userspace #172
Conversation
@msherif1234: This pull request references NETOBSERV-1268 which is a valid jira issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=f162e4b make set-agent-image |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #172 +/- ##
==========================================
+ Coverage 38.60% 39.24% +0.64%
==========================================
Files 31 31
Lines 2259 2301 +42
==========================================
+ Hits 872 903 +31
- Misses 1338 1346 +8
- Partials 49 52 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. 📢 Have feedback on the report? Share it here. |
@msherif1234 now that I see this concurrency issue, I am having serious doubts about having removed the perCpu maps. You assumed concurrency issues between kernel and userspace but is'nt it actually concurrency issues between the different cpu that could occur here? Especially as we know that the same 5-tuples / flow_id can be processed by several cpus. Isn't it something that the previous design, with per-cpu maps, was actually solving? (all maps being dedicated to a core, and the merge being done safely in the user space) |
To test:
You should see the flows similar to my screenshot above. |
335f76c
to
5733308
Compare
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=b32ef06 make set-agent-image |
5733308
to
5ab0fb5
Compare
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=8f969c1 make set-agent-image |
fyi I forgot to mention in my test steps above: |
5ab0fb5
to
2633601
Compare
@msherif1234: This pull request references NETOBSERV-1268 which is a valid jira issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
2633601
to
af8822f
Compare
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=79e1ce2 make set-agent-image |
cc'd @tohojo as discussed offline we have no way to ensure concurrency using global hmap now its shared with tracepoints hook so we have to fall back to use perCPU hmap |
af8822f
to
7ba7fe1
Compare
I'm also seeing issues on bytes count. Steps to reproduce:
Using this PR I get |
pkg/flow/tracer_map.go
Outdated
// eBPF hashmap values are not zeroed when the entry is removed. That causes that we | ||
// might receive entries from previous collect-eviction timeslots. | ||
// We need to check the flow time and discard old flows. | ||
if mt.StartMonoTimeTs <= m.lastEvictionNs || mt.EndMonoTimeTs <= m.lastEvictionNs { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if mt.StartMonoTimeTs <= m.lastEvictionNs || mt.EndMonoTimeTs <= m.lastEvictionNs { | |
if mt.EndMonoTimeTs <= m.lastEvictionNs { |
Can you please explain why we need to compare Start and End times here ?
It seems both curl on httpd page & ubuntu image download works fine when removing the compare on start 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please explain why we need to compare Start and End times here ?
It seems both curl on httpd page & ubuntu image download works fine when removing the compare on start 😸
that code was just a revert and that is what 1.3 has where u don't see the issue correct ? I would think comparing start > eviction time is sufficient, doing endTime is more of extra safety since we can have an old TS from prev collection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@msherif1234 could it be due to this code block being removed: (as said here #172 (comment) ) ?
// it might happen that start_mono_time hasn't been set due to
// the way percpu hashmap deal with concurrent map entries
if (aggregate_flow->start_mono_time_ts == 0) {
aggregate_flow->start_mono_time_ts = current_time;
}
It seems like sometimes start_mono_time_ts
is 0, which would indeed make the condition mt.StartMonoTimeTs <= m.lastEvictionNs
be true ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that is the proof that same flow won't always hit the same cpu core so we had to add this trick unfortuntely revert couldn't bring that code and I forget about it thanks for catching it now I tested both large and small curl and they are pretty accurate
5518398
to
62dd76f
Compare
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=8c253eb make set-agent-image |
@@ -253,12 +253,13 @@ static inline long pkt_drop_lookup_and_update_flow(struct sk_buff *skb, flow_id | |||
enum skb_drop_reason reason) { | |||
flow_metrics *aggregate_flow = bpf_map_lookup_elem(&aggregated_flows, id); | |||
if (aggregate_flow != NULL) { | |||
aggregate_flow->end_mono_time_ts = bpf_ktime_get_ns(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, there was some specific handling of empty start time here:
// it might happen that start_mono_time hasn't been set due to
// the way percpu hashmap deal with concurrent map entries
if (aggregate_flow->start_mono_time_ts == 0) {
aggregate_flow->start_mono_time_ts = current_time;
}
cf also c696bb0
But I admit I don't really understand this old patch... I don't see in which cases start_mono_time_ts
could not be set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joel this drop handling function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but u are right that part is missing in flows.c the revert didn't bring it back
pkg/agent/agent_test.go
Outdated
ebpfTracer.AppendLookupResults(map[ebpf.BpfFlowId]*ebpf.BpfFlowMetrics{ | ||
key1: &key1Metrics, | ||
ebpfTracer.AppendLookupResults(map[ebpf.BpfFlowId][]ebpf.BpfFlowMetrics{ | ||
key1: key1Metrics, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't testing the dedup, we should restore this test as it was previously:
key1Metrics := []ebpf.BpfFlowMetrics{
{Packets: 3, Bytes: 44, StartMonoTimeTs: now + 1000, EndMonoTimeTs: now + 1_000_000_000},
{Packets: 1, Bytes: 22, StartMonoTimeTs: now, EndMonoTimeTs: now + 3000},
}
key2Metrics := []ebpf.BpfFlowMetrics{
{Packets: 7, Bytes: 33, StartMonoTimeTs: now, EndMonoTimeTs: now + 2_000_000_000},
}
ebpfTracer.AppendLookupResults(map[ebpf.BpfFlowId][]ebpf.BpfFlowMetrics{
key1: key1Metrics,
key1Dupe: key1Metrics,
key2: key2Metrics,
})
.. and adapt the expectations in the related tests (dedup test expects 2 results, dedup-just-mark test expects 3 results with one flagged duplicate, no-dedup expects 3 results)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
…netobserv#118)" This reverts commit b6e2b87. fix Signed-off-by: msherif1234 <mmahmoud@redhat.com>
62dd76f
to
4b956f4
Compare
/ok-to-test |
New image: It will expire after two weeks. To deploy this build, run from the operator repo, assuming the operator is running: USER=netobserv VERSION=399209a make set-agent-image |
not tested - code-wise this looks good to me, now we must check if @jpinsonneau 's test is satisfied |
Yeah I confirm both small curl / 2GB download scenarios works fine 👍 |
/lgtm |
@memodi @Amoghrd can u pls sanity check this PR and make sure the new features still working @dushyantbehl can u pls check RTT functionality with this PR |
Sanity checked PacketDrop with this PR and everything looks good; works as expected! |
thanks @msherif1234 @Amoghrd @jpinsonneau ! |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jotak The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
with using global hmap we increased the window where both userspace and kernel can collide to we can't use
bpf_spin_lock()
because tracepoints doesn't allow it so we have to revert back to use perCPU map :(testing
Signed-off-by: msherif1234 mmahmoud@redhat.com