Netdev List
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Feng Tang <feng.tang@linux.alibaba.com>,
	Simon Horman <horms@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Sasha Levin <sashal@kernel.org>,
	davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
	shuah@kernel.org, netdev@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-6.1] selftests: net: reuseport_bpf_numa: consider cpuless numa node
Date: Mon, 19 Oct 2026 09:45:06 -0400	[thread overview]
Message-ID: <20261019135441.1420968-15-sashal@kernel.org> (raw)
In-Reply-To: <20261019135441.1420968-1-sashal@kernel.org>

From: Feng Tang <feng.tang@linux.alibaba.com>

[ Upstream commit 88b8d85e889e2fe1cce3e66e50c3029dda94842a ]

reuseport_bpf_numa case failed when testing on a platform with CXL
memory:

    #./reuseport_bpf_numa
    ---- IPv4 UDP ----
    send node 0, receive socket 0
    ./reuseport_bpf_numa: failed to pin to node: Invalid argument

The root cause is that the platform has 2 numa nodes: node 0 has
both cpu and memory, while node 1 is a CXL node which only has
memory, and caused numa_run_on_node() to fail.

Add sanity check to skip cpuless numa node for the numa binding test.

Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260807002436.43991-1-feng.tang@linux.alibaba.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
- Record: `[selftests: net]` `[consider]` skip CPU-less NUMA nodes in
  `reuseport_bpf_numa` so the test does not abort when
  `numa_run_on_node()` cannot pin to a memory-only node.

