Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/admin-cli/src/site_explorer/mlx_devices/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ List Mellanox/BlueField devices across all explored hosts:
List the devices found under one host BMC:
$ nico-admin-cli site-explorer mlx-devices --host 192.0.2.20

Find DPUs in NIC mode whose NIC firmware is below the desired version:
Find devices operating as NICs whose firmware is below the desired version:
$ nico-admin-cli site-explorer mlx-devices --nic-mode-only --expected-version 32.42.1000

")]
Expand All @@ -36,7 +36,7 @@ pub struct Args {
pub host: Option<String>,
#[clap(
long,
help = "Only BlueField-3 devices operating in NIC mode (part number 900-9D3B4)"
help = "Only devices operating as NICs: their DPU BMC reports NIC mode, or they have a SuperNIC SKU and the mode is unknown"
)]
pub nic_mode_only: bool,
#[clap(
Expand Down
92 changes: 87 additions & 5 deletions crates/admin-cli/src/site_explorer/mlx_devices/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ pub async fn mlx_devices(
.get_all_explored_mlx_devices(page_size, opts.host)
.await?
.into_iter()
// Only NIC-mode DPUs, when asked.
.filter(|d| !nic_mode_only || d.device_kind == MlxDeviceKind::Bf3NicMode as i32)
// Only devices operating as NICs, when asked.
.filter(|d| !nic_mode_only || operating_as_nic(d))
// Only devices whose NIC firmware is below the desired version, when given
// one. A device with no firmware, or a version we can't parse, is surfaced
// rather than hidden.
Expand Down Expand Up @@ -100,11 +100,31 @@ impl From<ExploredMlxDevice> for MlxDeviceRow {
}
}

