-
Notifications
You must be signed in to change notification settings - Fork 44
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
Add Support for TCX Programs #1222
Conversation
de1d0bf
to
1e5753d
Compare
81c8ff9
to
ef40d84
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1222 +/- ##
========================================
- Coverage 8.94% 8.57% -0.37%
========================================
Files 24 24
Lines 6027 6285 +258
========================================
Hits 539 539
- Misses 5488 5746 +258 ☔ View full report in Codecov by Sentry. |
ebc8772
to
f093d59
Compare
a058491
to
6d03cd7
Compare
e254539
to
247f0f3
Compare
@anfredette, this pull request is now in conflict and requires a rebase. |
247f0f3
to
b4f30a0
Compare
b4f30a0
to
e820a23
Compare
e7b6e8b
to
b4dc28b
Compare
This TCX pr is ready for review. |
Info::TcxAttachInfo(TcxAttachInfo { | ||
priority, | ||
iface, | ||
position: _, |
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 u drop position
if its not in use ?
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.
position
is set later when the program is attached.
#[prost(string, tag = "2")] | ||
pub iface: ::prost::alloc::string::String, | ||
#[prost(int32, tag = "3")] | ||
pub position: i32, |
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.
same here ?
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.
position
is set later when the program is attached.
links::FdLink, | ||
loaded_programs, | ||
tc::{SchedClassifierLink, SchedClassifierLinkId, TcAttachOptions}, | ||
trace_point::TracePointLink, |
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.
where is tcx
in this ?
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.
A tcx and tc programs are considered to be the same type by Aya and the kernel. It's the attach type that's different.
bpfman/src/lib.rs
Outdated
@@ -737,6 +762,105 @@ fn filter( | |||
}) | |||
} | |||
|
|||
fn get_txc_programs(root_db: &Db, if_index: u32, direction: Direction) -> Vec<TcxProgram> { |
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.
typo ? should be tcx
?
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.
bpfman/src/lib.rs
Outdated
let id = bytes_to_string(&p) | ||
.split('_') | ||
.last() | ||
.unwrap() |
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.
I would like to remove the unwrap()
calls. This pattern is in this file a few times. Move it to a separate function and re-code it without the unwrap()
calls.
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.
I added a helper function to get the id and fixed this one instance. However, it requires returning a Result
in this function and handling it several other places. If people are okay with the way I did it, then I can modify the existing code similarly.
bpfman/src/lib.rs
Outdated
if order.is_none() { | ||
np.set_current_position(tcx_programs.len())?; | ||
order = Some(AttachOrder::After( | ||
tcx_programs.last().unwrap().get_data().get_id()?, |
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 this unwrap()
fail? Would prefer not to have it if possible.
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.
Actually, this one cannot fail because I've already checked tcx_programs.is_empty()
at the top, and if it was it would have already returned. However, I plan to split this function into two separate functions to handle the cases with and without a new_program. I'd also like to see if I can make this whole function cleaner. I'll handle the unwrap()
when I do that.
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.
I re-worked this function and updated the last commit.
bpfman/src/lib.rs
Outdated
let owned_link: SchedClassifierLink = tcx.take_link(link_id)?; | ||
let fd_link: FdLink = owned_link | ||
.try_into() | ||
.expect("unable to get owned tcx attach link"); |
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.
.expect()
calls are scattered throughout the code, but if they are hit, they are a panic. I would like to avoid adding any new ones and slowly remove all the existing ones in the code.
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.
bpfman/src/types.rs
Outdated
|
||
pub fn get_direction(&self) -> Result<Direction, BpfmanError> { | ||
sled_get(&self.data.db_tree, TCX_DIRECTION) | ||
.map(|v| bytes_to_string(&v).to_string().try_into().unwrap()) |
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.
Avoid the unwrap()
.
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.
bpfman/src/types.rs
Outdated
// result, we use the following hack to figure out which one it | ||
// really is. | ||
ProgramType::Tc => { | ||
if data.db_tree.get(TCX_IFACE).unwrap().is_some() { |
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.
Avoid the unwrap()
.
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.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build | ||
|
||
|
||
FROM --platform=$TARGETPLATFORM registry.fedoraproject.org/fedora-minimal:latest |
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.
FROM --platform=$TARGETPLATFORM registry.fedoraproject.org/fedora-minimal:latest | |
FROM registry.fedoraproject.org/fedora-minimal:latest |
Removed in all the files in the multi-arch PR.
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.
ARG BUILDPLATFORM | ||
|
||
# The following ARGs are set internally by docker or podman on multiarch builds | ||
ARG TARGETPLATFORM=linux/amd64 |
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.
ARG TARGETPLATFORM=linux/amd64 | |
ARG TARGETARCH | |
ARG TARGETOS | |
ARG TARGETPLATFORM | |
RUN echo "TARGETOS=${TARGETOS} TARGETARCH=${TARGETARCH} BUILDPLATFORM=${BUILDPLATFORM} TARGETPLATFORM=${TARGETPLATFORM}" |
Similar change made in all the files in the multi-arch PR.
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.
|
||
FROM --platform=$TARGETPLATFORM registry.fedoraproject.org/fedora-minimal:latest | ||
|
||
ARG TARGETPLATFORM |
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.
ARG TARGETPLATFORM |
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.
bpfman/src/lib.rs
Outdated
.unwrap() | ||
.parse::<u32>() | ||
.unwrap(); | ||
let tree = root_db.open_tree(p).expect("unable to open database tree"); |
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.
.expect()
calls are scattered throughout the code, but if they are hit, they are a panic. I would like to avoid adding any new ones and slowly remove all the existing ones in the code.
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.
bpfman/src/lib.rs
Outdated
@@ -215,6 +224,10 @@ pub async fn add_program(mut program: Program) -> Result<Program, BpfmanError> { | |||
|
|||
add_multi_attach_program(root_db, &mut program, &mut image_manager, config).await | |||
} | |||
Program::Tcx(_) => { | |||
program.set_if_index(get_ifindex(&program.if_name().unwrap())?)?; |
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 this unwrap()
fail? Would prefer not to have it if possible.
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.
@anfredette, this pull request is now in conflict and requires a rebase. |
b4dc28b
to
e1fba01
Compare
e1fba01
to
4719179
Compare
83c36cb
to
bfa64cf
Compare
@anfredette, this pull request is now in conflict and requires a rebase. |
This PR adds support for TCX programs using priority-based API for TCX modeled after the existing TC API. Both the Linux kernel and Aya use a relative positioning approach for ordering TCX programs that requires new TCX programs to be positioned relative to an existing TCX program. To improve the user experience across multiple independent applications, we’ve retained a TC-like priority API in bpfman, which internally maps to Aya’s relative ordering API. Additional Changes: - A TCX integration test is included. - A go-tcx-counter example was added, and the go-app-counter example has been updated to include a TCX program. - GitHub Actions are now configured to use ubuntu-24.04 to meet the kernel version requirement (6.6 or higher) for TCX. Signed-off-by: Andre Fredette <[email protected]>
Also split up and reworked the update_tcx_program_positions() function. Signed-off-by: Andre Fredette <[email protected]>
bfa64cf
to
82a6937
Compare
/LGTM |
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.
/lgtm
Before I approve, quick question. How does bpfman handle it if TCX programs are already installed on the system outside of bpfman? For TC and XDP, it doesn't, but since the multi-prog is handled by the kernel, what is the expect behavior?
Both bpfman and other applications can install tcx programs. We don't currently pay attention to TCX programs installed by other means. The first bpfman TCX program on a given attach point is placed in first position regardless of whether there are already other programs attached. Subsequent bpfman TCX programs on the same attach point are positioned relative to existing bpfman programs based on priority without regard to any other TCX programs that may have been attached by other means. We've talked about some options for cooperating better with non-bpfman loaders, but this is the first step. |
This PR adds support for TCX programs using priority-based API for
TCX modeled after the existing TC API.
Both the Linux kernel and Aya use a relative positioning approach for
ordering TCX programs that requires new TCX programs to be positioned
relative to an existing TCX program. To improve the user experience
across multiple independent applications, we’ve retained a TC-like
priority API in bpfman, which internally maps to Aya’s relative
ordering API.
Additional Changes:
updated to include a TCX program.
version requirement (6.6 or higher) for TCX.
Fixes: #1215