netvsp: vtl0 vf operations safe when vtl2 absent#3891
Conversation
There was a problem hiding this comment.
Pull request overview
This PR tightens the netvsp VF manager’s state transitions so that a VTL0 VF is not left offered to the guest when VTL2 MANA device reconfiguration fails, preserving invariants relied on by subsequent state transitions (e.g., Hidden / Missing).
Changes:
- Extend
hide_vtl0_vfto revoke the VTL0 VF if it is still offered, even when VTL2 isn’tPresent. - Refactor
update_vtl0_vfinto amatchand add explicit handling forVtl2DeviceState::Reconfiguringto revoke any still-offered VF. - Update
reconfigure_vf_restartto revoke any still-offered VTL0 VF before marking the VTL2 deviceMissingwhen retries are exhausted.
…nger asserts not offered
| if matches!(vtl2_device_state, Vtl2DeviceState::Present) { | ||
| let vtl0_vf_offered = self.guest_state.is_offered_to_guest().await; | ||
| if vtl0_vf_offered { | ||
| // Reconfigure may have left the VTL0 VF offered to the guest. |
There was a problem hiding this comment.
Lets remove this line from the comment Reconfigure may have left the VTL0 VF offered to the guest.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
openhcl/underhill_core/src/emuplat/netvsp.rs:823
update_vtl0_vfcurrently panics if it receives a redundant/duplicate update (e.g. Present→Present or NotPresent→NotPresent) due toassert!(is_present != bus_control.is_some()). This RPC is ultimately driven bymodify_network_settings/update_vtl0_instance_id, which can plausibly be invoked multiple times with the same subordinate instance id (orNone) and should be handled idempotently rather than crashing the worker.
let is_present = matches!(
self.vtl0_bus_control,
Vtl0Bus::Present(_) | Vtl0Bus::HiddenPresent(_)
);
assert!(is_present != bus_control.is_some());
let is_offered_to_guest = self.guest_state.is_offered_to_guest().await;
| // VTL0 VF revoke will no-op when VTL2 is absent. Once the VTL2 device | ||
| // returns `startup_vtl2_device` will notify the netvsp cooridnator of | ||
| // the arrival, which will send a fresh `RemoveVtl0VF`. | ||
| self.try_notify_guest_and_revoke_vtl0_vf(&Vtl0Bus::NotPresent, vtl2_device_state) |
There was a problem hiding this comment.
these functions do different things
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
openhcl/underhill_core/src/emuplat/netvsp.rs:897
- In
update_vtl0_vf, whenvtl2_device_stateis notPresentthe code updatesself.vtl0_bus_controlbut leavesguest_state.vtl0_vfiduntouched. That can leaveVirtualFunction::id()returning a stale VF id after a removal (or other bus transition) while VTL2 is missing/reconfiguring. If the intention is forguest_stateto remain a projection of the current bus visibility, it should be updated here too.
(
Vtl2DeviceState::Reconfiguring
| Vtl2DeviceState::Missing
| Vtl2DeviceState::DeviceEnumerated,
_,
) => {
self.vtl0_bus_control = bus_control
.map(Vtl0Bus::Present)
.unwrap_or(Vtl0Bus::NotPresent);
}
…evoke reguardless of Present.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
openhcl/underhill_core/src/emuplat/netvsp.rs:609
- On revoke failure,
vtl0_busis logged as the worker's currentself.vtl0_bus_control, but the revoke is issued againstvpci_bus_control(which may come from the caller-providedbus_control, e.g. during hide). Logging the actual revoke target avoids confusing traces.
tracing::error!(
vtl2_vfid,
vtl0_bus = %self.vtl0_bus_control,
revoke_vtl0_vfid = vfid_from_guid(&vpci_bus_control.instance_id()),
err = err.as_ref() as &dyn std::error::Error,
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
openhcl/underhill_core/src/emuplat/netvsp.rs:609
- The revoke failure log uses
vtl0_bus = %self.vtl0_bus_control, but the revoke may be issued against the caller-suppliedvpci_bus_control(e.g. afterself.vtl0_bus_controlhas been replaced during hide/reconfig flows). Logging the bus control actually being revoked (and optionally the worker’s current bus state) will make these errors much easier to diagnose.
tracing::error!(
vtl2_vfid,
vtl0_bus = %self.vtl0_bus_control,
revoke_vtl0_vfid = vfid_from_guid(&vpci_bus_control.instance_id()),
err = err.as_ref() as &dyn std::error::Error,
| Vtl0Bus::Present(_) | Vtl0Bus::HiddenPresent(_) | ||
| ); | ||
| assert!(is_present != bus_control.is_some()); |
When EQE 135 resets the VTL 2 VF and the NIC has set
revoke_vtl0_vftofalsethen the VTL0 VF will still be offered to the Guest. This causes problems in functions likeupdate_vtl0_vfandhide_vtl0_vfwhich have assumptions about the VTL2 device beingPresentwhen VTL0 VF is offered. But now it is valid for the VTL2 device to be inReconfiguringandMissing.try_notify_guest_and_revoke_vtl0_vf- can be called fromManaDeviceRemoved. Modified so that when VTL2 device is notPresentthe HWC call to change MAC filter to synthetic path is skipped. Also modified bus-selection to skip calling revoke_vtl0_vf when VTL0 bus no present, in response to ahide_vtl0_vf.update_vtl0_vf- Removed panicking asserts that VTL0 VF could not be offered to guest when VTL2 was notPresent. Nested match logic replaced with a match(vtl2_device_state, vtl0_bus_control).add_vtl0_vf- Early skip if VTL2 device is notPresent. When VTL2 device returns,starup_vtl2_devicewill re-announce the VF arrival to Guest.remove_vtl0_vf- Unchanged.hide_vtl0_vf- When hiding, callstry_notify_guest_and_revoke_vtl0_vfregardless of VTL2 state.