141 lines
5.1 KiB
Diff
141 lines
5.1 KiB
Diff
commit a60b96821be3fadaf89d643072488e4762b28d10
|
|
Author: Halil Pasic <pasic@linux.ibm.com>
|
|
Date: Tue Dec 2 15:25:40 2025 +0100
|
|
|
|
smc_rnics: fix regression when PFT not available
|
|
|
|
Before commit 0b965ae ("smc_rnics: Add support for Network Express RNIC
|
|
in smc_rnics") the device type detection was based on PCI vendor and
|
|
device ID. The aforementioned commit switched smc_rnics to doing
|
|
the device type detection primarily on PCI function type (PFT), which
|
|
is in general a sound thing to do.
|
|
|
|
In certain virtualized environments however (most notably QEMU+KVM) PFT
|
|
is generally not available, and even for passed through devices, as of
|
|
now PFT 0 is reported regardless of the actual PFT as seen by G1 (i.e.
|
|
LPAR). And that leads to not detecting passed through rnics as such, and
|
|
generally displaying an empty list when smc_rnics is called with no
|
|
parameters, even in a presence of rnics to display.
|
|
|
|
The patch also degraded the ability of the script to handle unknown
|
|
vendor id 0x15b3 devices gracefully. This can be relevant if a not
|
|
enlightened version of the script is used on new hardware.
|
|
|
|
Adding a warning about the surprise PFT 0 does not seem to be a good
|
|
idea, because there are PCI devices which are readily available on
|
|
s390x and for which PFT 0 is just expected: most notably virtio-pci, and
|
|
frankly it isn't all that helpful either.
|
|
|
|
On the other hand, using the PFT, when available and suitable, is still
|
|
considered superior.
|
|
|
|
Use the old PCI vendor and device ID based logic as a fall back when PFT
|
|
is not available or not known.
|
|
|
|
With this the regressions introduced by commit 0b965ae ("smc_rnics: Add
|
|
support for Network Express RNIC in smc_rnics") shall be gone.
|
|
|
|
While at it fix the handling of ports too. The call to
|
|
set_RoCE_dev_and_port in the loop that iterates over network interfaces
|
|
does not make sense; and 'RoCE Express' needs special handling as a
|
|
device that has multiple ports and interfaces per PCI function
|
|
regardless of the value the variable 'rawIDs'.
|
|
|
|
I don't quite understand why grabbing port from the interface's dev_port
|
|
attribute is a bad idea. That precedence was established by 05d1c7e
|
|
("smc_rnics: Fix RoCE Express2 port display"). My best guess is that
|
|
dev_port is only valid if a PCI function can interact with multiple
|
|
physical ports, which is not the case with RoCE Express2 and higher. So
|
|
I am leaving that as is.
|
|
|
|
Fixes: commit 0b965ae ("smc_rnics: Add support for Network Express RNIC in smc_rnics")
|
|
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
|
|
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
|
|
|
|
diff --git a/smc_rnics b/smc_rnics
|
|
index 70b6f69..279da22 100755
|
|
--- a/smc_rnics
|
|
+++ b/smc_rnics
|
|
@@ -144,6 +144,26 @@ function set_by_firmware_lvl() {
|
|
set_RoCE_dev_and_port $name;
|
|
}
|
|
|
|
+function set_by_pciid(){
|
|
+
|
|
+ case "$vend" in
|
|
+ "0x1014" ) # IBM
|
|
+ case "$id" in
|
|
+ "0x04ed") dev_type="ISM";
|
|
+ int="n/a";;
|
|
+ esac;;
|
|
+ "0x15b3" ) # Mellanox
|
|
+ case "$id" in
|
|
+ "0x1003" | \
|
|
+ "0x1004") dev_type="RoCE_Express";
|
|
+ multiport_f=1;;
|
|
+ "0x1016") set_RoCE_dev_and_port "RoCE_Express2";;
|
|
+ "0x101e") set_by_firmware_lvl;;
|
|
+ *) set_RoCE_dev_and_port "Mlx_$id";;
|
|
+ esac;;
|
|
+ esac
|
|
+}
|
|
+
|
|
function print_rnics() {
|
|
# iterate over slots, as powered-off devices won't show elsewhere
|
|
for fid in `ls -1 /sys/bus/pci/slots`; do
|
|
@@ -188,12 +208,15 @@ function print_rnics() {
|
|
dev_type="${vend#0x}:${id#0x}";
|
|
pft=`cat pft`;
|
|
vfn=`cat vfn`;
|
|
+ multiport_f=0;
|
|
if [ $rawIDs -eq 0 ]; then
|
|
+ # prefer PFT for disamgibuating devices
|
|
case "$pft" in
|
|
"0x05") dev_type="ISM";
|
|
int="n/a";
|
|
set_RoCE_pft_and_vfn "$pft" "$vfn";;
|
|
"0x02") dev_type="RoCE_Express";
|
|
+ multiport_f=1;
|
|
set_RoCE_pft_and_vfn "$pft" "$vfn";;
|
|
"0x0a") set_by_firmware_lvl;
|
|
set_RoCE_pft_and_vfn "$pft" "$vfn";;
|
|
@@ -201,15 +224,20 @@ function print_rnics() {
|
|
"0x0f") set_RoCE_dev_and_port "Network_Express";
|
|
set_RoCE_pft_and_vfn "$pft" "$vfn";;
|
|
*)
|
|
+ # but if that fails go via the pci IDs
|
|
+ set_by_pciid
|
|
# For unknown PCI vendors, determine VF flag based on VFN value.
|
|
# This ensures consistent handling even for unrecognized vendor devices
|
|
- [ $all -eq 0 ] && continue
|
|
+ [ "$dev_type" = "${vend#0x}:${id#0x}" ] && [ $all -eq 0 ] && continue
|
|
if (( 16#${vfn#0x} != 0 )); then
|
|
vfn="y";
|
|
else
|
|
vfn="n";
|
|
fi;;
|
|
- esac
|
|
+ esac
|
|
+ else
|
|
+ set_RoCE_dev_and_port "$dev_type";
|
|
+ [ "0x15b3" = "$vend" ] && [ "0x1004" = "$id" ] && multiport_f=1;
|
|
fi
|
|
pchid="`cat pchid | sed 's/^0x//'`";
|
|
pnetids="`cat util_string | sed 's/\x0/\x40/g' | iconv -f IBM-1047 -t ASCII`";
|
|
@@ -221,10 +249,10 @@ function print_rnics() {
|
|
print_rnic;
|
|
continue;
|
|
fi
|
|
- # one device can have multiple interfaces (one per port)
|
|
for int in $interfaces; do
|
|
+ # one device can have multiple interfaces (one per port)
|
|
cd /sys/bus/pci/devices/$addr/net/$int;
|
|
- if [ "$dev_type" == "RoCE_Express" ] && [ -e dev_port ]; then
|
|
+ if [ $multiport_f -eq 1 ] && [ -e dev_port ]; then
|
|
port=`cat dev_port`;
|
|
fi
|
|
print_rnic;
|
|
--
|
|
2.54.0
|
|
|