On 14 Apr 2026, at 10:32, Eli Britstein wrote:

> On 08/04/2026 18:06, Eelco Chaudron wrote:
>> External email: Use caution opening links or attachments
>>
>>
>> This patch refactors the DPDK offload test infrastructure to simplify
>> the interface configuration.  Instead of using OVS_DPDK_VF_PCI_ADDRS
>> with a space-separated list of PCI addresses and VF indices (e.g.,
>> "0000:17:00.0,0 0000:17:00.0,1"), the tests now use OVS_PF_PCI
>> with a single PF address (e.g., "0000:17:00.0") and derive VF
>> information from sysfs.
>
> Hi Eelco
>
> Thanks for this. Just a few nits below.

Thanks for reviewing, Eli! I'll send out a v3; see comments on
your comments below :)

//Eelco

>>
>> Signed-off-by: Eelco Chaudron <[email protected]>
>> ---
>> Changes to v2:
>> - Use PCI address rather than port name, so other blades might
>>    be supported.
>> - Moved/renamed shell helpers.
>> - Updated documentation.
>> ---
>>   Documentation/topics/testing.rst     |  25 ++++---
>>   tests/system-common-macros.at        |  89 ++++++++++++++++++++++
>>   tests/system-dpdk-offloads-macros.at | 108 ++++-----------------------
>>   3 files changed, 120 insertions(+), 102 deletions(-)
>>
>> diff --git a/Documentation/topics/testing.rst 
>> b/Documentation/topics/testing.rst
>> index deb6088d7..9cb9e0b5b 100644
>> --- a/Documentation/topics/testing.rst
>> +++ b/Documentation/topics/testing.rst
>> @@ -306,19 +306,26 @@ Userspace datapath with DPDK offload
>>
>>   To invoke the userspace datapath tests with DPDK and its rte_flow offload,
>>   the same prerequisites apply as above. In addition, six Virtual Function 
>> (VF)
>> -interfaces must be preconfigured and capable of hardware offloading traffic
>> -between each other.
>> +interfaces must be preconfigured on a single Physical Function (PF) that
>> +supports rte_flow hardware offload.
>>
>> -These six VFs need to be passed as a list of PF PCI addresses with their
>> -corresponding VF indexes in the OVS_DPDK_VF_PCI_ADDRS variable.
>> -For example::
>> +This is an example on how to set this up for an NVIDIA blade on port
>> +``ens2f0np0``::
>>
>> -    OVS_DPDK_VF_PCI_ADDRS="0000:17:00.0,0 0000:17:00.0,1 0000:17:00.0,2 
>> 0000:17:00.0,3 0000:17:00.0,4 0000:17:00.0,5"
>> +    OVS_PF_PORT=ens2f0np0
>> +    OVS_PF_PCI=$(basename $(readlink /sys/class/net/$OVS_PF_PORT/device))
>
> Mentioning "OVS_PF_PORT", though just here for explaining how to configure 
> VFs might be confusing for the user.
>
> I think we can leave it to the user to figure out the PCI address of the 
> port, and drop those 2 lines.

You would be surprised how often I get the PCI question... But I
will move the interface name directly into the OVS_PF_PCI definition.

>> +    echo 0 > /sys/bus/pci/devices/$OVS_PF_PCI/sriov_numvfs
>> +    devlink dev eswitch set pci/$OVS_PF_PCI mode switchdev
>> +    echo 6 > /sys/bus/pci/devices/$OVS_PF_PCI/sriov_numvfs
>>
>> -To invoke the dpdk offloads testsuite with the userspace datapath, run::
>> +This PF's PCI ID needs to be passed with the OVS_PF_PORT variable.
> s/OVS_PF_PORT/OVS_PF_PCI

ACK

