Repository navigation
[26.04_linux-nvidia] veth: set the real number of queues before registering the devices - #696 - #697
JiandiAnNVIDIA wants to merge 2 commits into
Conversation
BaseOS Kernel ReviewTip ✅ Review passedNo issues found across the reviewed commits. Findings: none 🔍 Review artifacts
📦 Build checks — 🟢 4/4 passed
Install the PR kernel with APTPublished for reviewed head curl -fsS https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/install.sh | bash -s -- install pr-697Manual setup · signing fingerprint Manual commands for Ubuntu 24.04 Noble / amd64, on the NVIDIA network: (
set -euo pipefail
work=$(mktemp -d)
trap 'rm -rf -- "$work"' EXIT
curl -qfsS --proto '=https' -o "$work/archive-keyring.gpg" https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/archive-keyring.gpg
curl -qfsS --proto '=https' -o "$work/baseos-internal-tools.crt" https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/baseos-internal-tools.crt
sudo install -d -m 0755 /etc/apt/keyrings
sudo install -m 0644 "$work/archive-keyring.gpg" /usr/share/keyrings/baseos-pr-kernels.gpg
sudo install -m 0644 "$work/baseos-internal-tools.crt" /etc/apt/keyrings/baseos-pr-https.crt
printf '%s\n' \
'Acquire::https::baseos-internal-tools.nvidia.com::CaInfo "/etc/apt/keyrings/baseos-pr-https.crt";' \
'Acquire::https::baseos-internal-tools.nvidia.com::Verify-Peer "true";' \
'Acquire::https::baseos-internal-tools.nvidia.com::Verify-Host "true";' | \
sudo tee /etc/apt/apt.conf.d/90baseos-pr-kernels >/dev/null
printf '%s\n' 'deb [arch=amd64 signed-by=/usr/share/keyrings/baseos-pr-kernels.gpg] https://baseos-internal-tools.nvidia.com:4001/reviews/apt/NVIDIA/NV-Kernels/697/noble/amd64 noble main' | \
sudo tee /etc/apt/sources.list.d/nv-kernels-pr697.list >/dev/null
sudo apt update --error-on=any
sudo apt install --no-remove nv-kernels-pr-697
)The repository remains configured. Later Note Build reports and debs are retained for 10 days after the PR closes.
Review metadata
This comment is maintained by BaseOS Reviewer and updated when the GitHub watcher publishes a newer review. |
PR Validation ReportPatchscan ✅ No Missing FixesAll cherry-picked commits checked — no missing upstream fixes found. PR Lint ❌ Errors foundDetailsChecking 2 commits...
Cherry-pick digest:
E: 67f8106eba0a ("veth: decide peer queue count from the p"): patch-ID mismatch with upstream 267bc3f113d8
┌──────────────┬──────────────────────────────────────────────────────────────────┬────────────┬─────────┬───────────────────────────┐
│ Local │ Referenced upstream / Patch subject │ Patch-ID │ Subject │ SoB chain │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 30af1de94314 │ veth: set the real number of queues before registering the devic │ noted │ found │ ok, backporter: jan │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 67f8106eba0a │ 267bc3f113d8 veth: decide peer queue count from the peer's own a │ MISMATCH │ match │ preserved + jan added │
└──────────────┴──────────────────────────────────────────────────────────────────┴────────────┴─────────┴───────────────────────────┘
Lint: all checks passed.
|
veth_newlink() creates the peer netdev from tbp, which points at the
nested VETH_INFO_PEER attributes when they are supplied (peer_tb) and
only aliases the primary device's tb otherwise. However the queue
reduction is gated on the primary device's attributes:
err = veth_init_queues(peer, tb);
veth_init_queues() checks !tb[IFLA_NUM_{TX,RX}_QUEUES], so for the peer
it inspects the wrong attribute set whenever nested peer attributes are
used:
- If the user requests IFLA_NUM_TX/RX_QUEUES only for the peer, tb
carries no such attribute and veth_init_queues() still shrinks the
peer's real_num_{tx,rx}_queues back to 1, silently dropping the
user's explicit multi-queue request for the peer.
- If the user requests the counts only for the primary device, the
peer keeps nr_possible_cpus real queues instead of the legacy
default of 1.
Pass tbp so the peer's queue count is decided from the peer's own
attributes. When no nested peer attributes are given tbp aliases tb, so
the common case is unchanged.
Cc: stable+noautosel@kernel.org # never worked, high regression risk
Fixes: 9d3684c ("veth: create by default nr_possible_cpus queues")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Link: https://patch.msgid.link/20261014013620.2497-1-lirongqing@baidu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(backported from commit 267bc3f)
[jan: context has no netdev_hold() peer tracker in this tree]
Signed-off-by: Jiandi An <jan@nvidia.com>
… the devices Since commit 9d3684c ("veth: create by default nr_possible_cpus queues"), each veth device is allocated with one rx and one tx queue per possible CPU, and veth_newlink() reduces the real number of queues to one unless the user asked for a number. Both devices are already registered at that point, so netif_set_real_num_tx_queues() and netif_set_real_num_rx_queues() remove the sysfs objects of every extra queue that register_netdevice() has just created, each one emitting an add and a remove uevent, and the tx side also waits for an expedited RCU grace period. This happens with RTNL held, twice per pair, and grows with the number of possible CPUs: with 240 of them a veth pair emits about 1900 uevents, and udev processing them slows down later sysfs work such as deleting devices. Set the number of queues before registering each device. For a device that is not registered yet this only updates the counters, so the extra queues never appear in sysfs, and the error paths that undid a registration are no longer needed. Creating and then deleting 500 veth pairs, one ip -batch each, in a 16 vCPU guest, median of 3 runs, per pair: before after 16 possible CPUs create 1644 us 520 us delete 11822 us 9750 us 240 possible CPUs create 17253 us 1339 us delete 17082 us 9941 us uevents 1918 6 Signed-off-by: Qiliang Yuan <odys.yuan@gmail.com> Reviewed-by: Wang Zhan <wang.zhan@smartx.com> Tested-by: Wang Zhan <wang.zhan@smartx.com> (backported from https://lore.kernel.org/netdev/20261016-bug-veth-init-queues-before-register-v1-1-f48eb2bb25a0@gmail.com/) [jan: no netdev_hold() peer tracker in this tree, so one error label; peer call keeps tbp] Signed-off-by: Jiandi An <jan@nvidia.com>
b96a116 to
30af1de
Compare
|
|
|
|
|
|
|
|
Problem
Container churn on NVIDIA Vera is roughly 5x slower with udev running than with it
stopped. On a 352-CPU NVL72 node, throughput is capped at 3,100-3,850 container
cycles/h from 8 concurrent containers upward and does not improve with more
load; stopping
systemd-udevdraises it to 14,000-19,500. Across the loadedconcurrency levels the penalty is +276% to +514%. Kernel CPU sits at 19.9-26.0%
while user CPU is ~1%, so the machine is mostly idle while delivering a fifth
of its achievable throughput.
Root cause
Docker's default bridge networking creates a veth pair per container, and its
netlink library sets neither
IFLA_NUM_TX_QUEUESnorIFLA_NUM_RX_QUEUES. Inthat case veth allocates one rx and one tx queue per possible CPU and then
reduces the real count to one — but
veth_newlink()does the reduction afterregister_netdevice():register_queue_kobjects()publishes sysfs objects forreal_num_rx_queuesandreal_num_tx_queues, so every queue it just created is destroyed again a momentlater, each creation and destruction emitting a uevent. On this node that is
2816 uevents on the
queuessubsystem per veth pair — 704 adds plus 702immediate removals per device, times two devices, plus 2 removals at delete.
udev's 720 workers then contend on the per-kernfs-root semaphores while
processing them, which throttles all subsequent sysfs activity on the host.
The cost scales with
num_possible_cpus(), which is why this node is hit harderthan the 176-CPU node in the original report.
Fix
Set the real queue counts before registering each device. For a device that
is not yet registered,
netif_set_real_num_tx_queues()andnetif_set_real_num_rx_queues()only assign the counter — they skip all kobjectwork and the expedited RCU grace period the tx path otherwise takes — so the
extra queues never appear in sysfs at all, and the error label that unwound a
registration is no longer needed.
Two commits:
veth: decide peer queue count from the peer's own attributes267bc3f113d8c441f57014c502443686f5d33d57, in v7.4-rc1NVIDIA: SAUCE: veth: set the real number of queues before registering the devicesBoth are context-adjusted for this tree, which predates the
netdev_hold()peertracker in
veth_newlink()and therefore has one error label where upstream hastwo.
Verification
Measured on a Vera NVL72 node: 2 sockets x 88 cores x 2 threads = 352 logical
CPUs, 64k pages, Ubuntu 26.04, udev 259.5-0ubuntu3.4 with the default 720
workers, Docker 29.7.2 on the default bridge.
Uevents per veth pair
queuesaddsqueuesremovesA 352x reduction, exactly
num_possible_cpus(). No removals occur duringcreation at all — the storm does not happen rather than being made cheaper.
200 veth pairs created and deleted, no Docker
udevadm settle)Deletion is unaffected, as upstream's own numbers also show; this fixes
creation.
Container churn, cycles/h, two runs per kernel
The udev penalty goes from +276%..+514% to −9%..+6%, straddling zero in both
patched runs. Kernel CPU with udev running drops from 19.9–26.0% to 0.6–7.9%.
Mean container cycle time at 32 concurrent containers goes from 30.75–33.01 s
to 7.52–7.81 s.
Profile — udev workers account for 0.96% of cycles on the patched kernel,
and
rwsem_read_trylockplusup_readtogether total ~0.45% across allprocesses.
No functional change —
ethtool -lon a freshly created veth still reportspre-set maximums of 352 RX and 352 TX with current settings of 1, so
num_tx_queuesremainsnr_possible_cpus()andethtool -Lheadroom ispreserved. Container networking verified working.
LP: https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-bos/+bug/2173592
NvBug: https://nvbugspro.nvidia.com/bug/6962526