/// Whether a device is operating as a plain NIC -- its Arm OS is down, so scout
/// can't report its firmware and this inventory is the only one that sees it.
///
/// The authoritative signal is `nic_mode`, the mode the DPU's own BMC reports;
/// a `900-9D3B6` DPU flipped into NIC mode passes on that signal even though
/// its SKU says DPU. When the mode is unknown (`nic_mode` unset -- no DPU BMC
/// matched, or its firmware predates mode reporting), fall back to the SKU:
/// the SuperNIC families ship running as NICs, and like the firmware filter
/// below we err toward surfacing a device rather than hiding it.
fn operating_as_nic(device: &ExploredMlxDevice) -> bool {
match device.nic_mode {
Some(mode) => mode == NicMode::Nic as i32,
None => {
device.device_kind == MlxDeviceKind::Bf3NicMode as i32
|| device.device_kind == MlxDeviceKind::Bf3SuperNic as i32
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

fn kind_label(device_kind: i32) -> String {
match MlxDeviceKind::try_from(device_kind) {
Ok(MlxDeviceKind::Bf3NicMode) => "BlueField-3 (NIC mode)",
Ok(MlxDeviceKind::Bf3DpuMode) => "BlueField-3 (DPU mode)",
Ok(MlxDeviceKind::Bf3SuperNic) => "BlueField-3 SuperNIC",
// Both SuperNIC SKU families render under NVIDIA's product name; the
// part-number column alongside is the discriminator.
Ok(MlxDeviceKind::Bf3NicMode) | Ok(MlxDeviceKind::Bf3SuperNic) => "BlueField-3 SuperNIC",
Ok(MlxDeviceKind::Bf3DpuMode) => "BlueField-3 DPU",
Ok(MlxDeviceKind::Bf2Dpu) => "BlueField-2 DPU",
Ok(MlxDeviceKind::Unknown) | Err(_) => "Unknown",
}
Expand Down Expand Up @@ -172,6 +192,68 @@ fn parse_version(version: &str) -> Option<Vec<u64>> {
mod tests {
use super::*;

#[test]
fn operating_as_nic_prefers_reported_mode_over_sku() {
struct Case {
name: &'static str,
device_kind: MlxDeviceKind,
nic_mode: Option<NicMode>,
expect: bool,
}
let cases = [
Case {
name: "dpu sku flipped into nic mode",
device_kind: MlxDeviceKind::Bf3DpuMode,
nic_mode: Some(NicMode::Nic),
expect: true,
},
Case {
name: "dpu sku running as a dpu",
device_kind: MlxDeviceKind::Bf3DpuMode,
nic_mode: Some(NicMode::Dpu),
expect: false,
},
Case {
name: "supernic sku flipped into dpu mode",
device_kind: MlxDeviceKind::Bf3NicMode,
nic_mode: Some(NicMode::Dpu),
expect: false,
},
Case {
name: "unmatched 9d3b4 supernic falls back to sku",
device_kind: MlxDeviceKind::Bf3NicMode,
nic_mode: None,
expect: true,
},
Case {
name: "unmatched 9d3d4 supernic falls back to sku",
device_kind: MlxDeviceKind::Bf3SuperNic,
nic_mode: None,
expect: true,
},
Case {
name: "unmatched dpu sku stays a dpu",
device_kind: MlxDeviceKind::Bf3DpuMode,
nic_mode: None,
expect: false,
},
Case {
name: "unmatched bf2 stays a dpu",
device_kind: MlxDeviceKind::Bf2Dpu,
nic_mode: None,
expect: false,
},
];
for case in cases {
let device = ExploredMlxDevice {
device_kind: case.device_kind as i32,
nic_mode: case.nic_mode.map(|mode| mode as i32),
..Default::default()
};
assert_eq!(operating_as_nic(&device), case.expect, "{}", case.name);
}
}

#[test]
fn firmware_below_compares_dotted_versions() {
// Outdated -> below the target.
Expand Down
43 changes: 23 additions & 20 deletions crates/api-model/src/site_explorer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1815,16 +1815,22 @@ pub fn is_bluefield_part_number(part_number: &str) -> bool {

/// The kind of BlueField/Mellanox device, classified from its Redfish part number.
///
/// A BlueField-3's part number records the mode it is currently operating in:
/// `900-9D3B4` is a card running as a NIC, `900-9D3B6` is the same generation
/// running as a DPU, and `900-9D3D4` is a dedicated SuperNIC. That split is what
/// lets us pick out a DPU operating in NIC mode -- whose NIC firmware is
/// otherwise invisible while its Arm OS is down -- apart from a native SuperNIC.
/// The part number identifies the card's factory SKU, not the mode it is
/// operating in: `900-9D3B6` is a BlueField-3 DPU product, while `900-9D3B4`
/// and `900-9D3D4` are BlueField-3 SuperNIC products that ship running as
/// NICs. Reconfiguring a card between DPU and NIC mode (the DPU BMC's
/// `Mode.Set` action) does not change its part number -- a flipped `900-9D3B6`
/// still classifies as [`MlxDeviceKind::Bf3DpuMode`] here. For the mode a
/// device is actually operating in, read [`ExploredMlxDevice::nic_mode`],
/// which comes from the DPU's own BMC.
///
/// The `*Mode` variant names are frozen: they mirror the wire enum from when
/// this classification was believed to track the operating mode.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum MlxDeviceKind {
/// BlueField-3 operating as a NIC (part number `900-9D3B4...`).
/// BlueField-3 SuperNIC (part number `900-9D3B4...`).
Bf3NicMode,
/// BlueField-3 operating as a DPU (part number `900-9D3B6...`).
/// BlueField-3 DPU (part number `900-9D3B6...`).
Bf3DpuMode,
/// BlueField-3 SuperNIC (part number `900-9D3D4...`).
Bf3SuperNic,
Expand All @@ -1843,9 +1849,9 @@ impl MlxDeviceKind {
return Self::Unknown;
};
let part_number = part_number.trim().to_lowercase();
// `is_bf3_supernic_part_number` deliberately groups `900-9d3b4` and `900-9d3d4`; here
// we split them, because a NIC-mode DPU (`b4`) and a native SuperNIC
// (`d4`) are exactly what an operator needs told apart.
// `is_bf3_supernic_part_number` deliberately groups `900-9d3b4` and
// `900-9d3d4`; here we keep them apart because the wire enum
// distinguishes the two SuperNIC SKU families.
if part_number.starts_with("900-9d3b6") || part_number == "sn37b36732" {
Self::Bf3DpuMode
} else if part_number.starts_with("900-9d3b4") {
Expand All @@ -1858,20 +1864,15 @@ impl MlxDeviceKind {
Self::Unknown
}
}

/// Whether this is a BlueField-3 operating in NIC mode -- the devices whose
/// NIC firmware most needs auditing, since their Arm OS can't report it.
pub fn is_nic_mode(&self) -> bool {
matches!(self, Self::Bf3NicMode)
}
}

impl Display for MlxDeviceKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let label = match self {
Self::Bf3NicMode => "BlueField-3 (NIC mode)",
Self::Bf3DpuMode => "BlueField-3 (DPU mode)",
Self::Bf3SuperNic => "BlueField-3 SuperNIC",
// Both SuperNIC SKU families render under NVIDIA's product name;
// the part number alongside is the discriminator.
Self::Bf3NicMode | Self::Bf3SuperNic => "BlueField-3 SuperNIC",
Self::Bf3DpuMode => "BlueField-3 DPU",
Self::Bf2Dpu => "BlueField-2 DPU",
Self::Unknown => "Unknown",
};
Expand Down Expand Up @@ -1919,7 +1920,9 @@ pub struct ExploredMlxDevice {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dpu_bmc_ip: Option<IpAddr>,
/// The DPU's authoritative operating mode, read from its own Redfish endpoint
/// when matched -- corroborates the part-number-derived `device_kind`.
/// when matched. This is the mode the card is running in right now;
/// `device_kind` is its factory SKU, and the two legitimately differ for a
/// DPU reconfigured to run as a NIC.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub nic_mode: Option<NicMode>,
}
Expand Down
13 changes: 9 additions & 4 deletions crates/rpc/proto/site_explorer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,18 @@ message ExploredMlxDevice {
// DPU we have explored -- the address to target for a firmware push.
optional string dpu_bmc_ip = 9;
// The DPU's authoritative operating mode, read from its own Redfish endpoint
// when matched.
// when matched. This is the mode the card is running in right now; it
// legitimately differs from the SKU-derived device_kind for a DPU
// reconfigured to run as a NIC.
optional NicMode nic_mode = 10;
}

// The kind of BlueField/Mellanox device, classified from its part number. A
// BlueField-3's part number records the mode it is operating in: 900-9D3B4
// (NIC), 900-9D3B6 (DPU), 900-9D3D4 (SuperNIC).
// The kind of BlueField/Mellanox device, classified from its part number. The
// part number identifies the factory SKU, not the operating mode: 900-9D3B6 is
// a BlueField-3 DPU product, 900-9D3B4 and 900-9D3D4 are BlueField-3 SuperNIC
// products. A DPU/NIC mode flip does not change it -- nic_mode carries the
// operating mode. The *_MODE value names are frozen from when this was
// believed to track the operating mode.
enum MlxDeviceKind {
MLX_DEVICE_KIND_UNKNOWN = 0;
MLX_DEVICE_KIND_BF3_NIC_MODE = 1;
Expand Down
13 changes: 9 additions & 4 deletions rest-api/proto/core/gen/v1/site_explorer_nico.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions rest-api/proto/core/src/v1/site_explorer_nico.proto
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,18 @@ message ExploredMlxDevice {
// DPU we have explored -- the address to target for a firmware push.
optional string dpu_bmc_ip = 9;
// The DPU's authoritative operating mode, read from its own Redfish endpoint
// when matched.
// when matched. This is the mode the card is running in right now; it
// legitimately differs from the SKU-derived device_kind for a DPU
// reconfigured to run as a NIC.
optional NicMode nic_mode = 10;
}

// The kind of BlueField/Mellanox device, classified from its part number. A
// BlueField-3's part number records the mode it is operating in: 900-9D3B4
// (NIC), 900-9D3B6 (DPU), 900-9D3D4 (SuperNIC).
// The kind of BlueField/Mellanox device, classified from its part number. The
// part number identifies the factory SKU, not the operating mode: 900-9D3B6 is
// a BlueField-3 DPU product, 900-9D3B4 and 900-9D3D4 are BlueField-3 SuperNIC
// products. A DPU/NIC mode flip does not change it -- nic_mode carries the
// operating mode. The *_MODE value names are frozen from when this was
// believed to track the operating mode.
enum MlxDeviceKind {
MLX_DEVICE_KIND_UNKNOWN = 0;
MLX_DEVICE_KIND_BF3_NIC_MODE = 1;
Expand Down
Loading