>> +To invoke the DPDK offloads testsuite with the userspace datapath, run::
>>
>> -    make check-dpdk-offloads \
>> -        OVS_DPDK_VF_PCI_ADDRS="0000:17:00.0,0 0000:17:00.0,1 0000:17:00.0,2 
>> 0000:17:00.0,3 0000:17:00.0,4 0000:17:00.0,5"
>> +    make check-dpdk-offloads OVS_PF_PCI=0000:17:00.0
>> +
>> +.. note::
>> +   This has only been tested on NVIDIA blades due to the limited 
>> availability
>> +   of other blades that support rte_flow.
>>
>>   Userspace datapath: Testing and Validation of CPU-specific Optimizations
>>   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
>> index e4862231a..90a34b406 100644
>> --- a/tests/system-common-macros.at
>> +++ b/tests/system-common-macros.at
>> @@ -409,3 +409,92 @@ m4_define([OVS_CHECK_PSAMPLE],
>>   # OVS_CHECK_XT()
>>   m4_define([OVS_CHECK_XT],
>>       [AT_SKIP_IF([test $HAVE_IPTABLES = no && test $HAVE_NFT = no])])
>> +
>> +OVS_START_SHELL_HELPERS
>> +
>> +# ovs_get_vf_netdev(<PF_PORT_PCI>, <VF_INDEX>)
>> +#
>> +# This function tries to find the VF's netdev for the given PF's VF index.
>> +#
>> +ovs_get_vf_netdev() {
> s/netdev/port?

ACK

>> +    PF_PCI=$1
>> +    VF_IDX=$2
> local? also in other functions

Done for shell functions.

>> +
>> +    vf_net_dir="/sys/bus/pci/devices/$PF_PCI/virtfn$VF_IDX/net"
>> +    if test ! -d "$vf_net_dir"; then
>> +        return 1
>> +    fi
>> +
>> +    vf_name=$(ls "$vf_net_dir" 2>/dev/null | head -1)
>> +    if test -z "$vf_name"; then
>> +        return 2
>> +    fi
>> +
>> +    echo "$vf_name"
>> +    return 0
>> +}
>> +
>> +# ovs_get_representor_netdev(<PF_PORT_PCI>, <VF_INDEX>)
>> +#
>> +# This function tries to find the representor's netdev for the given PF's VF
>> +# index.
>> +#
>> +ovs_get_representor_netdev() {
>> +    PF_PCI=$1
>> +    VF_IDX=$2
>> +
>> +    representor=$(grep -l "vf$VF_IDX$" \
>> +                  /sys/bus/pci/devices/$PF_PCI/net/*/phys_port_name \
>> +                  2>/dev/null | head -1)
>> +    if test -z "$representor"; then
>> +        return 2
>> +    fi
>> +
>> +    basename $(dirname "$representor")
>> +    return 0
>> +}
>> +
>> +# ovs_verify_pf_cfg(<PF_PORT_PCI>)
>> +#
>> +# Verify that the given PF port exists and that the required VFs are 
>> properly
>> +# configured, i.e. have representor ports.
>> +#
>> +ovs_verify_pf_cfg() {
>> +    PF_PCI=$1
>> +    VF_NAMES=()
>> +    REPRESENTOR_NAMES=()
>> +    PCI_REGEX=[[0-9a-fA-F]]{4}:[[0-9a-fA-F]]{2}:[[0-9a-fA-F]]{2}\.[[0-7]]
>> +
>> +    echo "$PF_PCI" | grep -E -q "^$PCI_REGEX$" || return 1
>> +
>> +    for i in {0..5}; do
>> +        # Get VF netdev using PCI path
>> +        vf_net_dir="/sys/bus/pci/devices/$PF_PCI/virtfn$i/net"
>> +        if test ! -d "$vf_net_dir"; then
>> +            return 2
>> +        fi
>> +
>> +        vf_name=$(ls "$vf_net_dir" 2>/dev/null | head -1)
>> +        if test -z "$vf_name"; then
>> +            return 3
>> +        fi
>> +        VF_NAMES+=($vf_name)
>> +
>> +        # Find representor port for this VF
>> +        representor=$(grep -l "vf$i$" \
>> +                      /sys/bus/pci/devices/$PF_PCI/net/*/phys_port_name \
>> +                      2>/dev/null | head -1)
>> +        if test -z "$representor"; then
>> +            return 4
>> +        fi
>> +        REPRESENTOR_NAMES+=($(basename $(dirname "$representor")))
>> +    done
>> +
>> +    if test "${#VF_NAMES[*]}" -lt 6 -o "${#REPRESENTOR_NAMES[*]}" -lt 6; 
>> then
>> +        return 5
>> +    fi
>> +
>> +    return 0
>> +}
>> +
>> +OVS_END_SHELL_HELPERS
>> diff --git a/tests/system-dpdk-offloads-macros.at 
>> b/tests/system-dpdk-offloads-macros.at
>> index ff7a6e095..1ea089290 100644
>> --- a/tests/system-dpdk-offloads-macros.at
>> +++ b/tests/system-dpdk-offloads-macros.at
>> @@ -54,10 +54,8 @@ m4_define([CHECK_NO_DPDK_OFFLOAD],
>>   #
>>   m4_define([OVS_DPDK_OFFLOAD_PRE_CHECK], [
>>     OVS_DPDK_PRE_CHECK()
>> -  AT_SKIP_IF(
>> -    [test "$(printf '%s' "$OVS_DPDK_VF_PCI_ADDRS" | wc -w)" -ne 6])
>> -
>> -  AT_SKIP_IF([! ovs_dpdk_verify_vf_cfg "$OVS_DPDK_VF_PCI_ADDRS"])
>> +  AT_SKIP_IF([test -z "$OVS_PF_PCI"])
>> +  AT_SKIP_IF([! ovs_verify_pf_cfg "$OVS_PF_PCI"])
>>   ])
>>
>>   # OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], 
>> [dbinit-aux-args])
>> @@ -114,39 +112,38 @@ $1";/mlx5_net: Failed to update link status: /d"])
>>   m4_define([ADD_VF],
>>       [ USER_PORT=$1
>>         case "$USER_PORT" in
>> -        client) PORT_NO=0 ;;
>> -        server) PORT_NO=1 ;;
>> -        *) PORT_NO=${USER_PORT##*[!0-9]} ;;
>> +        client) VF_IDX=0 ;;
>> +        server) VF_IDX=1 ;;
>> +        *) VF_IDX=${USER_PORT##*[!0-9]} ;;
>>         esac
>>
>> -      AT_CHECK([[[ "$PORT_NO" -ge 0 ]] && [[ "$PORT_NO" -le 6 ]] || return 
>> 66])
>> -      PORT_CFG=$(echo $OVS_DPDK_VF_PCI_ADDRS | cut -d' ' -f$((PORT_NO+1)))
>> -      PF_PCI=$(ovs_dpdk_get_pci_id "$PORT_CFG")
>> -      VF_IDX=$(ovs_dpdk_get_vf_idx "$PORT_CFG")
>> -      REP=$(ovs_dpdk_get_representor_netdev $PF_PCI $VF_IDX)
>> -      AT_CHECK([test $? -eq 0])
>> +      AT_CHECK([[[ "$VF_IDX" -ge 0 ]] && [[ "$VF_IDX" -le 5 ]] || return 
>> 66])
>> +
>> +      VF=$(ovs_get_vf_netdev $OVS_PF_PCI $VF_IDX)
>> +      AT_CHECK([test -n "$VF"])
>>
>> -      AT_CHECK([ip link set $REP name $1])
>> +      AT_CHECK([ip link set $VF down])
>> +      AT_CHECK([ip link set $VF name $1])
>>         AT_CHECK([ip link set $1 netns $2])
>>         AT_CHECK([ovs-vsctl add-port $3 ovs-$1 -- \
>>                   set interface ovs-$1 external-ids:iface-id="$1" -- \
>>                   set interface ovs-$1 type=dpdk -- \
>>                   set interface ovs-$1 \
>> -                  options:dpdk-devargs=$PF_PCI,representor=vf$VF_IDX])
>> +                  options:dpdk-devargs=$OVS_PF_PCI,representor=vf$VF_IDX])
>>         NS_CHECK_EXEC([$2], [ip addr add $4 dev $1 $7])
>>         NS_CHECK_EXEC([$2], [ip link set dev $1 up])
>>         if test -n "$5"; then
>>           NS_CHECK_EXEC([$2], [ip link set dev $1 address $5])
>>         else
>>           NS_CHECK_EXEC([$2],
>> -                      [ip link set dev $1 address 02:00:00:00:EC:0$PORT_NO])
>> +                      [ip link set dev $1 address 02:00:00:00:EC:0$VF_IDX])
>>         fi
>>         if test -n "$6"; then
>>           NS_CHECK_EXEC([$2], [ip route add default via $6])
>>         fi
>>         on_exit "ip netns exec $2 ip link set $1 netns 1; \
>> -               ip link property del dev $1 altname $REP; \
>> -               ip link set $1 name $REP"
>> +               ip link property del dev $1 altname $VF; \
>> +               ip link set $1 name $VF"
>>       ]
>>   )
>>   m4_define([ADD_VETH], [ADD_VF($@)])
>> @@ -159,78 +156,3 @@ m4_define([DUMP_DP_IP_CLEAN_SORTED], [dnl
>>     grep 'eth_type(0x0800)' \
>>       | sed -e 
>> 's/eth(src=[[a-z0-9:]]*,dst=[[a-z0-9:]]*)/eth(macs)/;s/recirc_id(0),//' \
>>       | strip_used | strip_ptype | sort])
>> -
>> -OVS_START_SHELL_HELPERS
>> -
>> -# ovs_dpdk_is_valid_pci_vf_addr()
>> -#
>> -# Check if the given PF PCI address and the VF number are valid.
>> -#
>> -ovs_dpdk_is_valid_pci_vf_addr() {
>> -    PCI_ID='[[0-9a-fA-F]]{4}:[[0-9a-fA-F]]{2}:[[0-9a-fA-F]]{2}\.[[0-7]]'
>> -    echo "$1" | grep -E -q "^$PCI_ID,[[0-9]]+$" && return 0 || return 1
>> -}
>> -
>> -# ovs_dpdk_get_pci_id()
>> -#
>> -ovs_dpdk_get_pci_id() {
>> -    printf '%s\n' "${1%%,*}"
>> -}
>> -
>> -# ovs_dpdk_get_vf_idx()
>> -#
>> -ovs_dpdk_get_vf_idx() {
>> -    printf '%s\n' "${1##*,}"
>> -}
>> -
>> -# ovs_dpdk_get_representor_netdev(<PF_PCI>, <VF_INDEX>)
>> -#
>> -# This function tries to find the representor netdev for the given PF's VF.
>> -#
>> -ovs_dpdk_get_representor_netdev() {
>> -    PF_PCI=$1
>> -    VF_IDX=$2
>> -
>> -    VF_NET_DIR="/sys/bus/pci/devices/$PF_PCI/virtfn$VF_IDX/net"
>> -
>> -    if [[ ! -d "$VF_NET_DIR" ]]; then
>> -        echo "ERROR: VF $VF_IDX for PF $PF_PCI does not exist" >&2
>> -        return 1
>> -    fi
>> -
>> -    for iface in "$VF_NET_DIR"/*; do
>> -        if [[ -e "$iface" ]]; then
>> -            basename "$iface"
>> -            return 0
>> -        fi
>> -    done
>> -
>> -    echo "ERROR: No representor netdev found for VF $VF_IDX on PF $PF_PCI" 
>> >&2
>> -    return 1
>> -}
>> -
>> -# ovs_dpdk_verify_vf_cfg()
>> -#
>> -# Verify that the given PF PCI addresses and corresponding VF IDs in
>> -# OVS_DPDK_VF_PCI_ADDRS are valid, exist, and have corresponding
>> -# representor ports.
>> -#
>> -ovs_dpdk_verify_vf_cfg() {
>> -    i=0
>> -
>> -    for addr in $1; do
>> -        ovs_dpdk_is_valid_pci_vf_addr "$addr" || return 1
>> -
>> -        PCI_ID=$(ovs_dpdk_get_pci_id "$addr")
>> -        VF_IDX=$(ovs_dpdk_get_vf_idx "$addr")
>> -
>> -        REP=$(ovs_dpdk_get_representor_netdev $PCI_ID $VF_IDX) || return 1
>> -
>> -        echo "ovs-p$i: PF PCI $PCI_ID with VF $VF_IDX has representor $REP"
>> -        i=$((i + 1))
>> -    done
>> -
>> -    return 0
>> -}
>> -
>> -OVS_END_SHELL_HELPERS
>> --
>> 2.47.3
>>

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to