-
Notifications
You must be signed in to change notification settings - Fork 42
[multicast] viona CTRL_RX/CTRL_MAC receive filtering + softnpu egress lock scoping + dep updates #1093
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
base: master
Are you sure you want to change the base?
[multicast] viona CTRL_RX/CTRL_MAC receive filtering + softnpu egress lock scoping + dep updates #1093
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -227,6 +227,16 @@ pub trait VirtioDevice: Send + Sync + 'static + Lifecycle { | |
| ) -> Result<(), ()> { | ||
| Ok(()) | ||
| } | ||
|
|
||
| /// Notification that the virtio portion of the device has been reset. | ||
| /// | ||
| /// This fires for guest-initiated status resets as well as full device | ||
| /// resets, after the generic virtio state and virtqueues have been reset. | ||
| /// | ||
| /// Devices should use this to restore any state tied to feature | ||
| /// negotiation, since the next driver may negotiate a different feature | ||
| /// set. | ||
| fn device_reset(&self) {} | ||
|
Comment on lines
+230
to
+239
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is already covered by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not quite as The existing notification is only |
||
| } | ||
|
|
||
| pub trait VirtioIntr: Send + 'static { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -348,27 +348,14 @@ impl PciVirtioSoftNpuPort { | |
|
|
||
| let pkt = packet_in::new(&frame[..n]); | ||
|
|
||
| let mut pipeline = match self.pipeline.lock() { | ||
| Ok(pipe) => pipe, | ||
| Err(e) => { | ||
| error!(self.log, "failed to lock pipeline: {}", e); | ||
| break; | ||
| } | ||
| }; | ||
| let pl: &mut Box<dyn Pipeline> = match &mut *pipeline { | ||
| Some(ref mut x) => &mut x.1, | ||
| None => { | ||
| // This just means no P4 program has been set by the guest. | ||
| break; | ||
| } | ||
| }; | ||
|
|
||
| PacketHandler::process_guest_packet( | ||
| if !PacketHandler::process_guest_packet( | ||
| pkt, | ||
| &self.data_handles, | ||
| pl, | ||
| &self.pipeline, | ||
| &self.log, | ||
| ); | ||
| ) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if push_used { | ||
|
|
@@ -504,21 +491,13 @@ impl PacketHandler { | |
| // | ||
| // process packet with loaded P4 program | ||
| // | ||
|
|
||
| // TODO pipeline should not need to be mutable for packet handling? | ||
| let pkt = packet_in::new(&msg[..n]); | ||
| let mut p = pipeline.lock().unwrap(); | ||
| let pl = match &mut *p { | ||
| Some(ref mut pl) => &mut pl.1, | ||
| None => continue, // no program is loaded | ||
| }; | ||
|
|
||
| Self::process_external_packet( | ||
| index + 1, | ||
| pkt, | ||
| &data_handles, | ||
| &virtio, | ||
| pl, | ||
| &pipeline, | ||
| &log, | ||
| ) | ||
| } | ||
|
|
@@ -531,12 +510,26 @@ impl PacketHandler { | |
| mut pkt: packet_in<'_>, | ||
| data_handles: &Vec<dlpi::DlpiHandle>, | ||
| virtio: &Arc<PortVirtioState>, | ||
| pipeline: &mut Box<dyn Pipeline>, | ||
| pipeline: &Mutex<Option<LoadedP4Program>>, | ||
| log: &Logger, | ||
| ) { | ||
| for (mut out_pkt, port) in | ||
| // We hold the pipeline lock only while the pipeline computes the | ||
| // egress set. Every port worker serializes on this lock, and the | ||
| // dlpi and virtio egress I/O can block. Holding the lock across | ||
| // that I/O stalls the other workers, which is especially costly | ||
| // for multicast where one input frame fans out to several ports. | ||
| // The egress packets borrow from `pkt` rather than the pipeline, | ||
| // so they remain valid after the lock is released. | ||
| let outputs = { | ||
| let mut guard = pipeline.lock().unwrap(); | ||
| let pipeline = match &mut *guard { | ||
| Some(ref mut loaded) => &mut loaded.1, | ||
| None => return, // no program is loaded | ||
| }; | ||
| pipeline.process_packet(index as u16, &mut pkt) | ||
| { | ||
| }; | ||
|
|
||
| for (mut out_pkt, port) in outputs { | ||
| // packet is going to CPU port | ||
| if port == 0 { | ||
| Self::send_packet_to_cpu_port(&mut out_pkt, virtio, &log); | ||
|
|
@@ -555,20 +548,44 @@ impl PacketHandler { | |
|
|
||
| /// Run a packet coming into the ASIC from the guest pci port through the | ||
| /// loaded pipeline and forward it on to its destination. | ||
| /// | ||
| /// Returns false if no P4 program is loaded or the pipeline lock is | ||
| /// poisoned, in which case the caller should stop reading frames. | ||
| fn process_guest_packet( | ||
| mut pkt: packet_in<'_>, | ||
| data_handles: &Vec<dlpi::DlpiHandle>, | ||
| pipeline: &mut Box<dyn Pipeline>, | ||
| pipeline: &Mutex<Option<LoadedP4Program>>, | ||
| log: &Logger, | ||
| ) { | ||
| for (mut out_pkt, port) in pipeline.process_packet(0, &mut pkt) { | ||
| ) -> bool { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I'd rather this return a |
||
| // We hold the pipeline lock only for pipeline processing, not the | ||
| // egress I/O (see `process_external_packet` for rationale). | ||
| let outputs = { | ||
| let mut guard = match pipeline.lock() { | ||
| Ok(guard) => guard, | ||
| Err(e) => { | ||
| error!(log, "failed to lock pipeline: {e}"); | ||
| return false; | ||
| } | ||
| }; | ||
| let pipeline = match &mut *guard { | ||
| Some(ref mut loaded) => &mut loaded.1, | ||
| None => { | ||
| // This just means no P4 program has been set by the | ||
| // guest. | ||
| return false; | ||
| } | ||
| }; | ||
| pipeline.process_packet(0, &mut pkt) | ||
| }; | ||
|
|
||
| for (mut out_pkt, port) in outputs { | ||
| if port == 0 { | ||
| // no looping packets back to the guest | ||
| return; | ||
| return true; | ||
| } | ||
| if port == SOFTNPU_CPU_AUX_PORT { | ||
| // we are not currently emulating this port type | ||
| return; | ||
| return true; | ||
| } | ||
| Self::send_packet_to_ext_port( | ||
| &mut out_pkt, | ||
|
|
@@ -577,6 +594,7 @@ impl PacketHandler { | |
| &log, | ||
| ); | ||
| } | ||
| true | ||
| } | ||
|
|
||
| /// Send a packet out an external port using dlpi. | ||
|
|
||
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.
Calling this out to reset to
mainbefore merge.