Sled-agent: detect switch backend (tofino, softnpu, et al) at runtime - #11237
Sled-agent: detect switch backend (tofino, softnpu, et al) at runtime#11237sion42x wants to merge 8 commits into
Conversation
Replace the switch-asic, switch-stub, and switch-softnpu cargo features with startup detection. The propolis SoftNPU backend is selected by a virtio 9p device answering 9P2000.P4; without one the existing Tofino path is used. Optional switch_backend config added for the stub and SoftNPU zone backends. pumpkind is gated on Oxide hardware.
issues deserve to be fatal.
|
Note for reviewers: I realized |
| devinfo: &mut DevInfo, | ||
| ) -> Result<Option<String>, SwitchDetectError> { | ||
| let mut walker = devinfo.walk_node(); | ||
| while let Some(node) = |
There was a problem hiding this comment.
This loop kinda-sorta feels like a hand-rolled version of Iterator::find:
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find
? NodeWalk implements Iterator, so it may be useful to pull the bulk of logic here out into a predicate function. Dunno.
There was a problem hiding this comment.
Hmm... I can pull out the per-node logic and into a probe_node predicate. The catch with find itself is that each step is fallible and needs ? to propagate. try_find would make a good fit but I believe it's not stable. So I could do something like:
devinfo
.walk_node()
.map(|node| probe_node(log, &node.map_err(SwitchDetectError::DevInfo)?))
.find_map(Result::transpose)
.transpose()
but that feels harder to read than a loop. Not to mention doing a double transpose just to make it work which feels icky. Let me know which you think is clearer.
There was a problem hiding this comment.
yeah, that's a lot uglier than a loop. It may still be worthwhile to extract the test into a dedicated function, but if you need fallibility during the search, then a loop is the way to go.
|
Tests post On voxel: Working as expected on all scrimlet/non-scrimlet + rack/voxel combinations. |
|
We chatted via DM a bunch, and I'm summarizing it here: I am 100% on board with removing the sled-agent compile time features, but there's a lot of duplication with SwitchBackend, SwitchHardware, SidecarRevision, DendriteAsic, and kinda even SledMode. I'm not 100% sure what the sled-agent config changes should look like, but was hoping we could find a shape that elides some of those. What about shaping the config around the deployment type? Something like:
I originally talked myself out of this shape of config because the production and voxel branches look very similar (THAT'S THE POINT haha), and this isn't the granular config that exists today, which would support any type of deployment. Maybe then to support that we add a deployment = custom, which requires explicitly setting both the sled mode and the switch hardware? But at a higher level, I don't like throwing away information if we can prevent it, and the intended deployment type is information that is thrown away when setting a bunch of very granular options. Said another way, there may be things we want to do only for production, and things we may want to do only when deployed for voxel / a4x2, etc. There may not be but shaping the config this way gives us the choice in the future. I'm also looking to upstream patches that get my Canada Region config to work, and putting that behind a different deployment type also makes sense. My only bike-shed-type comment would be to change |
|
Thanks James. I like the "don't throw away information" thing and agree with it (versus in our chat when I mentioned using mechanism as the key). I'm going to work on this as another PR on top of this one and will add you. Basically I'm thinking:
I'll work on the PR (and hope it passes CI since the buildomat scripts rely on some config settings). |
| // Detected hardware wins in the priority order of `SwitchHardware`. With none | ||
| // detected, `auto` leaves Tofino detection to the hardware monitor and | ||
| // `scrimlet` assumes a Tofino ASIC when a physical sidecar is configured. | ||
| // `detect` runs only when the config leaves the backend to detection; it is | ||
| // a parameter so the decision can be tested without hardware. |
There was a problem hiding this comment.
This comment is a bit hard to understand, IMO. Perhaps we can express the decision tree as more of an if-else chain?
There was a problem hiding this comment.
This comment will be unnecessary soon given the changes James proposed that I'm working on. Agreed, the whole shebang is a bit hard to understand compared to just... selecting what it is.
| #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)] | ||
| #[serde(rename_all = "snake_case")] | ||
| pub enum SwitchBackend { | ||
| /// Probe for switch hardware: a SoftNPU 9p device, else the Tofino ASIC |
There was a problem hiding this comment.
"else the Tofino ASIC" feels like a sentence fragment?
There was a problem hiding this comment.
I can see that. I'll fix it, this will likely go away anyways.
Uncle Bob thanks you. Co-authored-by: Eliza Weisman <eliza@elizas.website>
42546c3 to
2403142
Compare
Replace the
switch-asic,switch-stub, andswitch-softnpucargo features with startup detection. A Tofino node in the device tree selects the Tofino ASIC; otherwise a virtio 9p device answering9P2000.P4selects the propolis SoftNPU backend, and with neither the existing auto Tofino path is used. Optionalswitch_backendconfig added for the stub and SoftNPU zone backends.pumpkindis gated on Oxide hardware.This PR is a proposed solution to #11202 based on feedback from the control plane team. Prior proposed/attempted solutions:
sled-agentwith CI as a downloadable artifact: Publish the omicron-sled-agent package as a separate artifact for dev labs #11133 (half measure and doesn't solve the real issue)vio9pdevice based on a new subsystem ID (breaks driver loading due to illumos device binding andscadmhardcoding, likewiseMode::Modernrequires newer stlouis changes and would be the first modern-only device)Options 2-4 would have also required additional tooling in omicron to detect these things, making it a pretty sizeable cross-repo change. However, @rcgoodfellow proposed a detection method
scadmalready uses:p9fsdevices usingdevinfop9server if it is9P2000.P4So rather than changing propolis, this PR uses that method to detect softnpu devices. A test on a racklette vs on a voxel lab showed:
Lastly, follow ups:
sled_mode,sidecar_revision, andswitch_backendoverlap, and legal combinations are enforced by runtime checks. It would probably be good to get the latter two into oneswitchenum so illegal configs aren't representable.