Skip to content
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

stirling/bpf_tools/bcc_wrapper.h: Add wrapped BPF maps & arrays. #1623

Merged
merged 13 commits into from
Aug 4, 2023

Conversation

etep
Copy link

@etep etep commented Jul 14, 2023

Summary: We add wrappers for BPF maps and arrays to our BCC wrapper class. These wrappers anticipate our upcoming "record & replay" feature. In specific, they will be used to shim in recording logic and return replayed values, i.e. when either record or replay ("RR") is in use. When "RR" is not in use, they pass through to the underlying BPF map or array.

Relevant Issues: #1163

Type of change: /kind feature

Test Plan: Existing test coverage exercises all of these.

@etep etep marked this pull request as draft July 14, 2023 22:42
Comment on lines 542 to 410
absl::flat_hash_map<K, V> GetTableOffline(const bool clear_table = false) {
absl::flat_hash_map<K, V> r;

for (const auto& k : shadow_keys_) {
auto s = GetValue(k);
const auto v = s.ConsumeValueOrDie();
r[k] = v;
if (clear_table) {
PX_UNUSED(underlying_->remove_value(k));
}
}
if (clear_table) {
shadow_keys_.clear();
}
return r;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this needs to take on reimplementing a function available on the underlying_ instance? I think it would be best to always defer to the underlying BCC function rather than including BCC implementation details in this shim.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We updated the wrapped BCC map to use the shadow keys only if template parameter kUserSpaceManaged is set to true. It should be the case that iterating over the keys in user space is faster than through iterated syscalls.

@etep etep marked this pull request as ready for review July 17, 2023 23:02
Copy link
Member

@ddelnano ddelnano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. Added some questions and minor comments.

src/stirling/bpf_tools/bcc_wrapper.h Outdated Show resolved Hide resolved
Comment on lines +55 to +71

#ifdef __cplusplus
template <typename H>
friend H AbslHashValue(H h, const stack_trace_key_t& k) {
return H::combine(std::move(h), k.upid, k.user_stack_id, k.kernel_stack_id);
}

friend bool operator==(const stack_trace_key_t& lhs, const stack_trace_key_t& rhs) {
if (lhs.upid != rhs.upid) {
return false;
}
if (lhs.user_stack_id != rhs.user_stack_id) {
return false;
}
return lhs.kernel_stack_id == rhs.kernel_stack_id;
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this not needed before with the original map usage?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shadow keys in the wrapped bcc map force us to supply the hash impl.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying 👍. Just wanted to make sure I didn't miss something important since I wasn't able to make that connection on my first pass.

const uint32_t sample_count_idx = using_map_set_a ? kSampleCountAIdx : kSampleCountBIdx;

// Read out the perf buffer that contains the histogram for this iteration.
// TODO(jps): change PollPerfBuffer() to use std::chrono.
constexpr int kPollTimeoutMS = 0;
histo_perf_buf->poll(kPollTimeoutMS);
PollPerfBuffer(perfbuf_name, kPollTimeoutMS);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why you chose to rely on bpf_ here rather than creating a WrappedBCCPerfBuffer data type? It feels like an inconsistent interface compared to how it worked previously and it's not clear to me why the perf buffer case is different.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason we find it this way is legacy. I did not introduce a wrapped perf buffer simply to follow our current setup. Wrapped perf buffer has crossed my mind, and so has moving all the wrapped bcc maps & arrays into bcc wrapper. There are some degrees of freedom here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I'm fine with the current implementation, but I wanted to make sure I understood the rationale 👍

Comment on lines +551 to +410

// "r" our result.
std::vector<std::pair<K, V>> r;

// This is a user space managed map: we can iterate over the shadow keys.
for (const auto& k : shadow_keys_) {
auto s = GetValue(k);
const auto v = s.ConsumeValueOrDie();
r.push_back({k, v});
if (clear_table) {
PX_UNUSED(underlying_->remove_value(k));
}
}
if (clear_table) {
shadow_keys_.clear();
}
return r;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the previous user space map implementation even provide this implementation? It appears to me this is new API surface area and didn't exist before. Assuming that understanding is correct, my preference would be to only add what is used.

Copy link
Author

@etep etep Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to agree with the insight here, but it is tricky. For GetTableOffline (which is not used by any user space managed instantiation) I removed the new impl. and added static_assert(kUserSpaceManaged) before the pass through. However, this static assertion failed (and I'd like to disagree with the compiler insomuch as the offending instantiation was not user space managed, so perhaps it did not really need to compile this method). Here are some other options:

  1. Return a StatusOr from this method.
  2. ECHECK(false) for user space managed.
  3. More template magic to ensure that we don't compile this wrongly.
  4. Provide two wrapped maps: (1) the normal pass through wrapped map, and (2) The user space managed wrapped map.
  5. Leave "as is."

I will vote for (4) or (5) above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see. In that case 5 is good with me.

@etep etep requested a review from a team July 18, 2023 20:20
@etep etep requested a review from aimichelle August 2, 2023 19:13
Pete Stevenson added 12 commits August 4, 2023 15:44
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
Signed-off-by: Pete Stevenson <[email protected]>
@etep etep force-pushed the rra-wrapped-bpf-maps-and-arrays branch from aaabc51 to 5343bd9 Compare August 4, 2023 22:45
Signed-off-by: Pete Stevenson <[email protected]>
@aimichelle aimichelle merged commit 44a8338 into pixie-io:main Aug 4, 2023
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants