From a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 5 Aug 2026 07:52:36 -0700 Subject: workqueue: skip the node_nr_active update for non-unbound workqueues apply_wqattrs_commit() updates node_nr_active->max unconditionally. wq->node_nr_active[] is only allocated for unbound workqueues, so guard the call before per-cpu workqueues start using this path. No functional change: only unbound workqueues reach apply_wqattrs_*() today. Signed-off-by: Breno Leitao Signed-off-by: Tejun Heo --- tools/testing/selftests/rdma/Makefile | 8 ++ tools/testing/selftests/rdma/config | 3 + tools/testing/selftests/rdma/rxe_ipv6.sh | 65 +++++++++++++++ .../selftests/rdma/rxe_rping_between_netns.sh | 92 ++++++++++++++++++++++ .../testing/selftests/rdma/rxe_sent_rcvd_bytes.sh | 75 ++++++++++++++++++ .../selftests/rdma/rxe_socket_with_netns.sh | 82 +++++++++++++++++++ .../selftests/rdma/rxe_test_NETDEV_UNREGISTER.sh | 65 +++++++++++++++ 7 files changed, 390 insertions(+) create mode 100644 tools/testing/selftests/rdma/Makefile create mode 100644 tools/testing/selftests/rdma/config create mode 100755 tools/testing/selftests/rdma/rxe_ipv6.sh create mode 100755 tools/testing/selftests/rdma/rxe_rping_between_netns.sh create mode 100755 tools/testing/selftests/rdma/rxe_sent_rcvd_bytes.sh create mode 100755 tools/testing/selftests/rdma/rxe_socket_with_netns.sh create mode 100755 tools/testing/selftests/rdma/rxe_test_NETDEV_UNREGISTER.sh (limited to 'tools/testing/selftests/rdma') diff --git a/tools/testing/selftests/rdma/Makefile b/tools/testing/selftests/rdma/Makefile new file mode 100644 index 000000000..07af7f15c --- /dev/null +++ b/tools/testing/selftests/rdma/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +TEST_PROGS := rxe_rping_between_netns.sh \ + rxe_ipv6.sh \ + rxe_socket_with_netns.sh \ + rxe_test_NETDEV_UNREGISTER.sh \ + rxe_sent_rcvd_bytes.sh + +include ../lib.mk diff --git a/tools/testing/selftests/rdma/config b/tools/testing/selftests/rdma/config new file mode 100644 index 000000000..4ffb814e2 --- /dev/null +++ b/tools/testing/selftests/rdma/config @@ -0,0 +1,3 @@ +CONFIG_TUN +CONFIG_VETH +CONFIG_RDMA_RXE diff --git a/tools/testing/selftests/rdma/rxe_ipv6.sh b/tools/testing/selftests/rdma/rxe_ipv6.sh new file mode 100755 index 000000000..32dad687a --- /dev/null +++ b/tools/testing/selftests/rdma/rxe_ipv6.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Configuration +NS_NAME="net6" +VETH_HOST="veth0" +VETH_NS="veth1" +RXE_NAME="rxe6" +PORT=4791 +IP6_ADDR="2001:db8::1/64" + +source "$(dirname "$0")/../kselftest/ktap_helpers.sh" + +exec > /dev/null + +# Cleanup function to run on exit (even on failure) +cleanup() { + ip netns del "$NS_NAME" 2>/dev/null + modprobe -r rdma_rxe 2>/dev/null + echo "Done." +} +trap cleanup EXIT + +# 1. Prerequisites check +for mod in tun veth rdma_rxe; do + if ! modinfo "$mod" >/dev/null 2>&1; then + echo "SKIP: Kernel module '$mod' not found." >&2 + exit $KSFT_SKIP + fi +done + +modprobe rdma_rxe + +# 2. Setup Namespace and Networking +echo "Setting up IPv6 network namespace..." +ip netns add "$NS_NAME" +ip link add "$VETH_HOST" type veth peer name "$VETH_NS" +ip link set "$VETH_NS" netns "$NS_NAME" +ip netns exec "$NS_NAME" ip addr add "$IP6_ADDR" dev "$VETH_NS" +ip netns exec "$NS_NAME" ip link set "$VETH_NS" up +ip link set "$VETH_HOST" up + +# 3. Add RDMA Link +echo "Adding RDMA RXE link..." +if ! ip netns exec "$NS_NAME" rdma link add "$RXE_NAME" type rxe netdev "$VETH_NS"; then + echo "Error: Failed to create RXE link." + exit 1 +fi + +# 4. Verification: Port should be listening +# Using -H to skip headers and -q for quiet exit codes +if ! ip netns exec "$NS_NAME" ss -Hul6n sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT is NOT listening after link creation." + exit 1 +fi +echo "Verified: Port $PORT is active." + +# 5. Removal and Verification +echo "Deleting RDMA link..." +ip netns exec "$NS_NAME" rdma link del "$RXE_NAME" + +if ip netns exec "$NS_NAME" ss -Hul6n sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT still active after link deletion." + exit 1 +fi +echo "Verified: Port $PORT closed successfully." diff --git a/tools/testing/selftests/rdma/rxe_rping_between_netns.sh b/tools/testing/selftests/rdma/rxe_rping_between_netns.sh new file mode 100755 index 000000000..e7554fbb8 --- /dev/null +++ b/tools/testing/selftests/rdma/rxe_rping_between_netns.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +# Configuration +NS="test1" +VETH_A="veth-a" +VETH_B="veth-b" +IP_A="1.1.1.1" +IP_B="1.1.1.2" +PORT=4791 + +source "$(dirname "$0")/../kselftest/ktap_helpers.sh" + +exec > /dev/null + +# --- Cleanup Routine --- +cleanup() { + echo "Cleaning up resources..." + rdma link del rxe1 2>/dev/null + ip netns exec "$NS" rdma link del rxe0 2>/dev/null + ip link delete "$VETH_B" 2>/dev/null + ip netns del "$NS" 2>/dev/null + modprobe -r rdma_rxe 2>/dev/null +} +trap cleanup EXIT + +# --- Prerequisite Checks --- +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if ! modinfo rdma_rxe >/dev/null 2>&1; then + echo "SKIP: Kernel module 'rdma_rxe' not found." >&2 + exit $KSFT_SKIP +fi + +modprobe rdma_rxe || { echo "Failed to load rdma_rxe"; exit 1; } + +# --- Setup Network Topology --- +echo "Setting up network namespace and veth pair..." +ip netns add "$NS" +ip link add "$VETH_A" type veth peer name "$VETH_B" +ip link set "$VETH_A" netns "$NS" + +# Configure Namespace side (test1) +ip netns exec "$NS" ip addr add "$IP_A/24" dev "$VETH_A" +ip netns exec "$NS" ip link set "$VETH_A" up +ip netns exec "$NS" ip link set lo up + +# Configure Host side +ip addr add "$IP_B/24" dev "$VETH_B" +ip link set "$VETH_B" up + +# --- RXE Link Creation --- +echo "Creating RDMA links..." +ip netns exec "$NS" rdma link add rxe0 type rxe netdev "$VETH_A" +rdma link add rxe1 type rxe netdev "$VETH_B" + +# Verify UDP 4791 is listening +check_port() { + local target=$1 # "host" or "ns" + if [ "$target" == "ns" ]; then + ip netns exec "$NS" ss -Huln sport == :$PORT | grep -q ":$PORT" + else + ss -Huln sport == :$PORT | grep -q ":$PORT" + fi +} + +check_port "ns" || { echo "Error: RXE port not listening in namespace"; exit 1; } +check_port "host" || { echo "Error: RXE port not listening on host"; exit 1; } + +# --- Connectivity Test --- +echo "Testing connectivity with rping..." +ping -c 2 -W 1 "$IP_A" > /dev/null || { echo "Ping failed"; exit 1; } + +# Start rping server in background +ip netns exec "$NS" rping -s -a "$IP_A" -v > /dev/null 2>&1 & +RPING_PID=$! +sleep 1 # Allow server to bind + +# Run rping client +rping -c -a "$IP_A" -d -v -C 3 +RESULT=$? + +kill $RPING_PID 2>/dev/null + +if [ $RESULT -eq 0 ]; then + echo "SUCCESS: RDMA traffic verified." +else + echo "FAILURE: rping failed." + exit 1 +fi diff --git a/tools/testing/selftests/rdma/rxe_sent_rcvd_bytes.sh b/tools/testing/selftests/rdma/rxe_sent_rcvd_bytes.sh new file mode 100755 index 000000000..0e4fbfeeb --- /dev/null +++ b/tools/testing/selftests/rdma/rxe_sent_rcvd_bytes.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# Configuration +PORT=4791 +MODS=("tun" "rdma_rxe") + +exec > /dev/null + +# --- Helper: Cleanup Routine --- +cleanup() { + echo "Cleaning up resources..." + rdma link del rxe0 2>/dev/null + ip link del tun0 2>/dev/null + for m in "${MODS[@]}"; do modprobe -r "$m" 2>/dev/null; done +} + +# Ensure cleanup runs on script exit or interrupt +trap cleanup EXIT + +# --- Phase 1: Environment Check --- +if [[ $EUID -ne 0 ]]; then + echo "Error: This script must be run as root." + exit 1 +fi + +for m in "${MODS[@]}"; do + modprobe "$m" || { echo "Error: Failed to load $m"; exit 1; } +done + +# --- Phase 2: Create Interfaces & RXE Links --- +echo "Creating tun0 (1.1.1.1) and rxe0..." +ip tuntap add mode tun tun0 +ip addr add 1.1.1.1/24 dev tun0 +ip link set tun0 up +rdma link add rxe0 type rxe netdev tun0 + +# Verify port 4791 is listening +if ! ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT not found after rxe0 creation" + exit 1 +fi + +orig_s=`cat /sys/class/infiniband/rxe0/ports/1/counters/port_xmit_data` +orig_r=`cat /sys/class/infiniband/rxe0/ports/1/counters/port_rcv_data` + +rping -s -a 1.1.1.1 -C 3 -v & +sleep 1 +rping -c -a 1.1.1.1 -C 3 -d -v + +new_s=`cat /sys/class/infiniband/rxe0/ports/1/counters/port_xmit_data` +new_r=`cat /sys/class/infiniband/rxe0/ports/1/counters/port_rcv_data` + +echo sent $new_s $orig_s +echo rcvd $new_r $orig_r + +result0=$((new_s - orig_s)) +result1=$((new_r - orig_r)) + +if [ $result0 != $result1 ]; then + echo "Error: sent and rcvd bytes different" + echo $result0 + echo $result1 + exit 1 +fi + +echo "Deleting rxe0..." +rdma link del rxe0 + +# Port should now be gone +if ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT still exists after all links deleted" + exit 1 +fi + +echo "Test passed successfully." diff --git a/tools/testing/selftests/rdma/rxe_socket_with_netns.sh b/tools/testing/selftests/rdma/rxe_socket_with_netns.sh new file mode 100755 index 000000000..9478657c0 --- /dev/null +++ b/tools/testing/selftests/rdma/rxe_socket_with_netns.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# Configuration +PORT=4791 +MODS=("tun" "rdma_rxe") + +source "$(dirname "$0")/../kselftest/ktap_helpers.sh" + +exec > /dev/null + +# --- Helper: Cleanup Routine --- +cleanup() { + echo "Cleaning up resources..." + rdma link del rxe1 2>/dev/null + rdma link del rxe0 2>/dev/null + ip link del tun0 2>/dev/null + ip link del tun1 2>/dev/null + for m in "${MODS[@]}"; do modprobe -r "$m" 2>/dev/null; done +} + +# Ensure cleanup runs on script exit or interrupt +trap cleanup EXIT + +# --- Phase 1: Environment Check --- +if [[ $EUID -ne 0 ]]; then + echo "Error: This script must be run as root." + exit 1 +fi + +for m in "${MODS[@]}"; do + if ! modinfo "$m" >/dev/null 2>&1; then + echo "SKIP: Kernel module '$m' not found." >&2 + exit $KSFT_SKIP + fi + modprobe "$m" || { echo "Error: Failed to load $m"; exit 1; } +done + +# --- Phase 2: Create Interfaces & RXE Links --- +echo "Creating tun0 (1.1.1.1) and rxe0..." +ip tuntap add mode tun tun0 +ip addr add 1.1.1.1/24 dev tun0 +ip link set tun0 up +rdma link add rxe0 type rxe netdev tun0 + +# Verify port 4791 is listening +if ! ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT not found after rxe0 creation" + exit 1 +fi + +echo "Creating tun1 (2.2.2.2) and rxe1..." +ip tuntap add mode tun tun1 +ip addr add 2.2.2.2/24 dev tun1 +ip link set tun1 up +rdma link add rxe1 type rxe netdev tun1 + +# Verify port 4791 is still listening +if ! ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT missing after rxe1 creation" + exit 1 +fi + +# --- Phase 3: Targeted Deletion --- +echo "Deleting rxe1..." +rdma link del rxe1 + +# Port should still be active because rxe0 is still alive +if ! ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT closed prematurely" + exit 1 +fi + +echo "Deleting rxe0..." +rdma link del rxe0 + +# Port should now be gone +if ss -Huln sport = :$PORT | grep -q ":$PORT"; then + echo "Error: UDP port $PORT still exists after all links deleted" + exit 1 +fi + +echo "Test passed successfully." diff --git a/tools/testing/selftests/rdma/rxe_test_NETDEV_UNREGISTER.sh b/tools/testing/selftests/rdma/rxe_test_NETDEV_UNREGISTER.sh new file mode 100755 index 000000000..8c18cea75 --- /dev/null +++ b/tools/testing/selftests/rdma/rxe_test_NETDEV_UNREGISTER.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Configuration +DEV_NAME="tun0" +RXE_NAME="rxe0" +RDMA_PORT=4791 + +source "$(dirname "$0")/../kselftest/ktap_helpers.sh" + +exec > /dev/null + +# --- Cleanup Routine --- +# Ensures environment is clean even if the script hits an error +cleanup() { + echo "Performing cleanup..." + rdma link del $RXE_NAME 2>/dev/null + ip link del $DEV_NAME 2>/dev/null + modprobe -r rdma_rxe 2>/dev/null +} +trap cleanup EXIT + +# 1. Dependency Check +if ! modinfo rdma_rxe >/dev/null 2>&1; then + echo "SKIP: rdma_rxe module not found." >&2 + exit $KSFT_SKIP +fi + +modprobe rdma_rxe + +# 2. Setup TUN Device +echo "Creating $DEV_NAME..." +ip tuntap add mode tun "$DEV_NAME" +ip addr add 1.1.1.1/24 dev "$DEV_NAME" +ip link set "$DEV_NAME" up + +# 3. Attach RXE Link +echo "Attaching RXE link $RXE_NAME to $DEV_NAME..." +rdma link add "$RXE_NAME" type rxe netdev "$DEV_NAME" + +# 4. Verification: Port Check +# Use -H (no header) and -q (quiet) for cleaner scripting logic +if ! ss -Huln sport == :$RDMA_PORT | grep -q ":$RDMA_PORT"; then + echo "Error: UDP port $RDMA_PORT is not listening." + exit 1 +fi +echo "Verified: RXE is listening on UDP $RDMA_PORT." + +# 5. Trigger NETDEV_UNREGISTER +# We delete the underlying device without deleting the RDMA link first. +echo "Triggering NETDEV_UNREGISTER by deleting $DEV_NAME..." +ip link del "$DEV_NAME" + +# 6. Final Verification +# The RXE link and the UDP port should be automatically cleaned up by the kernel. +if rdma link show "$RXE_NAME" 2>/dev/null; then + echo "Error: $RXE_NAME still exists after netdev removal." + exit 1 +fi + +if ss -Huln sport == :$RDMA_PORT | grep -q ":$RDMA_PORT"; then + echo "Error: UDP port $RDMA_PORT still listening after netdev removal." + exit 1 +fi + +echo "Success: NETDEV_UNREGISTER handled correctly." -- cgit v1.3.1