From 3de6471c6c9c1764f6f9c819bcf51c2ee3ce5acc Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Thu, 20 Nov 2025 10:29:42 -0800 Subject: [PATCH 1/3] reorder network/nic tables in report Signed-off-by: Harper, Jason M --- cmd/report/report.go | 7 +--- internal/report/table_defs.go | 55 ++++++++++++++------------- internal/report/table_helpers.go | 2 - internal/report/table_helpers_test.go | 3 -- internal/script/script_defs.go | 6 ++- 5 files changed, 35 insertions(+), 38 deletions(-) diff --git a/cmd/report/report.go b/cmd/report/report.go index d3cbf2e2..49e9094b 100644 --- a/cmd/report/report.go +++ b/cmd/report/report.go @@ -67,7 +67,6 @@ var ( flagMemory bool flagDimm bool flagNic bool - flagNetIrq bool flagNetConfig bool flagDisk bool flagFilesystem bool @@ -108,9 +107,8 @@ const ( flagSSTName = "sst" flagMemoryName = "memory" flagDimmName = "dimm" - flagNicName = "nic" flagNetConfigName = "netconfig" - flagNetIrqName = "netirq" + flagNicName = "nic" flagDiskName = "disk" flagFilesystemName = "filesystem" flagGpuName = "gpu" @@ -171,9 +169,8 @@ var categories = []common.Category{ {FlagName: flagElcName, FlagVar: &flagElc, Help: "Efficiency Latency Control Settings", TableNames: []string{report.ElcTableName}}, {FlagName: flagMemoryName, FlagVar: &flagMemory, Help: "Memory Configuration", TableNames: []string{report.MemoryTableName}}, {FlagName: flagDimmName, FlagVar: &flagDimm, Help: "DIMM Population", TableNames: []string{report.DIMMTableName}}, - {FlagName: flagNicName, FlagVar: &flagNic, Help: "Network Cards", TableNames: []string{report.NICTableName, report.NICPacketSteeringTableName}}, {FlagName: flagNetConfigName, FlagVar: &flagNetConfig, Help: "Network Configuration", TableNames: []string{report.NetworkConfigTableName}}, - {FlagName: flagNetIrqName, FlagVar: &flagNetIrq, Help: "Network IRQ to CPU Mapping", TableNames: []string{report.NetworkIRQMappingTableName}}, + {FlagName: flagNicName, FlagVar: &flagNic, Help: "Network Cards", TableNames: []string{report.NICTableName, report.NICCpuAffinityTableName, report.NICPacketSteeringTableName}}, {FlagName: flagDiskName, FlagVar: &flagDisk, Help: "Storage Devices", TableNames: []string{report.DiskTableName}}, {FlagName: flagFilesystemName, FlagVar: &flagFilesystem, Help: "File Systems", TableNames: []string{report.FilesystemTableName}}, {FlagName: flagGpuName, FlagVar: &flagGpu, Help: "GPUs", TableNames: []string{report.GPUTableName}}, diff --git a/internal/report/table_defs.go b/internal/report/table_defs.go index 27ebabe1..137e4b00 100644 --- a/internal/report/table_defs.go +++ b/internal/report/table_defs.go @@ -92,9 +92,9 @@ const ( ElcTableName = "Efficiency Latency Control" MemoryTableName = "Memory" DIMMTableName = "DIMM" - NICTableName = "NIC" - NetworkIRQMappingTableName = "Network IRQ Mapping" NetworkConfigTableName = "Network Configuration" + NICTableName = "NIC" + NICCpuAffinityTableName = "NIC CPU Affinity" NICPacketSteeringTableName = "NIC Packet Steering" DiskTableName = "Disk" FilesystemTableName = "Filesystem" @@ -367,21 +367,29 @@ var tableDefinitions = map[string]TableDefinition{ FieldsFunc: dimmTableValues, InsightsFunc: dimmTableInsights, HTMLTableRendererFunc: dimmTableHTMLRenderer}, - NICTableName: { - Name: NICTableName, - HasRows: true, + NetworkConfigTableName: { + Name: NetworkConfigTableName, + HasRows: false, MenuLabel: NetworkMenuLabel, + ScriptNames: []string{ + script.SysctlScriptName, + script.IRQBalanceScriptName, + }, + FieldsFunc: networkConfigTableValues}, + NICTableName: { + Name: NICTableName, + HasRows: true, ScriptNames: []string{ script.NicInfoScriptName, }, FieldsFunc: nicTableValues}, - NetworkConfigTableName: { - Name: NetworkConfigTableName, - HasRows: false, + NICCpuAffinityTableName: { + Name: NICCpuAffinityTableName, + HasRows: true, ScriptNames: []string{ - script.SysctlScriptName, + script.NicInfoScriptName, }, - FieldsFunc: networkConfigTableValues}, + FieldsFunc: nicCpuAffinityTableValues}, NICPacketSteeringTableName: { Name: NICPacketSteeringTableName, HasRows: true, @@ -389,13 +397,6 @@ var tableDefinitions = map[string]TableDefinition{ script.NicInfoScriptName, }, FieldsFunc: nicPacketSteeringTableValues}, - NetworkIRQMappingTableName: { - Name: NetworkIRQMappingTableName, - HasRows: true, - ScriptNames: []string{ - script.NicInfoScriptName, - }, - FieldsFunc: networkIRQMappingTableValues}, DiskTableName: { Name: DiskTableName, HasRows: true, @@ -1637,7 +1638,6 @@ func nicTableValues(outputs map[string]script.ScriptOutput) []Field { {Name: "MTU", Description: "Maximum Transmission Unit. The largest size packet or frame, specified in octets (eight-bit bytes), that can be sent in a packet- or frame-based network such as the Internet."}, {Name: "TX Queues"}, {Name: "RX Queues"}, - {Name: "IRQBalance", Description: "System level setting. Dynamically monitors system activity and spreads IRQs across available cores, aiming to balance CPU load, improve throughput, and reduce latency for interrupt-heavy workloads."}, {Name: "Adaptive RX", Description: "Enables dynamic adjustment of receive interrupt coalescing based on traffic patterns."}, {Name: "Adaptive TX", Description: "Enables dynamic adjustment of transmit interrupt coalescing based on traffic patterns."}, {Name: "rx-usecs", Description: "Sets the delay, in microseconds, before an interrupt is generated after receiving a packet. Higher values reduce CPU usage (by batching packets), but increase latency. Lower values reduce latency, but increase interrupt rate and CPU load."}, @@ -1675,11 +1675,10 @@ func nicTableValues(outputs map[string]script.ScriptOutput) []Field { fields[12].Values = append(fields[12].Values, nicInfo.MTU) fields[13].Values = append(fields[13].Values, nicInfo.TXQueues) fields[14].Values = append(fields[14].Values, nicInfo.RXQueues) - fields[15].Values = append(fields[15].Values, nicInfo.IRQBalance) - fields[16].Values = append(fields[16].Values, nicInfo.AdaptiveRX) - fields[17].Values = append(fields[17].Values, nicInfo.AdaptiveTX) - fields[18].Values = append(fields[18].Values, nicInfo.RxUsecs) - fields[19].Values = append(fields[19].Values, nicInfo.TxUsecs) + fields[15].Values = append(fields[15].Values, nicInfo.AdaptiveRX) + fields[16].Values = append(fields[16].Values, nicInfo.AdaptiveTX) + fields[17].Values = append(fields[17].Values, nicInfo.RxUsecs) + fields[18].Values = append(fields[18].Values, nicInfo.TxUsecs) } return fields } @@ -1700,14 +1699,14 @@ func nicPacketSteeringTableValues(outputs map[string]script.ScriptOutput) []Fiel // XPS row if nicInfo.TXQueues != "0" { fields[0].Values = append(fields[0].Values, nicInfo.Name) - fields[1].Values = append(fields[1].Values, "xps_cpus") + fields[1].Values = append(fields[1].Values, "XPS") fields[2].Values = append(fields[2].Values, formatQueueCPUMappings(nicInfo.XPSCPUs, "tx-")) } // RPS row if nicInfo.RXQueues != "0" { fields[0].Values = append(fields[0].Values, nicInfo.Name) - fields[1].Values = append(fields[1].Values, "rps_cpus") + fields[1].Values = append(fields[1].Values, "RPS") fields[2].Values = append(fields[2].Values, formatQueueCPUMappings(nicInfo.RPSCPUs, "rx-")) } } @@ -1746,7 +1745,7 @@ func formatQueueCPUMappings(mappings map[string]string, prefix string) string { return strings.Join(queueMappings, " | ") } -func networkIRQMappingTableValues(outputs map[string]script.ScriptOutput) []Field { +func nicCpuAffinityTableValues(outputs map[string]script.ScriptOutput) []Field { nicIRQMappings := nicIRQMappingsFromOutput(outputs) if len(nicIRQMappings) == 0 { return []Field{} @@ -1772,6 +1771,7 @@ func networkConfigTableValues(outputs map[string]script.ScriptOutput) []Field { {Name: "net.core.netdev_max_backlog"}, {Name: "net.ipv4.tcp_max_syn_backlog"}, {Name: "net.core.somaxconn"}, + {Name: "IRQ Balance"}, } // load the params into a map so we can easily look them up sysctlParams := make(map[string]string) @@ -1788,13 +1788,14 @@ func networkConfigTableValues(outputs map[string]script.ScriptOutput) []Field { } } // add the values to the fields - for i := range fields { + for i := range fields[:7] { if val, ok := sysctlParams[fields[i].Name]; ok { fields[i].Values = append(fields[i].Values, val) } else { fields[i].Values = append(fields[i].Values, "") } } + fields[7].Values = append(fields[7].Values, strings.TrimSpace(outputs[script.IRQBalanceScriptName].Stdout)) return fields } diff --git a/internal/report/table_helpers.go b/internal/report/table_helpers.go index 8e9eb752..f1ab9d8f 100644 --- a/internal/report/table_helpers.go +++ b/internal/report/table_helpers.go @@ -1254,7 +1254,6 @@ type nicInfo struct { MACAddress string NUMANode string CPUAffinity string - IRQBalance string AdaptiveRX string AdaptiveTX string RxUsecs string @@ -1294,7 +1293,6 @@ func parseNicInfo(scriptOutput string) []nicInfo { "MAC Address: ": &nic.MACAddress, "NUMA Node: ": &nic.NUMANode, "CPU Affinity: ": &nic.CPUAffinity, - "IRQ Balance: ": &nic.IRQBalance, "rx-usecs: ": &nic.RxUsecs, "tx-usecs: ": &nic.TxUsecs, "MTU: ": &nic.MTU, diff --git a/internal/report/table_helpers_test.go b/internal/report/table_helpers_test.go index b088666e..989cd991 100644 --- a/internal/report/table_helpers_test.go +++ b/internal/report/table_helpers_test.go @@ -654,9 +654,6 @@ func TestParseNicInfo(t *testing.T) { if first.CPUAffinity == "" { t.Errorf("expected non-empty CPUAffinity") } - if first.IRQBalance != "Disabled" { - t.Errorf("expected IRQBalance 'Disabled', got '%s'", first.IRQBalance) - } if first.AdaptiveRX != "off" { t.Errorf("expected AdaptiveRX 'off', got '%s'", first.AdaptiveRX) } diff --git a/internal/script/script_defs.go b/internal/script/script_defs.go index 7dabee94..21b0c94f 100644 --- a/internal/script/script_defs.go +++ b/internal/script/script_defs.go @@ -83,6 +83,7 @@ const ( TransparentHugePagesScriptName = "transparent huge pages" NumaBalancingScriptName = "numa balancing" NicInfoScriptName = "nic info" + IRQBalanceScriptName = "irq balance" DiskInfoScriptName = "disk info" HdparmScriptName = "hdparm" DfScriptName = "df" @@ -779,7 +780,6 @@ rdmsr 0x2FFE printf "%s:%s;" "$int" "$cpu" done printf "\n" - echo "IRQ Balance: $(pgrep irqbalance >/dev/null 2>&1 && echo "Enabled" || echo "Disabled")" echo "TX Queues: $(ls -d /sys/class/net/"$ifc"/queues/tx-* | wc -l)" echo "RX Queues: $(ls -d /sys/class/net/"$ifc"/queues/rx-* | wc -l)" for q in /sys/class/net/"$ifc"/queues/tx-*; do @@ -798,6 +798,10 @@ done Depends: []string{"ethtool"}, Superuser: true, }, + IRQBalanceScriptName: { + Name: IRQBalanceScriptName, + ScriptTemplate: "pgrep irqbalance >/dev/null 2>&1 && echo 'Enabled' || echo 'Disabled'", + }, DiskInfoScriptName: { Name: DiskInfoScriptName, ScriptTemplate: `echo "NAME|MODEL|SIZE|MOUNTPOINT|FSTYPE|RQ-SIZE|MIN-IO|FIRMWARE|ADDR|NUMA|LINKSPEED|LINKWIDTH|MAXLINKSPEED|MAXLINKWIDTH" From 9d7cb7ae79cb3aef4ba1fc2796c90df1ee1989f5 Mon Sep 17 00:00:00 2001 From: Jason Harper <78619061+harp-intel@users.noreply.github.com> Date: Fri, 21 Nov 2025 07:28:57 -0800 Subject: [PATCH 2/3] address magic number Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- internal/report/table_defs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/report/table_defs.go b/internal/report/table_defs.go index 137e4b00..37dba321 100644 --- a/internal/report/table_defs.go +++ b/internal/report/table_defs.go @@ -1788,14 +1788,14 @@ func networkConfigTableValues(outputs map[string]script.ScriptOutput) []Field { } } // add the values to the fields - for i := range fields[:7] { + for i := range fields[:len(fields)-1] { if val, ok := sysctlParams[fields[i].Name]; ok { fields[i].Values = append(fields[i].Values, val) } else { fields[i].Values = append(fields[i].Values, "") } } - fields[7].Values = append(fields[7].Values, strings.TrimSpace(outputs[script.IRQBalanceScriptName].Stdout)) + fields[len(fields)-1].Values = append(fields[len(fields)-1].Values, strings.TrimSpace(outputs[script.IRQBalanceScriptName].Stdout)) return fields } From aaf21b553fd78b16b5ca9ab38c505cf6d372a357 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Fri, 21 Nov 2025 07:34:07 -0800 Subject: [PATCH 3/3] fix: return empty string instead of "N/A" for empty queue mappings Signed-off-by: Harper, Jason M --- internal/report/table_defs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/report/table_defs.go b/internal/report/table_defs.go index 137e4b00..39dc2dc6 100644 --- a/internal/report/table_defs.go +++ b/internal/report/table_defs.go @@ -1740,7 +1740,7 @@ func formatQueueCPUMappings(mappings map[string]string, prefix string) string { } if len(queueMappings) == 0 { - return "N/A" + return "" } return strings.Join(queueMappings, " | ") }