**Step 1.2: Tags**
- Record: `Reviewed-by: Simon Horman <horms@kernel.org>`; `Link: https:/
  /patch.msgid.link/20260807002436.43991-1-feng.tang@linux.alibaba.com`;
  `Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>`; `Signed-off-
  by: Paolo Abeni <pabeni@redhat.com>`.
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Cc: stable`
  (absence is expected). Ignore any pipeline `Signed-off-by: Sasha
  Levin` / `[Upstream commit ...]` markers.

**Step 1.3: Body**
- Record: On a 2-node CXL box, node 0 has CPU+memory and node 1 is
  memory-only. The test prints `send node 0, receive socket 0` then dies
  with `failed to pin to node: Invalid argument` from
  `numa_run_on_node()`. Root cause is treating every bit in
  `numa_nodes_ptr` as a pin-able CPU node. Fix: skip CPU-less nodes.

**Step 1.4: Hidden bug fix?**
- Record: Yes. “Consider” is test-robustness language, but the program
  currently `error(1, ...)` and fails. This is a real false failure, not
  style cleanup.

## Phase 2: Diff analysis

**Step 2.1: Inventory**
- Record: One file, `tools/testing/selftests/net/reuseport_bpf_numa.c`.
  About +24 lines. New helper `is_cpuless_node()`; `test()` gains two
  `continue`s. Surgical, single-file, userspace selftest only.

**Step 2.2: Flow**
- Record: Before: both forward and reverse loops skip only nodes unset
  in `numa_nodes_ptr`, then call `send_from_node()` which does
  `numa_run_on_node()` and aborts on failure. After: also skip nodes
  whose libnuma CPU mask has weight 0. Normal send/receive path for CPU-
  bearing nodes is unchanged.

**Step 2.3: Bug mechanism**
- Record: Logic/correctness in a selftest. Memory-only NUMA nodes are
  present in `numa_nodes_ptr` (the 2021 skip does not drop them) but
  have an empty CPU mask, so pinning returns EINVAL. `is_cpuless_node()`
  uses `numa_allocate_cpumask()` / `numa_node_to_cpus()` /
  `numa_bitmask_weight()`; on helper error it returns false (do not
  skip), which is conservative.

**Step 2.4: Fix quality**
- Record: Obviously correct and minimal. Skipping a CPU-less node is
  right: `bpf_get_numa_node_id()` is the current CPU’s node, so a
  memory-only node can never be the sender. Regression risk is very low
  (userspace test only). Helper allocation failure still hits the old
  abort path.

## Phase 3: Git history

**Step 3.1: Blame**
- Record: Loops come from `3c2c3c16aaf6a` (Daniel Borkmann, 2016-10-21,
  “reuseport, bpf: add test case for bpf_get_numa_node_id”), first
  contained in v4.10-rc1. The existing skip is `a38bc45a08e97` (Kleber
  Sacilotto de Souza, 2021-11-01), contained in v5.16-rc1: skip nodes
  not in `numa_nodes_ptr` (non-consecutive IDs). That does not cover
  CPU-less memory nodes.

**Step 3.2: Fixes: tag**
- Record: None. Buggy assumption is in the original 2016 test, still
  present here.

**Step 3.3: File history**
- Record: This tree only has later `0273d10182ec4` (ARRAY_SIZE warning),
  then the 2021 skip, 2018 numa-skip-if-unavailable, SPDX, and the
  original test. No `setup_netns()` in this file (0 matches).
  Standalone; not patch X/Y.

**Step 3.4: Author**
- Record: Feng Tang has other tools/selftests work in this history (e.g.
  mm `compaction_test`) but no other net `reuseport_bpf_numa` commits.
  Not the net maintainer. Applied by Paolo Abeni after Simon Horman’s
  review.

**Step 3.5: Prerequisites**
- Record: Needs existing libnuma usage (`numa_nodes_ptr`,
  `numa_run_on_node`, `-lnuma`). All present. Makefile already has
  `$(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma`. No missing kernel
  APIs. Can apply standalone.

## Phase 4: Mailing list / external

**Step 4.1: Original discussion**
- Record: `b4 mbox` for msgid
  `20260807002436.43991-1-feng.tang@linux.alibaba.com` returned 404;
  lore.kernel.org fetches returned 403. Recovered from
  Openwall/LKML/Patchew.
- v1 (`20260730113040.75718-1-...`): check inside `send_from_node()`,
  return -1, no NULL check on `numa_allocate_cpumask()`.
- v2 (`[PATCH net v2]`): lift check into `test()`, add alloc-failure
  handling; typo “unlikeyly”; unnecessary `inline`.
- v3 (`[PATCH net-next v3]`): spelling + drop `inline` (Jakub, Sashiko).
  Committed version matches v3.
- No NAKs. No reviewer `Cc: stable` found.

**Step 4.2: Reviewers**
- Record: To/Cc included Jakub Kicinski, David Miller, Eric Dumazet,
  Paolo Abeni, Simon Horman, Shuah Khan, Andi Kleen, netdev, linux-
  kselftest, bpf. Jakub reviewed v2 (inline). Simon Horman `Reviewed-by`
  on v3. Paolo applied.

**Step 4.3: Bug report**
- Record: Author reproduced on CXL hardware; commit body has the exact
  abort. No syzbot/bugzilla. Severity for testers: hard FAIL after the
  first successful node-0 send.

**Step 4.4: Series**
- Record: Single patch, three revisions. No sibling patches required.

**Step 4.5: Stable list**
- Record: No stable-list hit found. UNVERIFIED that nobody asked for it
  on stable@ (lore 403).

## Phase 5: Semantic analysis

**Step 5.1: Functions**
- Record: Adds `is_cpuless_node()`. Touches `test()`. `send_from_node()`
  unchanged.

**Step 5.2: Callers**
- Record: `is_cpuless_node` only from `test()`. `test()` only from
  `main()` (IPv4/IPv6 × UDP/TCP). Userspace kselftest, not kernel.

**Step 5.3: Callees**
- Record: libnuma `numa_allocate_cpumask`, `numa_node_to_cpus`,
  `numa_bitmask_weight`, `numa_bitmask_free`. Already linked with
  `-lnuma`.

**Step 5.4: Reachability**
- Record: Triggered by running `./reuseport_bpf_numa` on NUMA
  (`CONFIG_NUMA=y` in `tools/testing/selftests/net/config`) with at
  least one CPU-less node. Not a syscall/kernel path.

**Step 5.5: Similar patterns**
- Record: Same file already skips unavailable nodes (`a38bc45a08e97`).
  This is the CPU-less counterpart. No other `numa_run_on_node`
  selftests in this tree.

## Phase 6: This tree (6.12.111)

**Step 6.1: Buggy code present?**
- Record: Yes. Local tree is `pending-6.12` / `p-6.12-3-gc504cf0baa3d8`,
  `make kernelversion` = **6.12.111**. File has the 2016 loops and the
  2021 `numa_nodes_ptr` skip, and still calls `send_from_node()` without
  a CPU-less check (`git merge-base --is-ancestor` for both historical
  commits succeeded). `git log --grep="consider cpuless"` on this file
  is empty. CXL is in this tree (`drivers/cxl/`).

**Step 6.2: Backport difficulty**
- Record: Clean apply. The three functional contexts exist verbatim
  (helper insertion after `attach_bpf()`, two loop sites). Mainline
  trailing `setup_netns()` context is **not** in 6.12 and is not part of
  the v3 hunks. `bool` is already used in other net selftests here
  without extra headers.

**Step 6.3: Related fixes already here?**
- Record: Only the 2021 unavailable-node skip. It does not fix CXL
  memory-only nodes. No equivalent `is_cpuless_node` fix.

## Phase 7: Subsystem context

**Step 7.1:** Record: `tools/testing/selftests/net` — kselftest for
SO_REUSEPORT + `bpf_get_numa_node_id`. Criticality: PERIPHERAL for
production runtime; IMPORTANT for people who run net kselftests (this
6.12.y tree already took ~100 `tools/testing/selftests/net` commits
since `v6.12`).

**Step 7.2:** Record: Net selftests are actively backported here (UAF in
tests, br_netfilter false failures, HZ=100 skips, portable timeouts,
etc.).

## Phase 8: Impact and risk

**Step 8.1:** Record: Testers running this binary on NUMA machines with
CPU-less nodes (CXL memory, similar memory-only nodes). Not a production
kernel path.

**Step 8.2:** Record: Trigger is running the selftest on that topology.
First CPU node can succeed; the next CPU-less node aborts. Unprivileged
if the test is run that way; not a kernel exploit path.

**Step 8.3:** Record: Failure mode = kselftest abort (`error(1, errno,
"failed to pin to node")`). Severity LOW–MEDIUM for the kernel (no
oops/corruption), HIGH for CI on those machines (hard fail).

**Step 8.4:** Record: Benefit medium for CXL/NUMA testers of 6.12.y;
risk very low (userspace, +24 lines, no kernel change). Ratio favors
backport on this tree, which already takes kselftest false-fail fixes.

## Phase 9: Synthesis

**For**
- Real, reproduced FAIL on CXL memory-only NUMA; 6.12 has both the test
  and CXL.
- Completes the 2021 skip: `numa_nodes_ptr` still includes CPU-less
  nodes.
- Small, reviewed, v3 is the applied form; no series deps.
- Applies cleanly here; zero kernel runtime risk.
- This tree regularly backports the same class (e.g. `selftests:
  netfilter: packetdrill: avoid failure on HZ=100 kernel`,
  vxlan/br_netfilter false-fail fixes).
- v2 was sent to `net` as a bugfix.

**Against**
- Not a kernel crash, security hole, or data-corruption fix.
- Affects one selftest on a subset of NUMA topologies.
- Final submission was `net-next`; no `Cc: stable` in the thread I could
  read.

**Unresolved**
- Exact mainline SHA (not on this branch).
- lore.kernel.org / `b4` thread dump (403/404).
- Whether stable@ ever discussed it.

**Stable rules checklist**
1. Obviously correct and tested? **PASS** (libnuma weight 0; Reviewed-by
   Horman; author reproduced).
2. Real bug that bothers people? **PASS** (hard selftest FAIL on real
   CXL hardware).
3. Important (crash/security/corruption/deadlock)? **PASS** under this
   tree’s documented “oh, that’s not good” / kselftest-false-fail
   practice; not a production oops.
4. Small and contained? **PASS** (~24 lines, one file).
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **PASS** (contexts verified).

**Exception category:** none of ID/quirk/DT/build/docs; it is a
kselftest correctness/robustness fix, which this 6.12.y tree already
accepts.

The test in 6.12.111 still assumes every exposed NUMA node has CPUs.
That is false on CXL memory-only nodes, so `reuseport_bpf_numa` aborts.
The patch only skips those nodes and does not change kernel behavior.
That is a contained, low-risk fix worth taking on this tree.

### Verification
- [Phase 1] Parsed tags: Reviewed-by Simon Horman; Link msgid; SOBs Feng
  Tang / Paolo Abeni; no Fixes/Reported-by/Cc:stable.
- [Phase 2] Diff: +24 lines, `is_cpuless_node()` + two `continue`s in
  `test()`; `send_from_node()` still `error(1)` on pin failure.
- [Phase 3] `git blame` loops: `3c2c3c16aaf6a` (2016) and
  `a38bc45a08e97` (2021 skip). Both are ancestors of HEAD.
- [Phase 3] `git describe --contains`: original test v4.10-rc1; 2021
  skip v5.16-rc1.
- [Phase 3] `git log --grep="consider cpuless"` on this file: empty (fix
  not in tree).
- [Phase 4] `b4 mbox` msgid: 404; lore WebFetch: 403; used
  Openwall/LKML/Patchew for v1–v3.
- [Phase 4] v1→v3: Sashiko NULL-check; lift skip out of
  `send_from_node`; Jakub spelling/`inline`; Horman Reviewed-by; no NAK.
- [Phase 5] Callers: `main` → `test` → `send_from_node`; userspace only.
  `grep numa_run_on_node` only this file under selftests.
- [Phase 6] `git describe HEAD` / `make kernelversion`: pending-6.12,
  6.12.111. File matches patch contexts (`hunk1 present`, two loop
  sites). No `setup_netns`. `drivers/cxl/` present. `CONFIG_NUMA=y` in
  net selftest config. `-lnuma` already in Makefile.
- [Phase 6] `v6.12..HEAD -- tools/testing/selftests/net/`: 100 commits,
  including false-fail/skip fixes.
- [Phase 8] Failure: selftest abort `failed to pin to node: Invalid
  argument`; not a kernel oops.
- UNVERIFIED: lore.kernel.org full thread; stable@ discussion; mainline
  SHA.

**YES**

 .../selftests/net/reuseport_bpf_numa.c        | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/tools/testing/selftests/net/reuseport_bpf_numa.c b/tools/testing/selftests/net/reuseport_bpf_numa.c
index c9ba36aa688e2..b04b511809ad2 100644
--- a/tools/testing/selftests/net/reuseport_bpf_numa.c
+++ b/tools/testing/selftests/net/reuseport_bpf_numa.c
@@ -104,6 +104,26 @@ static void attach_bpf(int fd)
 	close(bpf_fd);
 }
 
+/*
+ * Return true if it is a cpuless node. Return false if it isn't or any
+ * error (very unlikely) happens during the libnuma calls.
+ */
+static bool is_cpuless_node(int node_id)
+{
+	struct bitmask *cpumask;
+	bool ret = false;
+
+	cpumask = numa_allocate_cpumask();
+	if (!cpumask)
+		return ret;
+
+	if (!numa_node_to_cpus(node_id, cpumask) && !numa_bitmask_weight(cpumask))
+		ret = true;
+
+	numa_bitmask_free(cpumask);
+	return ret;
+}
+
 static void send_from_node(int node_id, int family, int proto)
 {
 	struct sockaddr_storage saddr, daddr;
@@ -213,6 +233,8 @@ static void test(int *rcv_fd, int len, int family, int proto)
 	for (node = 0; node < len; ++node) {
 		if (!numa_bitmask_isbitset(numa_nodes_ptr, node))
 			continue;
+		if (is_cpuless_node(node))
+			continue;
 		send_from_node(node, family, proto);
 		receive_on_node(rcv_fd, len, epfd, node, proto);
 	}
@@ -221,6 +243,8 @@ static void test(int *rcv_fd, int len, int family, int proto)
 	for (node = len - 1; node >= 0; --node) {
 		if (!numa_bitmask_isbitset(numa_nodes_ptr, node))
 			continue;
+		if (is_cpuless_node(node))
+			continue;
 		send_from_node(node, family, proto);
 		receive_on_node(rcv_fd, len, epfd, node, proto);
 	}
-- 
2.53.0


  parent reply	other threads:[~2026-10-19 13:55 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 13:44 [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check CORE_PLL_GROUP4 access in mt7531_setup() Sasha Levin
2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context Sasha Levin
2026-10-19 13:45 ` Sasha Levin [this message]
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.1] net: stmmac: fix device node reference leaks in stmmac_mtl_setup() Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] netfilter: conntrack: tcp: use UNACK timeout for non-closing RST packets Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add Rolling Wireless RN947R Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] net: usb: rtl8150: handle link status read failures Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] net: prestera: ignore duplicate RIF destruction events Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net: dsa: mt7530: error out on failed PHY_IAC command writes Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.6] tap: fix incorrect variable used for USO check in set_offload() Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] net: dsa: mt7530: check bus->read() error in core_rmw() Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock() Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] netpoll: do not warn when the best-effort pool refill fails Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18] net: libwx: disable TX VLAN offload for packets with >2 VLAN tags Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] net: sfp: add quirk for HORACO copper SFP+ module Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.15] net: usb: cdc_ether: add quirk for AMI BMC stale link events Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] sctp: auth: propagate HMAC calculation errors to callers Sasha Levin
2026-10-19 17:28   ` Eric Biggers
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] selftests/net: fin_ack_lat: fix latency threshold typo Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] netfilter: ebtables: bound num_counters like nentries in do_replace() Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.6] xsk: account ring allocations to memcg Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] net: mvneta_bm: add suspend/resume support to prevent crash after resume Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] net: stmmac: use dma_addr_t for DMA addresses Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.12] gre: fix ERSPAN o_flags race/corruption in xmit and fill_info Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] netfilter: nf_tables: call skb_valid_dst() before skb_dst() Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.15] net: stmmac: raise TX completion interrupt at the end of an xmit burst Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.6] net: pcs: mtk-lynxi: check regmap reads in mtk_pcs_lynxi_get_state() Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] sfc: add X4D PF support Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.1] netfilter: tproxy: use DEBUG_NET_WARN_ON_ONCE for protocol fallbacks Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-6.12] net: ethernet: mtk_wed: increase WED v2 WDMA RESV_BUFF to 0x80 Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261019135441.1420968-15-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=feng.tang@linux.alibaba.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=patches@lists.linux.dev \
    --cc=shuah@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox