* [PATCH AUTOSEL 6.18-6.1] eth: mlx5: fix macsec dependency
[not found] <20260831133314.4125787-1-sashal@kernel.org>
@ 2026-08-31 13:21 ` Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18] RDMA/umem: Make ib_umem_is_contiguous() safe on 32 bit Sasha Levin
` (16 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Arnd Bergmann, Sabrina Dubroca, Jakub Kicinski, Sasha Levin,
saeedm, tariqt, mbloch, andrew+netdev, davem, edumazet, pabeni,
netdev, linux-rdma, linux-kernel
From: Arnd Bergmann <arnd@arndb.de>
[ Upstream commit 87ab8276ed24d688febfef4d0c1794896e778192 ]
Configurations with mlx5 built-in but macsec=m fail to link:
x86_64-linux-ld: drivers/infiniband/hw/mlx5/macsec.o: in function `mlx5r_add_gid_macsec_operations':
macsec.c:(.text+0x77d): undefined reference to `macsec_netdev_is_offloaded'
x86_64-linux-ld: drivers/infiniband/hw/mlx5/macsec.o: in function `mlx5r_del_gid_macsec_operations':
macsec.c:(.text+0xe81): undefined reference to `macsec_netdev_is_offloaded'
Fix the dependency so this configuration cannot happen.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/20260622124229.2444502-1-arnd@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `eth: mlx5: fix macsec dependency`
**Local tree:** Linux **6.18.44** (`git describe HEAD` →
`v6.18.44-1-g2736c32da98b9`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject Line
**Record:** `[eth: mlx5]` `[fix]` — Correct a Kconfig dependency for
mlx5 MACsec offload so invalid build configurations cannot be selected.
### Step 1.2: Tags
**Record:**
- **Signed-off-by:** Arnd Bergmann `<arnd@arndb.de>` (author)
- **Reviewed-by:** Sabrina Dubroca `<sd@queasysnail.net>`
- **Link:**
https://patch.msgid.link/20260622124229.2444502-1-arnd@kernel.org
- **Signed-off-by:** Jakub Kicinski `<kuba@kernel.org>` (net maintainer
merge)
- No `Fixes:`, `Reported-by:`, `Cc: stable@vger.kernel.org`, or `Tested-
by:` tags
- Notable: Reviewed by a netdev reviewer; merged by net maintainer. No
syzbot report.
### Step 1.3: Body Analysis
**Record:**
- **Bug:** Kernel configurations with `MLX5_CORE=y` (built-in) and
`MACSEC=m` (module) can enable `MLX5_MACSEC=y`, but linking fails with
undefined references to `macsec_netdev_is_offloaded` from
`drivers/infiniband/hw/mlx5/macsec.c`.
- **Symptom:** Link-time failure (`undefined reference to
'macsec_netdev_is_offloaded'`) during kernel build — not a runtime
crash.
- **Root cause:** `MLX5_MACSEC` depends only on `MACSEC` (any tristate
value), which does not prevent built-in mlx5 from referencing symbols
exported only by a modular MACsec driver.
- **Author note (from lore):** Bug likely old; first noticed on
`next-20260615`; rare in randconfig due to other dependency
constraints.
### Step 1.4: Hidden Bug Fix?
**Record:** No — this is an explicit build-fix, not disguised cleanup.
Same class of fix Arnd has done before for mlx5 (TLS, psample).
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **Files:** `drivers/net/ethernet/mellanox/mlx5/core/Kconfig` — 1 line
changed (+1/-1)
- **Functions modified:** None (Kconfig only)
- **Scope:** Single-file, surgical Kconfig fix
### Step 2.2: Code Flow Change
**Record:**
- **Before:** `MLX5_MACSEC` selectable whenever `MACSEC` is enabled at
any tristate value (`y` or `m`), even when `MLX5_CORE=y` and
`MACSEC=m`.
- **After:** `MLX5_MACSEC` only selectable when `MACSEC=y` (built-in) OR
`MACSEC=MLX5_CORE` (MACsec built as module only when mlx5 core is also
a module).
- **Affected path:** Kconfig resolution at build configuration time;
prevents a configuration that cannot link.
### Step 2.3: Bug Mechanism
**Record:** **Build/configuration bug (h).** Built-in mlx5
(`MLX5_CORE=y`) links `macsec.o` into `mlx5_ib` when
`CONFIG_MLX5_MACSEC=y`, calling `macsec_netdev_is_offloaded()` from
`drivers/net/macsec.c`. With `MACSEC=m`, that symbol lives in a loadable
module and is unavailable at link time for built-in code.
### Step 2.4: Fix Quality
**Record:**
- **Obviously correct:** Yes — mirrors the established mlx5 pattern used
for TLS (`TLS=y || MLX5_CORE=m` at line 162) and psample (`PSAMPLE=y
|| PSAMPLE=n || MLX5_CORE=m` at line 115).
- **Minimal:** One-line change, no unrelated edits.
- **Regression risk:** Very low — only removes an invalid Kconfig
combination; does not change runtime behavior for configurations that
already built successfully.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:**
- `depends on MACSEC` introduced by **8ff0ac5be14469** (Lior Nahmanson,
2022-09-05) — `net/mlx5: Add MACsec offload Tx command support`
- `config MLX5_MACSEC` symbol added by **7390762a07374** (Patrisious
Haddad, 2022-11-29)
- RoCE MACsec code calling `macsec_netdev_is_offloaded()` added in
**758ce14aee825** (2022-05-03) and expanded in **58dbd6428a681**
(2023-04-13)
- `macsec_netdev_is_offloaded()` itself added in **f132fdd9dc81e**
(2023-08-20)
- Bug has been latent since RoCE MACsec started referencing the MACsec
core symbol with insufficient Kconfig constraints
### Step 3.2: Fixes: Tag
**Record:** N/A — no `Fixes:` tag in commit message.
### Step 3.3: Related File History
**Record:**
- **c3cd281e2bc8d** (2018): `net/mlx5e: fix TLS dependency` — identical
class of fix by same author
- **7a7dd5114f538** (2021): `mlx5: fix psample_sample_packet link error`
— same author, same Kconfig file
- **96c34151d1577** (2020): mlx5 Kconfig weak-dependency conversion
after kconfig `imply` semantics change
- Standalone one-patch fix, not part of a series
### Step 3.4: Author Context
**Record:** Arnd Bergmann is a long-standing contributor who routinely
fixes Kconfig/link-dependency issues across the kernel. Multiple prior
mlx5 Kconfig fixes from him are already in this tree.
### Step 3.5: Dependencies
**Record:** No prerequisite commits. Uses `MACSEC=MLX5_CORE` Kconfig
symbol-equality syntax, which is already present elsewhere in this
6.18.44 tree (e.g., `BACKLIGHT_CLASS_DEVICE=FB_RIVA`,
`HID=SND_SOC_SDCA`). Applies standalone.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original Discussion
**Record:**
- **URL:** https://lists.openwall.net/linux-kernel/2026/06/22/987
- **Series revisions:** v1 only (single patch)
- **Reviewer feedback:** No NAKs found; `Reviewed-by: Sabrina Dubroca`
- **Stable nomination:** None in thread
- **Author context:** Notes bug is probably old, first seen on
next-20260615
### Step 4.2: Reviewers
**Record:** To: mlx5 maintainers (Saeed Mahameed, Leon Romanovsky,
etc.), netdev maintainers (Andrew Lunn, David Miller, Jakub Kicinski,
Paolo Abeni, Eric Dumazet). Cc: netdev@, linux-rdma@, linux-kernel@.
Reviewed-by from Sabrina Dubroca (netdev).
### Step 4.3: Bug Report
**Record:** No external bug report or syzbot link. Failure documented
via reproducible linker error in commit message and lore submission.
Syzbot CI skipped the patch as having no functional/runtime impact
(Kconfig-only).
### Step 4.4: Related Patches
**Record:** No multi-patch series. Direct precedent: TLS and psample
mlx5 Kconfig fixes already in tree.
### Step 4.5: Stable List History
**Record:** No stable@ discussion found. Not searched exhaustively on
lore stable@, but absence is not a negative signal per review
guidelines.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key Functions
**Record:** No C functions modified. Affected symbols at build time:
- `mlx5r_add_gid_macsec_operations()` /
`mlx5r_del_gid_macsec_operations()` in
`drivers/infiniband/hw/mlx5/macsec.c` (call
`macsec_netdev_is_offloaded()`)
- `macsec_netdev_is_offloaded()` in `drivers/net/macsec.c`
(EXPORT_SYMBOL_GPL)
### Step 5.2: Callers
**Record:** `mlx5r_add/del_gid_macsec_operations()` called from
`drivers/infiniband/hw/mlx5/main.c` during RoCE GID add/delete. Only
compiled when `CONFIG_MLX5_MACSEC=y`. `mlx5_ib-$(CONFIG_MLX5_MACSEC) +=
macsec.o` in `drivers/infiniband/hw/mlx5/Makefile`.
### Step 5.3: Callees
**Record:** `macsec_netdev_is_offloaded()` checks whether a netdevice
has MACsec offload enabled — exported GPL symbol from MACsec core
driver.
### Step 5.4: Reachability
**Record:** Bug is reachable at **build time** when a user/distro
selects `MLX5_CORE=y`, `MACSEC=m`, `MLX5_MACSEC=y`. Not a runtime
userspace trigger, but blocks kernel compilation entirely for that
config.
### Step 5.5: Similar Patterns
**Record:** Same Kconfig dependency pattern already used in this file:
- `MLX5_EN_TLS`: `depends on TLS=y || MLX5_CORE=m` (line 162)
- `MLX5_TC_SAMPLE`: `depends on PSAMPLE=y || PSAMPLE=n || MLX5_CORE=m`
(line 115)
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE (6.18.44)
### Step 6.1: Does Buggy Code Exist?
**Record:** **YES.** Current tree at
`drivers/net/ethernet/mellanox/mlx5/core/Kconfig:146` still has `depends
on MACSEC`. RoCE MACsec code and `macsec_netdev_is_offloaded()`
references are present. Fix commit is **not yet applied** to this
checkout.
### Step 6.2: Backport Complications
**Record:** **Clean apply expected.** Single-line change.
`MACSEC=MLX5_CORE` syntax is supported in 6.18.44 Kconfig (verified via
grep of other `=SYMBOL` patterns in tree). No conflicting recent churn
on this Kconfig block.
### Step 6.3: Related Fixes Already Present?
**Record:** TLS and psample mlx5 Kconfig link fixes are present. No
equivalent MACsec fix found (`git log --grep="macsec dependency"`
returns nothing in this tree).
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem
**Record:** **drivers/net/ethernet/mellanox/mlx5** +
**drivers/infiniband/hw/mlx5** (RDMA/RoCE MACsec). Criticality:
**IMPORTANT** — affects Mellanox ConnectX users building custom or
distro kernels with MACsec offload; not universal core-path but affects
a widely deployed NIC family.
### Step 7.2: Activity
**Record:** mlx5 Kconfig actively maintained; recent commits include PSP
offload, VXLAN co-dependency removal, HWS support. MACsec Kconfig
dependency has been unchanged since 2022.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who Is Affected
**Record:** Kernel builders (distro maintainers, embedded vendors,
advanced users) configuring `MLX5_CORE=y` + `MACSEC=m` +
`MLX5_MACSEC=y`. Hardware-specific (Mellanox/NVIDIA ConnectX with RoCE
MACsec offload).
### Step 8.2: Trigger Conditions
**Record:** Selecting the invalid Kconfig combination during `make
menuconfig` / defconfig customization. Uncommon but explicitly allowed
by current Kconfig. Not user-triggerable at runtime.
### Step 8.3: Failure Mode Severity
**Record:** **Build failure** — linker error, kernel cannot be built.
Per `Documentation/process/stable-kernel-rules.rst` line 19, build
errors are explicitly listed as valid stable material (excluding
CONFIG_BROKEN). Severity for stable purposes: **qualifying build
error**.
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** Unblocks valid-intent builders; prevents wasted build
time hitting link failure; aligns Kconfig with link requirements
- **Risk:** Minimal — one-line Kconfig constraint, proven pattern
- **Ratio:** High benefit, very low risk
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence Summary
**FOR backport:**
- Fixes a real, reproducible linker failure
- Explicitly listed stable category: build error
- One-line, obviously correct fix
- Same author fixed identical mlx5 Kconfig class before (TLS, psample) —
those are in this tree
- Reviewed-by from netdev reviewer; merged by net maintainer
- Buggy code confirmed present in 6.18.44
- Clean backport expected
**AGAINST backport:**
- Rare configuration (author notes randconfig rarely hits it)
- No runtime/user-visible crash — build-time only
- No explicit stable nomination or user bug reports
**Unresolved:** Whether any distro actually ships this broken config
combination in practice (unverified; not needed for decision — build
errors are stable-worthy regardless).
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — proven Kconfig pattern,
Reviewed-by present
2. Fixes real bug affecting users? **PASS** — reproducible link failure
blocks kernel build
3. Important issue? **PASS** — build error per stable-kernel-rules.rst
4. Small and contained? **PASS** — 1 line, 1 file
5. No new features/APIs? **PASS** — Kconfig constraint only
6. Can apply to local tree? **PASS** — buggy code present, syntax
supported, clean apply
### Step 9.3: Exception Category
**Record:** **Build fix** — Kconfig dependency correction preventing
link failure.
### Step 9.4: Decision Rationale
For **Linux 6.18.44**, this commit should be backported. The tree still
has the insufficient `depends on MACSEC` constraint while RoCE MACsec
code unconditionally references `macsec_netdev_is_offloaded()` when
`CONFIG_MLX5_MACSEC=y`. The fix is a one-line Kconfig change using an
established mlx5 pattern and syntax already supported in 6.18.y. It
meets all stable kernel criteria, including the explicit allowance for
build errors in `stable-kernel-rules.rst`.
---
## Verification
- **[Phase 1]** `git describe HEAD` → v6.18.44; parsed commit message
tags from user query and lore
- **[Phase 1]** WebFetch lore: https://lists.openwall.net/linux-
kernel/2026/06/22/987 — confirmed patch content and author notes
- **[Phase 2]** Read `Kconfig` lines 143–165 — confirmed current
`depends on MACSEC` and TLS precedent at line 162
- **[Phase 2]** Grep `macsec_netdev_is_offloaded` — found in
`drivers/infiniband/hw/mlx5/macsec.c:246,332` and
`drivers/net/macsec.c:4355`
- **[Phase 3]** `git blame` on Kconfig:143-150 — `depends on MACSEC`
from 8ff0ac5be14469 (2022-09-05)
- **[Phase 3]** `git show 8ff0ac5be14469`, `758ce14aee825`,
`58dbd6428a681` — MACsec Kconfig and RoCE MACsec introduction
- **[Phase 3]** `git show c3cd281e2bc8d`, `7a7dd5114f538` — prior Arnd
mlx5 Kconfig link fixes
- **[Phase 3]** `git log --oneline -20 --
drivers/net/ethernet/mellanox/mlx5/core/Kconfig` — recent file history
- **[Phase 3]** `git show f132fdd9dc81e` — `macsec_netdev_is_offloaded`
added 2023-08-20
- **[Phase 4]** b4 dig requires commit hash; commit not in local tree —
used WebFetch lore instead
- **[Phase 4]** WebSearch — found lore URL, GitHub commit 87ab827,
syzbot CI skip (no runtime test needed)
- **[Phase 5]** Read `drivers/infiniband/hw/mlx5/Makefile:33` —
`mlx5_ib-$(CONFIG_MLX5_MACSEC) += macsec.o`
- **[Phase 5]** Grep `=MLX5_CORE` and `=SYMBOL` patterns —
`MACSEC=MLX5_CORE` syntax supported in 6.18.44 tree
- **[Phase 6]** Grep confirmed fix NOT present (`depends on MACSEC`
without `MACSEC=y || MACSEC=MLX5_CORE`)
- **[Phase 6]** `git log --grep="macsec dependency"` — no fix already in
tree
- **[Phase 7]** Read `Documentation/process/stable-kernel-rules.rst:19`
— build errors explicitly allowed
- **[Phase 8]** Confirmed failure mode is link-time build failure, not
runtime crash
**YES**
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index 3c3e84100d5aa..925ee25d05b47 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -143,7 +143,7 @@ config MLX5_CORE_IPOIB
config MLX5_MACSEC
bool "Connect-X support for MACSec offload"
depends on MLX5_CORE_EN
- depends on MACSEC
+ depends on MACSEC=y || MACSEC=MLX5_CORE
default n
help
Build support for MACsec cryptography-offload acceleration in the NIC.
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18] RDMA/umem: Make ib_umem_is_contiguous() safe on 32 bit
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-6.1] eth: mlx5: fix macsec dependency Sasha Levin
@ 2026-08-31 13:21 ` Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-5.15] RDMA/rtrs-srv: Fix integer underflow in process_read and process_write Sasha Levin
` (15 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:21 UTC (permalink / raw)
To: patches, stable; +Cc: Jason Gunthorpe, Sasha Levin, linux-rdma, linux-kernel
From: Jason Gunthorpe <jgg@nvidia.com>
[ Upstream commit 55d984dae65262fbb0a673cff7cc9824a5e19bdb ]
Sashiko points out the roundup_pow_of_two() only uses unsigned long but
dma_addr_t can be u64.
Change this algorithm to be simpler, compute the page size, if any page
size is found and it results in a single block then it is contiguous.
Link: https://patch.msgid.link/r/3-v1-88303e9e509f+f7-ib_umem_types_jgg@nvidia.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.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:** `[RDMA/umem]` `[Make/safe]` — Make `ib_umem_is_contiguous()`
safe on 32-bit by fixing type truncation in page-size computation.
### Step 1.2: Tags
**Record:**
- **Link:** https://patch.msgid.link/r/3-v1-88303e9e509f+f7-
ib_umem_types_jgg@nvidia.com
- **Signed-off-by:** Jason Gunthorpe \<jgg@nvidia.com\>
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, or Cc: stable in
the commit message itself
- **Notable:** Patch is **[PATCH 3/3]** in series "Fix typing issues in
the umem code"; cover letter and patch 1 CC `stable@vger.kernel.org`.
Author is RDMA subsystem maintainer.
### Step 1.3: Body Analysis
**Record:**
- **Bug:** `roundup_pow_of_two()` operates on `unsigned long`, but its
input involves `dma_addr_t` which can be `u64` on 32-bit kernels with
`CONFIG_ARCH_DMA_ADDR_T_64BIT`.
- **Symptom:** Incorrect page-size computation in
`ib_umem_is_contiguous()`, yielding wrong contiguous/non-contiguous
results.
- **Root cause:** Silent truncation of a 64-bit DMA-address expression
to 32-bit `unsigned long` before `roundup_pow_of_two()`.
- **Fix approach:** Replace XOR/roundup algorithm with
`ib_umem_find_best_pgsz()` + `ib_umem_num_dma_blocks() == 1` check.
### Step 1.4: Hidden Bug Fix?
**Record:** Yes — despite no "fix" in the subject, this is a type-
truncation correctness bug, not cleanup. Reported by Sashiko per commit
message.
---
## Phase 2: Diff Analysis
### Step 2.1: Inventory
**Record:**
- **Files:** `include/rdma/ib_umem.h` only (+3 / -8 lines)
- **Functions:** `ib_umem_is_contiguous()`
- **Scope:** Single-file, surgical inline-helper fix
### Step 2.2: Code Flow Change
**Record:**
- **Before:** Compute `pgsz = roundup_pow_of_two((dma_addr ^
(umem->length - 1 + dma_addr)) + 1)`, then call
`ib_umem_find_best_pgoff(umem, pgsz, U64_MAX)`.
- **After:** `pgsz = ib_umem_find_best_pgsz(umem, ULONG_MAX,
ib_umem_start_dma_addr(umem))`, return true iff `pgsz &&
ib_umem_num_dma_blocks(umem, pgsz) == 1`.
- **Path affected:** Any caller checking umem contiguity (EFA CQ
external-memory creation).
### Step 2.3: Bug Mechanism
**Record:**
- **Category:** Type/size truncation (endianness/type bug family)
- **Mechanism:** On 32-bit with 64-bit `dma_addr_t`, `(dma_addr ^
(umem->length - 1 + dma_addr)) + 1` is computed in 64-bit arithmetic
but implicitly truncated when passed to `roundup_pow_of_two(unsigned
long)`, producing wrong `pgsz` and wrong contiguity result.
### Step 2.4: Fix Quality
**Record:** Obviously correct and simpler. Uses existing helpers that
already handle `dma_addr_t` internally for SG traversal. Low regression
risk. **Caveat:** Full correctness on 32-bit also requires patch 2/3 of
the same series (changing `ib_umem_find_best_pgsz()`'s `virt` parameter
from `unsigned long` to `u64`), which is not yet in this tree.
---
## Phase 3: Git History Investigation
### Step 3.1: Blame
**Record:** Buggy `ib_umem_is_contiguous()` introduced in
`c897c2c8b8e82` ("RDMA/core: Add umem is_contiguous and start_dma_addr
helpers", 2025-07-08). Present in this 6.18.y tree.
### Step 3.2: Fixes: Tag
**Record:** N/A — no Fixes: tag on this commit.
### Step 3.3: Related File History
**Record:**
- Part of 3-patch series by Jason Gunthorpe (2026-06-01):
1. `15fe76e23615f` — Fix truncation for block sizes >= 4G (`iter.c`) —
**already backported** as `afd35fec92971`
2. `09ea6837a0434` — Boundary conditions in `ib_umem_find_best_pgsz()`
— **NOT in tree**
3. `55d984dae6526` — This commit — **NOT in tree**
- `ib_umem_is_contiguous()` caller added in `9fb3dd85197f5` (EFA CQ
external memory support), also in tree.
### Step 3.4: Author Context
**Record:** Jason Gunthorpe is core RDMA maintainer. Recent related work
includes `ib_umem_find_best_pgsz()` improvements and umem typing fixes.
### Step 3.5: Dependencies
**Record:** Patch 2 (`09ea6837a0434`) changes `ib_umem_find_best_pgsz()`
to accept `u64 virt` instead of `unsigned long virt`. This commit passes
`ib_umem_start_dma_addr(umem)` (`dma_addr_t`) as that argument. **For a
complete 32-bit fix, patch 2 should accompany this commit.** Patch 3
compiles and applies standalone but retains `virt` truncation without
patch 2.
---
## Phase 4: Mailing List and External Research
### Step 4.1: Original Discussion
**Record:**
- **URL:** https://patch.msgid.link/3-v1-88303e9e509f+f7-
ib_umem_types_jgg@nvidia.com (via `b4 dig -c 55d984dae6526`)
- **Series:** v1 only found; applied to mainline by Jason Gunthorpe on
2026-06-05 ("Applied")
- **Cover letter:** "Fix various silent truncations, issues on 32 bit
compiles and understandability"
### Step 4.2: Reviewers
**Record:** To: Leon Romanovsky, linux-rdma; Cc:
patches@lists.linux.dev, Shiraz Saleem, **stable@vger.kernel.org**
### Step 4.3: Bug Report
**Record:** No formal bugzilla/syzbot report. Issue raised by Sashiko
during review (per commit message). No stack traces or crash reports.
### Step 4.4: Related Patches
**Record:** 3-patch series; patch 1 already backported to 6.18.y.
Patches 2+3 remain.
### Step 4.5: Stable List History
**Record:** Author CC'd stable on cover letter and patch 1 (which was
backported). Explicit stable nomination signal.
---
## Phase 5: Code Semantic Analysis
### Step 5.1: Key Functions
**Record:** `ib_umem_is_contiguous()`, `ib_umem_find_best_pgsz()`,
`ib_umem_num_dma_blocks()`, `ib_umem_start_dma_addr()`
### Step 5.2: Callers
**Record:** Single caller in this tree:
- `drivers/infiniband/hw/efa/efa_verbs.c` — EFA CQ creation with
external memory; rejects non-contiguous buffers with `-EINVAL`.
### Step 5.3: Callees
**Record:** `ib_umem_find_best_pgsz()` walks SG table using
`dma_addr_t`; `ib_umem_num_dma_blocks()` counts blocks from `umem->iova`
and `umem->length`.
### Step 5.4: Reachability
**Record:** Reachable from userspace via RDMA uverbs CQ creation ioctl
(EFA driver, `CONFIG_INFINIBAND_EFA`). Requires
`CONFIG_INFINIBAND_USER_MEM`.
### Step 5.5: Similar Patterns
**Record:** Same series addresses related truncation in `iter.c`
(already backported) and `ib_umem_find_best_pgsz()` (patch 2, not yet
backported).
---
## Phase 6: Cross-Reference Against Local Tree
### Step 6.1: Buggy Code Present?
**Record:** **Yes.** Tree is **v6.18.44** (`linux-6.18.y`). Buggy
`roundup_pow_of_two()` code is at lines 122–134 of
`include/rdma/ib_umem.h`. Introduced July 2025, well within 6.18's
lifetime.
### Step 6.2: Backport Complications
**Record:** Clean apply expected — single hunk in one header. No
conflicting changes found. **Recommend backporting patch 2 alongside for
complete fix.**
### Step 6.3: Related Fixes Already Present?
**Record:** Patch 1 of series (`afd35fec92971`) already backported.
Patches 2 and 3 are not. No alternative fix for this specific bug.
---
## Phase 7: Subsystem Context
### Step 7.1: Subsystem
**Record:** RDMA core (`include/rdma/ib_umem.h`) — **IMPORTANT**
(affects RDMA memory registration path, used by multiple drivers via
shared helpers).
### Step 7.2: Activity
**Record:** Actively developed; `ib_umem_is_contiguous()` is relatively
new (2025).
---
## Phase 8: Impact and Risk Assessment
### Step 8.1: Who Is Affected
**Record:** Users of RDMA with `CONFIG_INFINIBAND_USER_MEM` on **32-bit
architectures with 64-bit DMA addresses** (e.g., ARM with
`CONFIG_ARCH_DMA_ADDR_T_64BIT`). Currently impacts EFA external-memory
CQ path directly; helper is available for other drivers.
### Step 8.2: Trigger Conditions
**Record:** Creating an RDMA memory region where DMA addresses or span
computations exceed 32-bit when truncated. Requires EFA (currently) +
external memory CQ. Not every boot, but reachable from userspace RDMA
operations.
### Step 8.3: Failure Mode Severity
**Record:**
- **False negative** (contiguous reported as non-contiguous): `-EINVAL`,
CQ creation fails — **MEDIUM**
- **False positive** (non-contiguous reported as contiguous): device
programmed with wrong memory layout — potential **data corruption /
hardware malfunction** — **HIGH**
- Not a typical kernel oops/panic, but correctness bug with corruption
potential.
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** MEDIUM-HIGH — fixes real type bug in shared RDMA helper;
author nominated for stable; series already partially backported
- **Risk:** LOW — 3-line net change, uses existing well-tested helpers
- **Ratio:** Favorable
---
## Phase 9: Final Synthesis
### Step 9.1: Evidence Summary
**FOR:**
- Real type-truncation bug on 32-bit with 64-bit `dma_addr_t`
- Small, surgical, obviously correct fix from RDMA maintainer
- Author CC'd stable; patch 1 of same series already in 6.18.y
- False-positive contiguity could cause serious RDMA misprogramming
- Buggy code confirmed present in v6.18.44
**AGAINST:**
- Niche platform config (32-bit + 64-bit DMA + RDMA)
- Only one direct caller today (EFA)
- Complete fix requires patch 2 (`09ea6837a0434`) not yet in tree
- No crash report or syzbot reproduction
**Unresolved:** No runtime test results in mailing list thread.
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **PASS** — logic is sound; applied to
mainline; no objections in review
2. Fixes a real bug? **PASS** — confirmed type truncation in existing
code
3. Important issue? **PASS** — correctness bug with potential data
corruption (false positive path)
4. Small and contained? **PASS** — 3 lines net, one file
5. No new features/APIs? **PASS** — same function signature and
semantics
6. Can apply to local tree? **PASS** — applies cleanly; patch 2 should
accompany for completeness
### Step 9.3: Exception Categories
**Record:** N/A — standard bug fix, not device-ID/quirk/build/doc
exception.
### Step 9.4: Decision Rationale
This commit fixes a real, verifiable type-truncation bug in
`ib_umem_is_contiguous()` that exists in the 6.18.44 tree. The buggy
code was introduced in July 2025 and can cause incorrect contiguity
detection on 32-bit kernels where `dma_addr_t` is 64-bit. While the
immediate caller is the EFA driver's external-memory CQ path, the helper
is shared RDMA infrastructure.
The fix is minimal, low-risk, and from the RDMA maintainer who
explicitly CC'd stable. Patch 1 of the same 3-patch series is already
backported to this tree (`afd35fec92971`), establishing precedent.
**Patch 2 (`09ea6837a0434`) should be backported together with this
commit** for a complete 32-bit fix, since this commit passes a
`dma_addr_t` to `ib_umem_find_best_pgsz()` which still takes `unsigned
long virt` in 6.18.y. Even standalone, removing the broken
`roundup_pow_of_two()` path is a meaningful improvement.
---
## Verification
- **[Phase 1]** Parsed commit message: subsystem RDMA/umem, Link tag,
Jason Gunthorpe SOB, Sashiko attribution
- **[Phase 2]** Diff analysis: 3 insertions, 8 deletions in
`ib_umem_is_contiguous()`; removes `roundup_pow_of_two()` call
- **[Phase 3]** `git blame`: buggy code from `c897c2c8b8e82`
(2025-07-08), present in tree
- **[Phase 3]** `git merge-base --is-ancestor c897c2c8b8e82 HEAD`: intro
commit IS in tree
- **[Phase 3]** Series check: patch 1 (`afd35fec92971`) IN tree; patches
2 (`09ea6837a0434`) and 3 (`55d984dae6526`) NOT in tree
- **[Phase 3]** `git log --oneline -20 -- include/rdma/ib_umem.h`:
confirmed recent umem history
- **[Phase 4]** `b4 dig -c 55d984dae6526`: found thread at
patch.msgid.link
- **[Phase 4]** `b4 dig -c 55d984dae6526 -a`: v1 series, 3 patches
- **[Phase 4]** `b4 dig -c 55d984dae6526 -w`: stable@vger.kernel.org
CC'd
- **[Phase 4]** `b4 dig -m /tmp/umem_thread.mbox`: cover letter
describes 32-bit truncation fixes; "Applied" reply from author
- **[Phase 5]** `grep ib_umem_is_contiguous`: one caller in
`efa_verbs.c:1222`
- **[Phase 5]** Read `efa_verbs.c:1215-1230`: rejects non-contiguous
with `-EINVAL`
- **[Phase 5]** Read `ib_umem_find_best_pgsz()` in `umem.c`: uses
`dma_addr_t` internally for SG traversal
- **[Phase 6]** `git describe HEAD`: v6.18.44; `make kernelversion`:
6.18.44
- **[Phase 6]** Read current `ib_umem.h:122-134`: confirmed buggy code
still present
- **[Phase 6]** `include/linux/types.h:157-161`: `dma_addr_t` is `u64`
when `CONFIG_ARCH_DMA_ADDR_T_64BIT`
- **[Phase 6]** `include/linux/log2.h:174-181`: `roundup_pow_of_two()`
uses `unsigned long` / `1UL`
- **[Phase 8]** Failure mode: wrong contiguity → EINVAL or potential
RDMA misprogramming
**YES**The analysis is complete: **this commit should be backported to
the 6.18.y tree (v6.18.44).**
**Why:** `ib_umem_is_contiguous()` truncates 64-bit `dma_addr_t` values
through `roundup_pow_of_two()` on 32-bit kernels with 64-bit DMA
addresses. That can mis-detect memory contiguity and break EFA external-
memory CQ creation (or worse, accept non-contiguous memory).
**Scope:** Small, low-risk change in `include/rdma/ib_umem.h` (3 lines
net). The buggy code from July 2025 is present in this tree; the fix is
not.
**Follow-up for stable maintainers:** Backport patch 2 of the same
series (`09ea6837a0434` — changes `ib_umem_find_best_pgsz()` to take
`u64 virt`) together with this commit for a complete 32-bit fix. Patch 1
of the series is already in 6.18.y as `afd35fec92971`.
include/rdma/ib_umem.h | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 0cda3e6425d2e..8a74153332577 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -121,16 +121,11 @@ static inline unsigned long ib_umem_find_best_pgoff(struct ib_umem *umem,
static inline bool ib_umem_is_contiguous(struct ib_umem *umem)
{
- dma_addr_t dma_addr;
unsigned long pgsz;
- /*
- * Select the smallest aligned page that can contain the whole umem if
- * it was contiguous.
- */
- dma_addr = ib_umem_start_dma_addr(umem);
- pgsz = roundup_pow_of_two((dma_addr ^ (umem->length - 1 + dma_addr)) + 1);
- return !!ib_umem_find_best_pgoff(umem, pgsz, U64_MAX);
+ pgsz = ib_umem_find_best_pgsz(umem, ULONG_MAX,
+ ib_umem_start_dma_addr(umem));
+ return pgsz && ib_umem_num_dma_blocks(umem, pgsz) == 1;
}
struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.15] RDMA/rtrs-srv: Fix integer underflow in process_read and process_write
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-6.1] eth: mlx5: fix macsec dependency Sasha Levin
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18] RDMA/umem: Make ib_umem_is_contiguous() safe on 32 bit Sasha Levin
@ 2026-08-31 13:22 ` Sasha Levin
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-6.6] net/mlx5: E-Switch, align disable sequence with switchdev-to-legacy transition Sasha Levin
` (14 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:22 UTC (permalink / raw)
To: patches, stable
Cc: Aurelien DESBRIERES, Md Haris Iqbal, Jason Gunthorpe, Sasha Levin,
jinpu.wang, linux-rdma, linux-kernel
From: Aurelien DESBRIERES <aurelien@hackers.camp>
[ Upstream commit 54bf38b27afc08a0eb6b732f9c14eb8a4bcb66b5 ]
usr_len is read from a network-supplied message field (le16_to_cpu)
and used to compute data_len = off - usr_len without validating that
usr_len <= off. A malicious RDMA client can send usr_len > off causing
an integer underflow, resulting in data_len wrapping to a huge size_t
value which is then passed to the rdma_ev callback as a memory length,
leading to out-of-bounds memory access.
Fix by reading and validating usr_len <= off before rtrs_srv_get_ops_ids()
in both process_read() and process_write(), ensuring the early return
path acquires no reference and has no resource leak.
Link: https://patch.msgid.link/r/20260608134802.5019-1-aurelien@hackers.camp
Reported-by: Aurelien DESBRIERES <aurelien@hackers.camp>
Reviewed-by: Md Haris Iqbal <haris.iqbal@ionos.com>
Signed-off-by: Aurelien DESBRIERES <aurelien@hackers.camp>
Assisted-by: Claude <claude-sonnet-4-6>
Acked-by: Md Haris Iqbal <haris.iqbal@ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: RDMA/rtrs-srv integer underflow fix
**Local tree:** `v6.18.44` (`6.18.44` per `make kernelversion`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[RDMA/rtrs-srv]` `[Fix]` — integer underflow in
`process_read()` and `process_write()` when computing `data_len` from
network-supplied `usr_len` and offset `off`.
### Step 1.2: Tags
**Record:**
- **Link:**
https://patch.msgid.link/r/20260608134802.5019-1-aurelien@hackers.camp
- **Reported-by:** Aurelien DESBRIERES \<aurelien@hackers.camp\>
- **Reviewed-by:** Md Haris Iqbal \<haris.iqbal@ionos.com\> (IONOS RTRS
maintainer)
- **Acked-by:** Md Haris Iqbal \<haris.iqbal@ionos.com\>
- **Signed-off-by:** Aurelien DESBRIERES, Jason Gunthorpe (RDMA
maintainer)
- **Assisted-by:** Claude (notable but not decision-critical)
- No **Fixes:** tag (expected for manual review pipeline)
- No **Cc: stable** tag (absence is not a negative signal per
instructions)
Notable: security-relevant report from researcher, reviewed and acked by
subsystem maintainer, signed off by RDMA maintainer.
### Step 1.3: Body analysis
**Record:**
- **Bug:** `usr_len` is read from wire (`le16_to_cpu(msg->usr_len)`) and
used as `data_len = off - usr_len` without checking `usr_len <= off`.
- **Symptom:** Integer underflow wraps `data_len` to a huge `size_t`,
passed to `rdma_ev()` as a memory length → out-of-bounds memory
access.
- **Attack model:** Malicious RDMA client sends crafted messages.
- **Fix approach:** Validate `usr_len <= off` before
`rtrs_srv_get_ops_ids()` so early return does not leak references.
### Step 1.4: Hidden bug fix detection
**Record:** Not disguised — explicitly labeled a fix. The “no resource
leak on early return” note is a secondary correctness detail (placing
validation before `rtrs_srv_get_ops_ids()` avoids acquiring
`ids_inflight_ref` on invalid input).
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/infiniband/ulp/rtrs/rtrs-srv.c` only
- **Scope:** +16 lines, −2 lines moved (net +14); two functions modified
- **Functions:** `process_read()`, `process_write()`
- **Classification:** Single-file, surgical security fix
### Step 2.2: Code flow change
**Record:**
**`process_read()` hunk:**
- **Before:** After state/sg_cnt checks → `rtrs_srv_get_ops_ids()` →
read `usr_len` → `data_len = off - usr_len` → `rdma_ev()`
- **After:** Read `usr_len` → if `usr_len > off`, return early (no ref
acquired) → then existing path
**`process_write()` hunk:** Same pattern.
### Step 2.3: Bug mechanism
**Record:**
- **Category:** Buffer overflow / out-of-bounds access via integer
underflow (unsigned wraparound)
- **Mechanism:** `usr_len` is `size_t`, `off` is `u32`. Expression `off
- usr_len` uses unsigned arithmetic; when `usr_len > off`, `data_len`
wraps to ~`SIZE_MAX`. That length is passed to upper-layer `rdma_ev()`
callbacks with `data` pointing at a fixed-size chunk page
(`max_chunk_size`, default 128 KiB).
### Step 2.4: Fix quality
**Record:**
- Fix is minimal and obviously correct: reject invalid wire input before
any side effects.
- Moving validation before `rtrs_srv_get_ops_ids()` is correct — without
it, early return would leak a percpu ref.
- **Regression risk:** Very low. Legitimate clients must satisfy
`usr_len <= off` by protocol; invalid messages are silently dropped
with `pr_debug()`.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** Buggy lines (`usr_len = le16_to_cpu(...); data_len = off -
usr_len`) introduced in **9cb837480424** (“RDMA/rtrs: server: main
functionality”, Jack Wang, 2020-05-11). Confirmed ancestor of HEAD.
### Step 3.2: Fixes: tag
**Record:** No `Fixes:` tag in commit message. N/A.
### Step 3.3: Related file history
**Record:** Recent related security fix already in this tree:
- **5a45d0aa1fa50** — “RDMA/rtrs-srv: Bound RDMA-Write length to chunk
size in rdma_write_sg” (different OOB vector, same file, has `Cc:
stable`, backported by Greg K-H)
- Other recent commits are error-handling and mapping fixes, not
duplicates of this issue.
- This underflow fix is **not** present in the tree (grep shows
vulnerable code at lines 1059–1060, 1112–1113).
### Step 3.4: Author context
**Record:** Aurelien DESBRIERES is a security researcher (reporter).
Reviewer/acker Md Haris Iqbal is an active IONOS RTRS contributor with
multiple recent commits in `drivers/infiniband/ulp/rtrs/`. Jason
Gunthorpe is RDMA maintainer.
### Step 3.5: Dependencies
**Record:** Standalone fix. No series markers (“patch X/Y”). No
prerequisite commits. `git apply --check` with the provided diff: **exit
0** (applies cleanly to current tree).
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** `b4 dig -c <commit>` not possible — fix commit not in this
checkout. WebFetch of Link URL returned Anubis bot-wall (no content).
Lore.kernel.org returned 403. **UNVERIFIED:** full mailing-list thread
content.
### Step 4.2: Reviewers (b4 dig -w)
**Record:** Not run (no commit hash in tree). From commit message: Md
Haris Iqbal reviewed and acked; Jason Gunthorpe signed off.
### Step 4.3: Bug report
**Record:** Reported-by Aurelien DESBRIERES with Link to patch
submission. Mechanism described in commit message is consistent with
code analysis. No syzbot report.
### Step 4.4: Related patches
**Record:** Same subsystem recently received **5a45d0aa1fa50** (remote
peer OOB in `rdma_write_sg`), indicating active security hardening of
rtrs-srv. This fix addresses a separate, earlier code path.
### Step 4.5: Stable list history
**Record:** **UNVERIFIED** — could not access lore stable archive (403).
Related commit 5a45d0aa1fa50 was explicitly nominated for stable (`Cc:
stable@vger.kernel.org`).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `process_read()`, `process_write()` (modified); callers:
`process_io_req()`; entry: `rtrs_srv_rdma_done()` on
`IB_WC_RECV_RDMA_WITH_IMM`.
### Step 5.2: Callers
**Record:**
```
rtrs_srv_rdma_done() [IB completion, off bounded < max_chunk_size]
→ process_io_req()
→ process_read() / process_write()
→ ctx->ops.rdma_ev() [upper-layer callback]
```
`off` is validated in `rtrs_srv_rdma_done()` at line 1273 (`off >=
max_chunk_size` rejected), but **`usr_len` is not validated there** — it
lives inside the RDMA-written message buffer.
### Step 5.3: Callees
**Record:** `rtrs_srv_get_ops_ids()` (percpu ref),
`rtrs_srv_update_rdma_stats()`, `page_address()`, `ctx->ops.rdma_ev()`.
### Step 5.4: Reachability / impact chain
**Record:** Reachable by any connected RDMA peer sending
`RDMA_WRITE_WITH_IMM` I/O requests. Primary consumer in this tree:
- `drivers/block/rnbd/rnbd-srv.c` registers `rnbd_srv_rdma_ev` via
`rtrs_srv_open()`
- `rnbd_srv_rdma_ev()` → `process_rdma()` → `bio_add_virt_nofail(bio,
data, datalen)` when `datalen != 0`
A wrapped `datalen` causes the block layer to reference memory far
beyond the 128 KiB chunk page → **kernel OOB access, potential crash or
information disclosure**.
**Trigger:** Remote RDMA client on the fabric (not arbitrary
unprivileged local users, but a real remote attacker for RNBD/RTRS
deployments).
### Step 5.5: Similar patterns
**Record:** Same file already has `off >= max_chunk_size` check in
`rtrs_srv_rdma_done()` and `plist->length > max_chunk_size` check in
`rdma_write_sg()` (5a45d0aa1fa50). This patch closes the missing
validation on `usr_len` vs `off`.
---
## PHASE 6: CROSS-REFERENCE AGAINST LOCAL TREE (6.18.44)
### Step 6.1: Buggy code present?
**Record:** **YES.** Current tree at lines 1059–1060 and 1112–1113:
```1059:1063:drivers/infiniband/ulp/rtrs/rtrs-srv.c
usr_len = le16_to_cpu(msg->usr_len);
data_len = off - usr_len;
data = page_address(srv->chunks[buf_id]);
ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
data + data_len, usr_len);
```
Bug present since 9cb837480424 (2020); not introduced after 6.18 branch.
### Step 6.2: Backport complications
**Record:** Clean apply verified (`git apply --check` exit 0). No
structural refactoring conflicts in this area. Minor context difference:
error messages in current tree use `%d` instead of `%pe` for errors —
unrelated to this hunk.
### Step 6.3: Related fixes already present?
**Record:** The **5a45d0aa1fa50** `rdma_write_sg` bound fix is present.
The **usr_len underflow fix is NOT** present. No duplicate fix found via
grep/log.
---
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/infiniband/ulp/rtrs/` — RDMA transport layer;
server module (`CONFIG_INFINIBAND_RTRS_SERVER`) used by RNBD server.
**IMPORTANT** for RDMA block-export deployments; not universal like
mm/net core, but security-critical for those users.
### Step 7.2: Activity
**Record:** Active maintenance in 6.18.y — multiple rtrs-srv fixes in
recent history including security-related bounds checking.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Systems with `CONFIG_INFINIBAND_RTRS_SERVER` loaded
(typically via `rtrs_srv` / `rnbd-srv` modules) exposed to RDMA network
peers.
### Step 8.2: Trigger conditions
**Record:** Malicious or buggy RTRS client sends I/O message with
`usr_len > off`. `off` can be as small as 0; `usr_len` is `u16` (up to
65535). **Easily triggerable** by a connected peer.
### Step 8.3: Failure mode severity
**Record:** Out-of-bounds memory access via oversized `datalen` passed
to `rdma_ev` → potential **kernel crash, memory corruption, or
information disclosure**. **Severity: CRITICAL/HIGH** (security-relevant
remote attack on RDMA server).
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH — closes exploitable remote integer-underflow → OOB
path
- **Risk:** VERY LOW — 8 lines of validation per function, no API
changes
- **Ratio:** Strongly favors backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real security bug: unsigned underflow → huge length → OOB in `rdma_ev`
callback
- Verified vulnerable code exists in 6.18.44 since rtrs server inception
(2020)
- Small, surgical, applies cleanly
- Reviewed/acked by subsystem maintainer, signed off by RDMA maintainer
- Same subsystem already received a related OOB fix (5a45d0aa1fa50) in
this tree
- Fix also prevents ref leak on error path (correct placement before
`get_ops_ids`)
**AGAINST backport:**
- Affects only RTRS server users (niche vs whole kernel) — but those
users face real remote attack surface
- Mailing-list thread content unverified (does not weaken technical
case)
**UNRESOLVED:**
- Full lore/kernel.org discussion not accessible (403/bot wall)
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — simple bounds check;
reviewed by maintainer
2. Fixes real bug affecting users? **PASS** — remote peer can trigger
OOB via crafted `usr_len`
3. Important issue? **PASS** — security / OOB memory access (CRITICAL
for affected deployments)
4. Small and contained? **PASS** — one file, ~16 lines
5. No new features/APIs? **PASS** — input validation only
6. Can apply to local tree? **PASS** — `git apply --check` succeeded
### Step 9.3: Exception categories
**Record:** None of the special exceptions (device ID, quirk, DT, build,
docs). This is a straight security bug fix.
### Step 9.4: Decision rationale
For **6.18.44**, the vulnerable code is present, the bug has existed
since the rtrs server was added, a remote RDMA client can trigger
integer underflow leading to out-of-bounds memory access in the
`rdma_ev` path (including RNBD block I/O), and the fix is minimal with
negligible regression risk. This meets all stable-kernel criteria for a
security fix.
---
## Verification
- [Phase 1] Parsed subject, tags, body from user-provided commit message
- [Phase 1] Identified Reported-by, Reviewed-by, Acked-by, Link tags
- [Phase 2] Read current `rtrs-srv.c` lines 1027–1135; confirmed
vulnerable `data_len = off - usr_len` pattern
- [Phase 2] Confirmed `usr_len` is `size_t`, `off` is `u32` — unsigned
underflow verified by type inspection
- [Phase 3] `git blame -L 1055,1065`: buggy code from 9cb837480424
(2020-05-11)
- [Phase 3] `git merge-base --is-ancestor 9cb837480424 HEAD`: buggy
commit is in tree
- [Phase 3] `git log --oneline -20 -- drivers/infiniband/ulp/rtrs/rtrs-
srv.c`: related security fix 5a45d0aa1fa50 present; underflow fix
absent
- [Phase 3] `git apply --check` with provided diff: exit 0 (clean apply)
- [Phase 4] WebFetch Link URL: blocked by Anubis — **UNVERIFIED** thread
content
- [Phase 4] curl lore.kernel.org: 403 — **UNVERIFIED** stable-list
discussion
- [Phase 4] `b4 dig -c`: not run — commit not in checkout
- [Phase 5] Traced call chain: `rtrs_srv_rdma_done` → `process_io_req` →
`process_read`/`process_write`
- [Phase 5] Verified `off >= max_chunk_size` check at line 1273 does not
cover `usr_len`
- [Phase 5] `grep rtrs_srv_open`: only `rnbd-srv.c` uses server; traced
to `bio_add_virt_nofail(bio, data, datalen)`
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] `make kernelversion`: 6.18.44
- [Phase 6] Grep confirmed fix NOT applied; vulnerable code at
1059–1060, 1112–1113
- [Phase 7] Kconfig: `CONFIG_INFINIBAND_RTRS_SERVER` tristate module
- [Phase 8] `DEFAULT_MAX_CHUNK_SIZE` = 128 KiB; chunk is fixed-size page
— OOB impact confirmed
**YES**
drivers/infiniband/ulp/rtrs/rtrs-srv.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
index 1fc67fdff9fc2..12a9a888fe0ee 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
@@ -1049,6 +1049,11 @@ static void process_read(struct rtrs_srv_con *con,
"Processing read request failed, invalid message\n");
return;
}
+ usr_len = le16_to_cpu(msg->usr_len);
+ if (usr_len > off) {
+ pr_debug("rtrs-srv: Invalid usr_len %zu > off %u\n", usr_len, off);
+ return;
+ }
rtrs_srv_get_ops_ids(srv_path);
rtrs_srv_update_rdma_stats(srv_path->stats, off, READ);
id = srv_path->ops_ids[buf_id];
@@ -1056,7 +1061,6 @@ static void process_read(struct rtrs_srv_con *con,
id->dir = READ;
id->msg_id = buf_id;
id->rd_msg = msg;
- usr_len = le16_to_cpu(msg->usr_len);
data_len = off - usr_len;
data = page_address(srv->chunks[buf_id]);
ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
@@ -1102,6 +1106,11 @@ static void process_write(struct rtrs_srv_con *con,
rtrs_srv_state_str(srv_path->state));
return;
}
+ usr_len = le16_to_cpu(req->usr_len);
+ if (usr_len > off) {
+ pr_debug("rtrs-srv: Invalid usr_len %zu > off %u\n", usr_len, off);
+ return;
+ }
rtrs_srv_get_ops_ids(srv_path);
rtrs_srv_update_rdma_stats(srv_path->stats, off, WRITE);
id = srv_path->ops_ids[buf_id];
@@ -1109,7 +1118,6 @@ static void process_write(struct rtrs_srv_con *con,
id->dir = WRITE;
id->msg_id = buf_id;
- usr_len = le16_to_cpu(req->usr_len);
data_len = off - usr_len;
data = page_address(srv->chunks[buf_id]);
ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-6.6] net/mlx5: E-Switch, align disable sequence with switchdev-to-legacy transition
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (2 preceding siblings ...)
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-5.15] RDMA/rtrs-srv: Fix integer underflow in process_read and process_write Sasha Levin
@ 2026-08-31 13:22 ` Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Fix state and counter desync on loopback enable failure Sasha Levin
` (13 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:22 UTC (permalink / raw)
To: patches, stable
Cc: Shay Drory, Mark Bloch, Tariq Toukan, Jakub Kicinski, Sasha Levin,
saeedm, andrew+netdev, davem, edumazet, pabeni, netdev,
linux-rdma, linux-kernel
From: Shay Drory <shayd@nvidia.com>
[ Upstream commit b48b6308dfaeae49fcda61b4066773cb5e8a9ce8 ]
This patch align the eswitch disable sequence with the
switchdev-to-legacy mode transition, where eswitch must be disabled
before device detachment. The consistent ordering is required for proper
SD LAG cleanup which depends on eswitch state during teardown.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260531113954.395443-3-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `net/mlx5: E-Switch, align disable sequence
with switchdev-to-legacy transition`
**Local tree:** Linux **6.18.44** (`v6.18.44`, `VERSION=6 PATCHLEVEL=18
SUBLEVEL=44`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[net/mlx5: E-Switch] [align] — reorder eswitch disable to
match switchdev-to-legacy teardown ordering`
### Step 1.2: Tags
**Record:**
- **Signed-off-by:** Shay Drory `<shayd@nvidia.com>` (author)
- **Reviewed-by:** Mark Bloch `<mbloch@nvidia.com>`
- **Signed-off-by:** Tariq Toukan `<tariqt@nvidia.com>`
- **Link:**
https://patch.msgid.link/20260531113954.395443-3-tariqt@nvidia.com
(patch **3/3** in a series)
- **Signed-off-by:** Jakub Kicinski `<kuba@kernel.org>` (net maintainer)
- No `Fixes:`, `Reported-by:`, `Cc: stable@vger.kernel.org`, or syzbot
tags
- Message-ID suffix `-3-` indicates this is the third patch in a series
### Step 1.3: Body analysis
**Record:**
- **Bug:** E-switch disable runs too late in driver unload paths — after
`mlx5_detach_device()` / `mlx5_unregister_device()` — while the
switchdev-to-legacy transition disables eswitch **before** detachment.
- **Symptom/failure mode:** Improper **SD LAG** (Socket Direct / shared-
FDB LAG) cleanup during teardown; commit does not include a crash
trace.
- **Root cause (author):** SD LAG cleanup in `mlx5_eswitch_disable()`
depends on eswitch still being in the correct state and representors
still being present; detaching/unregistering auxiliary devices first
breaks that.
### Step 1.4: Hidden bug fix?
**Record:** Yes. Described as “align,” but it fixes a **teardown
ordering bug** — same class as other mlx5 LAG/eswitch unload issues.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/net/ethernet/mellanox/mlx5/core/main.c` only
- **Scope:** ~3 lines moved (net zero lines); 3 functions touched
- **Functions modified:** `mlx5_unload()`, `mlx5_uninit_one()`,
`mlx5_unload_one_devl_locked()`
- **Classification:** Single-file, surgical reordering
### Step 2.2: Code flow per hunk
**Hunk 1 — `mlx5_unload()`:**
- **Before:** `mlx5_eswitch_disable()` was the first call in
`mlx5_unload()`.
- **After:** Removed from `mlx5_unload()`.
**Hunk 2 — `mlx5_uninit_one()`:**
- **Before:** `mlx5_unregister_device()` → … → `mlx5_unload()` (which
disabled eswitch).
- **After:** `mlx5_eswitch_disable()` → `mlx5_unregister_device()` → … →
`mlx5_unload()`.
**Hunk 3 — `mlx5_unload_one_devl_locked()`:**
- **Before:** `mlx5_detach_device()` → … → `mlx5_unload()` (which
disabled eswitch).
- **After:** `mlx5_eswitch_disable()` → `mlx5_detach_device()` → … →
`mlx5_unload()`.
**Record:** Both primary unload paths now disable eswitch **before**
tearing down auxiliary devices.
### Step 2.3: Bug mechanism
**Record:** **Teardown ordering / logic correctness bug**
- `mlx5_eswitch_disable()` calls `mlx5_lag_disable_change()` →
`mlx5_disable_lag()`.
- For shared-FDB LAG (`MLX5_LAG_MODE_FLAG_SHARED_FDB`),
`mlx5_disable_lag()` calls `mlx5_eswitch_reload_ib_reps()`, which
requires `esw->mode == MLX5_ESWITCH_OFFLOADS` and `REP_LOADED`
representors.
- `mlx5_detach_device()` / `mlx5_unregister_device()` remove auxiliary
devices (including eswitch representors) **before** `mlx5_unload()`
ran, so SD LAG cleanup could not run correctly.
- `mlx5_devlink_eswitch_mode_set()` already disables eswitch **before**
mode transition — the unload paths were inconsistent.
### Step 2.4: Fix quality
**Record:**
- Fix is minimal and mirrors the known-good
`mlx5_devlink_eswitch_mode_set()` ordering.
- `mlx5_eswitch_disable()` requires devlink lock; both call sites
already hold `devl_lock()`.
- **Regression risk:** Low for main unload paths. **Note:**
`mlx5_unload()` is still called from init error paths (`err_register`,
`err_attach`) without the new early `mlx5_eswitch_disable()` — those
paths typically run before switchdev/SD LAG is configured (unverified
for all edge cases).
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:**
- `mlx5_eswitch_disable()` in `mlx5_unload()`: added/moved to first
position by **85b47dc40bbc7** (Sep 2023, Jiri Pirko).
- `mlx5_detach_device()` before `mlx5_unload()` in
`mlx5_unload_one_devl_locked()`: **72ed5d5624af3** (Jan 2023).
- `mlx5_unregister_device()` before `mlx5_unload()` in
`mlx5_uninit_one()`: longstanding (Leon Romanovsky, 2020).
- Original `mlx5_eswitch_disable` in unload: **f019679ea5f2a** (May
2022).
- **Ordering mismatch has existed since ~2023** when detach was placed
before `mlx5_unload()` while eswitch disable remained inside
`mlx5_unload()`.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag.
### Step 3.3: Related file history
**Record:**
- Shared-FDB LAG introduced **af8c0e25f249a** (Aug 2021) — present in
this tree.
- Related crash fix **4b8eeed4fb105** (Mar 2025): bridge + shared-FDB
LAG teardown oops — same subsystem, similar LAG teardown sensitivity.
- Patch appears standalone (only `main.c`); patches 1–2 of the series
were not found locally.
### Step 3.4: Author context
**Record:** Shay Drory is an active mlx5 contributor (eswitch, LAG,
devlink). Reviewed by Mark Bloch (mlx5 maintainer). Committed via Jakub
Kicinski (netdev).
### Step 3.5: Dependencies
**Record:** Self-contained for `main.c`. No structural/API prerequisites
identified. Patches 1–2 of the series were **not found** in this
workspace; this patch does not appear to depend on them functionally.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** `b4 dig -c HEAD` did not match (commit not in tree). Lore
search returned **403 Forbidden**. patch.msgid.link blocked by bot
protection. **Could not retrieve mailing list thread.**
### Step 4.2: Reviewers
**Record:** Mark Bloch (Reviewed-by). Jakub Kicinski merged. Full
recipient list unavailable (b4 `-w` requires commit in tree).
### Step 4.3: Bug report
**Record:** No external bug report, syzbot link, or crash trace in the
commit message.
### Step 4.4: Series context
**Record:** Message-ID indicates patch **3/3**; patches 1–2 not
identified locally. This change is independently applicable.
### Step 4.5: Stable list history
**Record:** Not searched (lore inaccessible). No stable nomination found
in commit message.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `mlx5_eswitch_disable()`, `mlx5_unload()`,
`mlx5_uninit_one()`, `mlx5_unload_one_devl_locked()`,
`mlx5_detach_device()`, `mlx5_unregister_device()`,
`mlx5_disable_lag()`, `mlx5_eswitch_reload_ib_reps()`
### Step 5.2: Callers of affected paths
**Record:**
- `mlx5_uninit_one()` ← `remove_one()` (module/PCI remove), SF driver
teardown
- `mlx5_unload_one_devl_locked()` ← `mlx5_unload_one()` ← devlink
reload, firmware reset, health recovery, suspend/resume
- Both are common operational paths for mlx5 users
### Step 5.3: Callees
**Record:** `mlx5_eswitch_disable()` → `mlx5_lag_disable_change()` →
`mlx5_disable_lag()` → (shared FDB) `mlx5_eswitch_reload_ib_reps()`;
`mlx5_detach_device()` tears down auxiliary drivers in reverse order
### Step 5.4: Reachability
**Record:** Triggered on driver remove, devlink reload, FW reset
recovery — admin-initiated but routine in datacenter deployments.
Requires **CONFIG_MLX5_ESWITCH**, switchdev mode, and multi-PF Socket
Direct / shared-FDB LAG.
### Step 5.5: Similar patterns
**Record:** `mlx5_devlink_eswitch_mode_set()` disables eswitch before
cleanup (lines 3832–3866 in `eswitch_offloads.c`). Bridge+LAG crash fix
**4b8eeed4fb105** shows mlx5 shared-FDB LAG teardown ordering can cause
kernel oops.
---
## PHASE 6: CROSS-REFERENCE WITH LOCAL TREE (6.18.44)
### Step 6.1: Buggy code present?
**Record:** **YES.** Current tree has:
- `mlx5_eswitch_disable()` at line 1430 inside `mlx5_unload()`
- `mlx5_detach_device()` at line 1623 **before** `mlx5_unload()` at line
1632
- `mlx5_unregister_device()` at line 1539 **before** `mlx5_unload()` at
line 1550
### Step 6.2: Backport complications
**Record:** Expected **clean apply** with minor context adjustment (line
ordering in `mlx5_unload()` differs slightly from the provided diff —
`mlx5_vhca_event_stop` position — but the semantic change is identical).
### Step 6.3: Related fixes already present?
**Record:** **4b8eeed4fb105** (bridge LAG crash) is in tree. This
specific eswitch-disable ordering fix is **not** present.
---
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/net/ethernet/mellanox/mlx5` — **IMPORTANT**
(datacenter NIC driver, widely deployed on stable/LTS kernels)
### Step 7.2: Subsystem activity
**Record:** Actively maintained; frequent mlx5 commits in 6.18.y.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users of **Mellanox ConnectX multi-PF Socket Direct**
configurations with **shared-FDB LAG** in **switchdev** mode —
datacenter/cloud NIC deployments. Not universal; config-specific.
### Step 8.2: Trigger conditions
**Record:** Driver unload, devlink reload, FW-reset recovery, or suspend
on configured SD LAG + switchdev. Admin-initiated but routine.
Unprivileged users cannot directly trigger.
### Step 8.3: Failure mode severity
**Record:** Improper LAG/eswitch teardown;
`mlx5_eswitch_reload_ib_reps()` silently skipped when reps already
detached. Can leave inconsistent LAG state; related mlx5 LAG teardown
bugs have caused **kernel oops** (4b8eeed4fb105). **Severity: MEDIUM-
HIGH** for affected configs; **LOW** for typical single-PF users.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** MEDIUM for affected enterprise users; prevents broken SD
LAG teardown on common unload paths
- **Risk:** LOW — 3-line reorder, mirrors existing mode-set path,
reviewed by subsystem maintainer
- **Ratio:** Favorable for backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Verified ordering bug: detach/unregister before eswitch disable in
both main unload paths
- SD LAG cleanup (`mlx5_disable_lag` → `mlx5_eswitch_reload_ib_reps`)
requires eswitch/rep state that detach destroys
- Matches proven-correct `mlx5_devlink_eswitch_mode_set()` ordering
- Small, surgical, low regression risk
- Bug present since ~2023; shared-FDB LAG in tree since 2021
- Same subsystem had LAG teardown oops fixed for stable (4b8eeed4fb105)
- NVIDIA maintainer review
**AGAINST backport:**
- No crash trace, syzbot report, or user bug report in commit message
- Affects niche multi-PF Socket Direct + switchdev configuration
- Patch 3/3 — series context unavailable
- Init error paths (`err_register`/`err_attach`) still call
`mlx5_unload()` without early eswitch disable (likely low impact —
switchdev typically not configured at probe failure)
**Unresolved:**
- Full mailing list review thread (lore inaccessible)
- Patches 1–2 of the series not found
- No quantitative report of how often this causes visible failures
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — ordering matches mode-set
path; Reviewed-by from mlx5 maintainer (no Tested-by)
2. Fixes a real bug? **PASS** — verifiable teardown ordering violation
3. Important issue? **PASS (MEDIUM)** — improper teardown on
unload/reload for SD LAG; related bugs caused oopses, though this one
lacks explicit crash report
4. Small and contained? **PASS** — single file, ~3 lines moved
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — code exists; clean/minor-context
apply expected
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build fix, or docs fix).
Standard bug-fix backport.
### Step 9.4: Decision rationale
For **Linux 6.18.44**, the buggy ordering is present and the fix is
minimal, obviously correct, and aligns unload paths with the already-
correct switchdev-to-legacy transition. While the affected configuration
(multi-PF Socket Direct + shared-FDB LAG + switchdev) is niche and the
commit lacks a crash report, the mechanism is verified in code, the
subsystem has a history of LAG teardown oopses, and the fix carries very
low risk. This meets stable criteria for an important driver teardown
correctness fix.
---
## Verification
- **[Phase 1]** Parsed commit message and tags from user-provided diff
- **[Phase 2]** Analyzed diff: 3 hunks in `main.c`, eswitch disable
moved from `mlx5_unload` to `mlx5_uninit_one` and
`mlx5_unload_one_devl_locked`
- **[Phase 3]** `git describe HEAD` → `v6.18.44`; `Makefile` → 6.18.44
- **[Phase 3]** `git blame` on lines 1428–1450, 1530–1558, 1618–1636 of
`main.c` — ordering history confirmed
- **[Phase 3]** `git show 85b47dc40bbc7` — eswitch disable moved to
first in `mlx5_unload` (2023)
- **[Phase 3]** `git show f019679ea5f2a` — original addition of eswitch
disable to unload (2022)
- **[Phase 3]** `git show af8c0e25f249a` — shared-FDB LAG since Aug 2021
- **[Phase 3]** `git show 4b8eeed4fb105` — related bridge+LAG oops fix
in tree
- **[Phase 4]** `b4 dig -c HEAD` — no match (commit not in tree)
- **[Phase 4]** Lore/patch.msgid.link fetch — blocked (403/bot
protection); thread not retrieved
- **[Phase 4]** Workspace `.mbx` search for `align disable sequence` /
`395443` — not found
- **[Phase 5]** Read `mlx5_eswitch_disable()` in `eswitch.c:1780–1790` —
calls `mlx5_lag_disable_change`
- **[Phase 5]** Read `mlx5_disable_lag()` in `lag.c:900–937` — shared-
FDB path calls `mlx5_eswitch_reload_ib_reps`
- **[Phase 5]** Read `mlx5_eswitch_reload_ib_reps()` in
`eswitch_offloads.c:3346–3368` — requires OFFLOADS mode and REP_LOADED
- **[Phase 5]** Read `mlx5_detach_device()` in `dev.c:414–454` — removes
auxiliary devices before unload
- **[Phase 5]** Read `mlx5_devlink_eswitch_mode_set()` in
`eswitch_offloads.c:3807–3890` — disables eswitch before mode change
- **[Phase 5]** `grep mlx5_unload(` — callers: err_register,
mlx5_uninit_one, err_attach, mlx5_unload_one_devl_locked
- **[Phase 6]** Read current `main.c:1428–1645` — buggy ordering
confirmed in 6.18.44
- **[Phase 6]** `grep mlx5_eswitch_disable` — present in tree, not yet
reordered
- **[Phase 8]** Confirmed SD = Socket Direct via `mlx5_get_sd()` usage
in `eswitch_offloads.c:3826–3828`
- **UNVERIFIED:** Mailing list reviewer stable nominations; patches 1–2
of series; explicit user crash reports for this specific bug
**YES**
drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 22bdefe5696c9..42bc553d034b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1427,7 +1427,6 @@ static int mlx5_load(struct mlx5_core_dev *dev)
static void mlx5_unload(struct mlx5_core_dev *dev)
{
- mlx5_eswitch_disable(dev->priv.eswitch);
mlx5_devlink_traps_unregister(priv_to_devlink(dev));
mlx5_sf_dev_table_destroy(dev);
mlx5_sriov_detach(dev);
@@ -1536,6 +1535,7 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)
mlx5_hwmon_dev_unregister(dev);
mlx5_crdump_disable(dev);
+ mlx5_eswitch_disable(dev->priv.eswitch);
mlx5_unregister_device(dev);
if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
@@ -1620,6 +1620,7 @@ void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend)
devl_assert_locked(priv_to_devlink(dev));
mutex_lock(&dev->intf_state_mutex);
+ mlx5_eswitch_disable(dev->priv.eswitch);
mlx5_detach_device(dev, suspend);
if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Fix state and counter desync on loopback enable failure
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (3 preceding siblings ...)
2026-08-31 13:22 ` [PATCH AUTOSEL 6.18-6.6] net/mlx5: E-Switch, align disable sequence with switchdev-to-legacy transition Sasha Levin
@ 2026-08-31 13:24 ` Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18] RDMA/counter: Fix num_counters leak on bind_qp failure in alloc_and_bind() Sasha Levin
` (12 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:24 UTC (permalink / raw)
To: patches, stable
Cc: Li RongQing, Jason Gunthorpe, Sasha Levin, linux-rdma,
linux-kernel
From: Li RongQing <lirongqing@baidu.com>
[ Upstream commit 0d32eabccbe4b2f8d45be3192c5f3c76c8af703d ]
In mlx5_ib_enable_lb(), dev->lb.enabled was unconditionally set
to true even if mlx5_nic_vport_update_local_lb() failed.
Fix this by only setting dev->lb.enabled on success. On failure,
roll back the reference counters and return the error.
Link: https://patch.msgid.link/r/20260601095818.2227-1-lirongqing@baidu.com
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: PARSE THE SUBJECT LINE
**Record:** `[RDMA/mlx5]` `[Fix]` — Correct state/counter
desynchronization when vport loopback enable fails in
`mlx5_ib_enable_lb()`.
### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
**Record:**
- **Link:** `https://patch.msgid.link/r/20260601095818.2227-1-
lirongqing@baidu.com`
- **Signed-off-by:** Li RongQing `<lirongqing@baidu.com>` (author)
- **Signed-off-by:** Jason Gunthorpe `<jgg@nvidia.com>` (RDMA
maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable@vger.kernel.org` tags
- Notable: Signed-off-by from Jason Gunthorpe (RDMA subsystem
maintainer) is a strong quality signal
### Step 1.3: ANALYZE THE COMMIT BODY TEXT
**Record:**
- **Bug description:** In `mlx5_ib_enable_lb()`, `dev->lb.enabled` is
set to `true` unconditionally after calling
`mlx5_nic_vport_update_local_lb()`, even when that call fails.
- **Symptom/failure mode:** Software state (`enabled` flag and reference
counters `user_td`/`qps`) becomes inconsistent with hardware state. SW
believes loopback is enabled; HW is not.
- **Root cause:** Missing error check before setting `enabled`, and
missing rollback of incremented counters on failure.
- **Version info:** None stated in commit message.
### Step 1.4: DETECT HIDDEN BUG FIXES
**Record:** Not hidden — explicitly labeled as a fix. This is a classic
error-path state-machine bug (logic/correctness), not cosmetic cleanup.
---
## PHASE 2: DIFF ANALYSIS - LINE BY LINE
### Step 2.1: INVENTORY THE CHANGES
**Record:**
- **Files:** `drivers/infiniband/hw/mlx5/main.c` only (+11 / -0 net)
- **Function modified:** `mlx5_ib_enable_lb()`
- **Scope:** Single-file, surgical fix in one function
### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
**Record:**
**Hunk (enable path):**
- **Before:** Increment `user_td`/`qps`, call
`mlx5_nic_vport_update_local_lb()`, always set `dev->lb.enabled =
true`, unlock, return `err` (possibly non-zero).
- **After:** On `mlx5_nic_vport_update_local_lb()` failure, jump to
`err_rollback`, decrement the counters that were just incremented,
unlock, return error. Only set `enabled = true` on success.
**Affected path:** Error path inside loopback enable, triggered when
`user_td == 2` or `qps == 1`.
### Step 2.3: IDENTIFY THE BUG MECHANISM
**Record:**
- **Bug category:** Logic/correctness fix — error-path state
desynchronization (related to reference-counting semantics).
- **Mechanism:** On `mlx5_nic_vport_update_local_lb()` failure, counters
remain inflated and `enabled` is wrongly `true`. Future calls skip re-
enabling (`if (!dev->lb.enabled)` guard), and disable thresholds
(`user_td == 1 && qps == 0`) may never be reached again. State
corruption persists until driver reload.
### Step 2.4: ASSESS THE FIX QUALITY
**Record:**
- **Fix quality:** Obviously correct. Mirrors the existing pattern in
`mlx5_ib_enable_lb_mp()` in the same file, which already checks errors
from `mlx5_nic_vport_update_local_lb()` before updating state.
- **Regression risk:** Very low. Only affects the failure path; success
path unchanged.
- **Red flags:** None.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: BLAME THE CHANGED LINES
**Record:**
- Buggy logic introduced in `0042f9e458a560` (Mark Bloch, 2018-09-21):
"RDMA/mlx5: Enable vport loopback when user context or QP mandate"
- `dev->lb.enabled = true` unconditionally after
`mlx5_nic_vport_update_local_lb()` has been present since 2018
- Verified: `git merge-base --is-ancestor 0042f9e458a560 HEAD` → bug
commit is in v6.18.44
### Step 3.2: FOLLOW THE FIXES: TAG
**Record:** No `Fixes:` tag present. N/A.
### Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
**Record:**
- Related commit already in tree: `65e344925fa30` — "IB/mlx5: Fix
transport-domain rollback and initialize lb mutex earlier"
- Fixes TD leak when `mlx5_ib_enable_lb()` returns error from
`mlx5_ib_alloc_transport_domain()`
- Does **not** fix the internal state corruption inside
`mlx5_ib_enable_lb()` itself
- This commit is standalone (not part of a numbered series)
- Complementary to `65e344925fa30`: that commit handles the caller; this
one fixes the callee's state machine
### Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
**Record:** No prior commits from Li RongQing in mlx5 in this tree.
Jason Gunthorpe (Signed-off-by) is a core RDMA maintainer.
### Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
**Record:** No dependencies. Applies cleanly to current
`mlx5_ib_enable_lb()` in v6.18.44. Fix is self-contained.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
**Record:** UNVERIFIED — `b4 dig -c <commit>` not possible (commit not
yet in tree). Lore.kernel.org and patch.msgid.link blocked by bot
protection (Anubis). Could not retrieve review thread.
### Step 4.2: CHECK WHO REVIEWED THE PATCH
**Record:** UNVERIFIED via b4 dig -w. Commit message shows Jason
Gunthorpe Signed-off-by (maintainer acceptance).
### Step 4.3: SEARCH FOR THE BUG REPORT
**Record:** No `Reported-by:` or syzbot link. Bug identified through
code analysis (author's commit message). No external bug report
retrieved.
### Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
**Record:** Standalone 1-commit fix. Related but separate:
`65e344925fa30` already in v6.18.44.
### Step 4.5: CHECK STABLE MAILING LIST HISTORY
**Record:** UNVERIFIED — lore.kernel.org inaccessible.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
**Record:** `mlx5_ib_enable_lb()` (modified)
### Step 5.2: TRACE CALLERS
**Record:** Three call sites verified via grep:
1. **`mlx5_ib_alloc_transport_domain()`** (`main.c:1946`) — called
during ucontext creation (`main.c:2144`). Userspace-triggered via
`ibv_open_device()` / RDMA ucontext alloc. **High-impact path.**
2. **`create_raw_packet_qp_tir()`** (`qp.c:1554`) — raw packet QP with
self-LB flags
3. **RSS raw QP TIR creation** (`qp.c:1875`)
On failure at sites 2/3, callers invoke destroy paths that call
`mlx5_ib_disable_lb()`, partially mitigating `qps` counter drift. Site 1
does **not** call `disable_lb` on failure (only deallocates TD per
`65e344925fa30`).
### Step 5.3: TRACE CALLEES
**Record:** `mlx5_nic_vport_update_local_lb()` (`vport.c:896`) can fail
with:
- `-ENOMEM` from `kvzalloc()`
- Error from `mlx5_cmd_exec_in()` (firmware/HW command failure)
### Step 5.4: FOLLOW THE CALL CHAIN
**Record:**
- Userspace opens RDMA device → `mlx5_ib_alloc_ucontext()` →
`mlx5_ib_alloc_transport_domain()` → `mlx5_ib_enable_lb(dev, true,
false)`
- Reachable from unprivileged userspace on mlx5 RoCE devices with
`disable_local_lb_uc` or `disable_local_lb_mc` capability
- On transient failure, `user_td` stuck at 2 and `enabled=true`
permanently breaks loopback for all subsequent operations until module
reload
### Step 5.5: SEARCH FOR SIMILAR PATTERNS
**Record:** `mlx5_ib_enable_lb_mp()` in the same file
(`main.c:1849-1868`) already implements correct error handling — enable
HW, check error, only then update state; rollback on failure. The fix
brings `mlx5_ib_enable_lb()` in line with this established pattern.
---
## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
### Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
**Record:** **YES.** Local tree is **v6.18.44** (`git describe HEAD`).
Buggy code at `main.c:1897-1898`:
```1896:1899:drivers/infiniband/hw/mlx5/main.c
if (!dev->lb.enabled) {
err = mlx5_nic_vport_update_local_lb(dev->mdev,
true);
dev->lb.enabled = true;
}
```
Fix not yet applied (`git log -S "err_rollback"` returns nothing).
### Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
**Record:** Expected **clean apply**. No recent refactoring of this
function. Only `force_enable` early-return added in 2025
(`08aae7860450c8`); fix integrates cleanly around existing structure.
### Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
**Record:** `65e344925fa30` (TD rollback on `enable_lb` error) is
present. The internal state corruption inside `mlx5_ib_enable_lb()`
itself is **not** fixed by that commit and remains unfixed.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
**Record:** RDMA/mlx5 (Mellanox/NVIDIA ConnectX InfiniBand/RoCE driver).
**IMPORTANT** — widely deployed in HPC, cloud, and enterprise RDMA
workloads. Not universal like mm/net core, but critical for mlx5 users.
### Step 7.2: ASSESS SUBSYSTEM ACTIVITY
**Record:** Actively maintained — multiple mlx5 fixes in recent `main.c`
history (`65e344925fa30`, `d3ff718c0c715`, etc.).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: DETERMINE WHO IS AFFECTED
**Record:** Users of mlx5 RoCE devices where `disable_local_lb_uc` or
`disable_local_lb_mc` firmware capabilities are set — devices requiring
explicit vport loopback enable for self-loopback QPs and transport
domains.
### Step 8.2: DETERMINE THE TRIGGER CONDITIONS
**Record:**
- **Trigger:** `mlx5_nic_vport_update_local_lb()` fails during ucontext
open or QP creation (ENOMEM or firmware command error)
- **Likelihood:** Uncommon but realistic under memory pressure or
transient HW/firmware issues
- **Userspace reachable:** Yes — ucontext allocation is a normal
userspace operation
### Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
**Record:**
- **Failure mode:** Persistent driver state corruption — SW/HW loopback
state mismatch, inflated counters prevent recovery
- **User impact:** Loopback traffic broken for device lifetime after one
transient failure; RDMA apps using self-loopback may fail silently or
behave incorrectly
- **Severity:** **MEDIUM-HIGH** — not a kernel crash or security issue,
but persistent functional corruption on a common initialization path.
Complements the already-backported TD leak fix.
### Step 8.4: CALCULATE RISK-BENEFIT RATIO
**Record:**
- **Benefit:** Prevents permanent loopback state corruption on error
paths; completes the error-handling story started by `65e344925fa30`
- **Risk:** Very low — ~11 lines, error-path only, matches existing
`mlx5_ib_enable_lb_mp()` pattern
- **Ratio:** Favorable for backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: COMPILE THE EVIDENCE
**FOR backporting:**
- Real, long-standing bug (since 2018, commit `0042f9e458a560`)
- Buggy code confirmed present in v6.18.44
- Small, surgical, obviously correct fix
- Maintainer Signed-off-by (Jason Gunthorpe)
- Matches existing correct pattern in same file (`mlx5_ib_enable_lb_mp`)
- Userspace-reachable via ucontext allocation
- Persistent state corruption on transient failure
- Complements already-backported `65e344925fa30`
- No new APIs or features
**AGAINST backporting:**
- Only triggers on error paths (ENOMEM, firmware cmd failure) — not
common
- No crash, security vulnerability, or data corruption reported
- No user bug reports or syzbot findings documented
- Severity is functional state corruption, not oops/panic
**UNRESOLVED:**
- Mailing list review discussion (lore blocked)
- Whether reviewers explicitly nominated for stable
### Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — logic is clear; maintainer
SOB; mirrors existing code pattern. No explicit Tested-by.
2. Fixes a real bug that affects users? **PASS** — persistent SW/HW
state desync on mlx5 RoCE loopback enable failure.
3. Important issue? **PASS (borderline)** — persistent driver state
corruption on userspace-initiated path; functional breakage until
reload, though not crash-level.
4. Small and contained? **PASS** — 1 file, ~11 lines, 1 function.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — buggy code present; clean
apply expected.
### Step 9.3: CHECK FOR EXCEPTION CATEGORIES
**Record:** None apply directly (not device ID, quirk, DT, build, or
docs fix). Standard bug fix.
### Step 9.4: DECISION RATIONALE
This commit fixes a real error-path state machine bug in widely used
mlx5 RDMA driver code that has existed since 2018. When
`mlx5_nic_vport_update_local_lb()` fails during ucontext creation, the
driver permanently corrupts its loopback tracking state, preventing
recovery without reload. The fix is minimal, follows an established
pattern in the same file, and completes error handling partially
addressed by the already-backported `65e344925fa30`. While the trigger
is an uncommon error path and severity is functional rather than crash-
level, persistent state corruption on a userspace-initiated
initialization path meets stable backport criteria for mlx5 driver
correctness fixes.
---
## Verification
- **[Phase 1]** Parsed subject, tags; found Link and Jason Gunthorpe
SOB; no Fixes/Reported-by/syzbot
- **[Phase 2]** Diff analysis: adds error check + `err_rollback` counter
decrement in `mlx5_ib_enable_lb()`
- **[Phase 3]** `git blame`: buggy code from `0042f9e458a560`
(2018-09-21); `git merge-base --is-ancestor` confirms in tree
- **[Phase 3]** `git show 65e344925fa30`: related TD rollback fix
already in tree; does not fix internal `enable_lb` state
- **[Phase 3]** `git log -S "err_rollback"`: fix not yet in tree
- **[Phase 4]** UNVERIFIED: lore.kernel.org and patch.msgid.link
blocked; `b4 dig` requires commit hash not in tree
- **[Phase 5]** `grep mlx5_ib_enable_lb`: 3 call sites in `main.c` and
`qp.c`
- **[Phase 5]** Read `mlx5_nic_vport_update_local_lb()` at
`vport.c:896-933`: returns `-ENOMEM` or cmd errors
- **[Phase 5]** Read `mlx5_ib_enable_lb_mp()` at `main.c:1849-1868`:
correct error-handling pattern exists
- **[Phase 5]** Read ucontext alloc path `main.c:2144-2147`: `enable_lb`
failure path does not call `disable_lb`
- **[Phase 6]** `git describe HEAD`: v6.18.44; buggy code at
`main.c:1897-1898` confirmed
- **[Phase 6]** No conflicting fix found in tree
- **[Phase 8]** Failure mode: persistent loopback state corruption,
severity MEDIUM-HIGH
**YES**The background searches finished:
- **Keyword search** (`counter desync`, `loopback enable failure`): no
matches — this fix is **not yet in v6.18.44**.
- **Related commit search**: found `65e344925fa30` (TD rollback when
`mlx5_ib_enable_lb()` fails), which is already in the tree but does
not fix the internal state/counter desync inside `mlx5_ib_enable_lb()`
itself.
That supports the earlier **YES** verdict: the bug is present here, and
this commit is still needed.
drivers/infiniband/hw/mlx5/main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 09709ae5bd471..09d76952372de 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1895,6 +1895,9 @@ int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp)
dev->lb.qps == 1) {
if (!dev->lb.enabled) {
err = mlx5_nic_vport_update_local_lb(dev->mdev, true);
+ if (err)
+ goto err_rollback;
+
dev->lb.enabled = true;
}
}
@@ -1902,6 +1905,14 @@ int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp)
mutex_unlock(&dev->lb.mutex);
return err;
+
+err_rollback:
+ if (td)
+ dev->lb.user_td--;
+ if (qp)
+ dev->lb.qps--;
+ mutex_unlock(&dev->lb.mutex);
+ return err;
}
void mlx5_ib_disable_lb(struct mlx5_ib_dev *dev, bool td, bool qp)
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18] RDMA/counter: Fix num_counters leak on bind_qp failure in alloc_and_bind()
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (4 preceding siblings ...)
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Fix state and counter desync on loopback enable failure Sasha Levin
@ 2026-08-31 13:24 ` Sasha Levin
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-5.10] rds: annotate data-race around rs_seen_congestion Sasha Levin
` (11 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:24 UTC (permalink / raw)
To: patches, stable
Cc: Tao Cui, Jason Gunthorpe, Sasha Levin, linux-rdma, linux-kernel
From: Tao Cui <cuitao@kylinos.cn>
[ Upstream commit 4fbc8230009f5b1bcd13cc74c5a6a43ddba141fd ]
When __rdma_counter_bind_qp() fails in alloc_and_bind(), the error path
jumps to err_mode which frees the counter without decrementing
port_counter->num_counters. The only place that decrements is
rdma_counter_free(), which is unreachable since the counter was never
successfully bound.
This leak accumulates across repeated failures, permanently preventing
the port from switching to AUTO mode (-EBUSY in __counter_set_mode())
and blocking the MANUAL→NONE auto-revert in rdma_counter_free(). When
the mode was NONE before the call, the MANUAL mode set by
__counter_set_mode() also leaks since the revert logic is never
reached.
Add an err_bind label between the num_counters increment and the
existing err_mode label. It decrements num_counters and mirrors the
MANUAL→NONE revert from rdma_counter_free(), ensuring the port state
is fully restored on bind failure.
Link: https://patch.msgid.link/r/20260520104546.1776253-2-cuitao@kylinos.cn
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: RDMA/counter num_counters leak fix
**Local tree:** Linux **6.18.44** (`git describe HEAD` → `v6.18.44`,
`make kernelversion` → `6.18.44`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Parse the subject line
**Record:** `[RDMA/counter]` `[Fix]` — Fix `num_counters` leak on
`bind_qp` failure in `alloc_and_bind()`.
### Step 1.2: Parse all commit message tags
**Record:**
- **Link:** `https://patch.msgid.link/r/20260520104546.1776253-2-
cuitao@kylinos.cn`
- **Signed-off-by:** Tao Cui `<cuitao@kylinos.cn>`
- **Signed-off-by:** Jason Gunthorpe `<jgg@nvidia.com>` (RDMA
maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
stable@vger.kernel.org`
- Notable: part of a 2-patch series; sibling patch (`1776253-3`) is
already backported to this tree as `9420871183eab`.
### Step 1.3: Analyze commit body
**Record:**
- **Bug:** On `__rdma_counter_bind_qp()` failure in `alloc_and_bind()`,
error path jumps to `err_mode` and frees the counter without
decrementing `port_counter->num_counters`.
- **Symptom:** Leak accumulates across repeated failures; port cannot
switch to AUTO mode (`-EBUSY` from `__counter_set_mode()`);
MANUAL→NONE auto-revert never runs; if mode was NONE before call,
MANUAL mode also leaks.
- **Root cause:** `num_counters` is incremented before bind; decrement
only happens in `rdma_counter_free()`, which is unreachable when bind
never succeeded.
- **Fix approach:** Add `err_bind` label that decrements `num_counters`
and mirrors MANUAL→NONE revert from `rdma_counter_free()`.
### Step 1.4: Detect hidden bug fixes
**Record:** Not disguised — explicitly a resource/state leak fix on an
error path.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory the changes
**Record:**
- **File:** `drivers/infiniband/core/counters.c` (+9 / -1 lines)
- **Function:** `alloc_and_bind()`
- **Scope:** Single-file surgical fix
### Step 2.2: Code flow change
**Record:**
- **Hunk 1 (bind failure):** `goto err_mode` → `goto err_bind`
- **Hunk 2 (new `err_bind`):** Lock `port_counter`, decrement
`num_counters`, if zero and MANUAL mode call
`__counter_set_mode(NONE)`, unlock, then fall through to `err_mode`
- **Before:** Bind failure leaked counter refcount state and left port
mode stuck
- **After:** Bind failure fully restores port counter state before
freeing counter object
### Step 2.3: Bug mechanism
**Record:** **Category:** Error-path resource/state leak (reference-
count-like counter + mode state machine).
- `num_counters++` at line 191 happens before `__rdma_counter_bind_qp()`
at line 199
- Current tree still has `goto err_mode` on failure (lines 200–201),
skipping decrement/revert
- Fix mirrors existing cleanup in `rdma_counter_free()` (lines 220–225)
### Step 2.4: Fix quality
**Record:** Obviously correct — duplicates proven cleanup logic from
`rdma_counter_free()`. Minimal, no API changes. Low regression risk;
uses existing lock and `__counter_set_mode()` patterns.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame changed lines
**Record:** Buggy lines blame to `e664048784506` (tree import merge).
Shallow stable-tree history; counters subsystem predates 6.18 (file
copyright 2019 Mellanox; sibling fix references `Fixes: 56594ae1d250`).
### Step 3.2: Follow Fixes: tag
**Record:** N/A — no `Fixes:` tag on this commit. Sibling patch fixes
`56594ae1d250` (mutex annotation commit in RDMA core).
### Step 3.3: Related file history
**Record:**
- `9420871183eab` — "RDMA/counter: Fix incorrect port index in
rdma_counter_init() error cleanup" — **already in this 6.18.44 tree**
(same author, same series, committed by Greg K-H)
- This `num_counters` leak fix is **not** yet in the tree
### Step 3.4: Author context
**Record:** Tao Cui authored both patches; Jason Gunthorpe (maintainer)
Signed-off-by and replied "Applied to for-next" on the series.
### Step 3.5: Dependencies
**Record:** Standalone 2-patch series; patches are independent. This
patch applies cleanly to current `counters.c` (pre-patch index
`c3aa6d7fc66b6` matches current file). No prerequisite commits required
beyond existing counters code.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original patch discussion
**Record:**
- **URL:** https://lkml.iu.edu/2605.2/07986.html (patch 1/2)
- **Cover:** https://lkml.iu.edu/2605.2/07985.html
- **Series:** 2 patches, both error-path fixes in `counters.c`
- **Maintainer response:** Jason Gunthorpe: "Applied to for-next"
(https://lists.openwall.net/linux-kernel/2026/05/25/1182)
- No NAKs found; no explicit stable nomination in thread
- `b4 dig -c <hash>` failed (commit not in local tree); lore.kernel.org
blocked by bot protection
### Step 4.2: Reviewers
**Record:** CC'd: `leon@kernel.org`, `linux-rdma@vger.kernel.org`,
`linux-kernel@vger.kernel.org`. Jason Gunthorpe reviewed and applied.
### Step 4.3: Bug report
**Record:** No external bug report or syzbot — found via code review in
a small 2-patch series.
### Step 4.4: Related patches
**Record:** Patch 2/2 (`rdma_counter_init()` port index) already
backported here as `9420871183eab` (upstream `b86fd95805a7`).
### Step 4.5: Stable mailing list
**Record:** Not searched (no stable-specific discussion found in
available sources).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `alloc_and_bind()`, `__rdma_counter_bind_qp()`,
`__counter_set_mode()`, `rdma_counter_free()`
### Step 5.2: Callers of `alloc_and_bind()`
**Record:**
- `rdma_counter_bind_qp_auto()` — called from `verbs.c` during QP
RST→INIT with port specified (common QP creation path)
- `rdma_counter_bind_qpn_alloc()` — called from `nldev.c` via RDMA
netlink/devlink counter configuration
### Step 5.3: Callees
**Record:** `__rdma_counter_bind_qp()` → driver `counter_bind_qp` op
(e.g. mlx5 `mlx5_ib_counter_bind_qp()` which can fail on hardware
counter allocation or flow binding)
### Step 5.4: Reachability
**Record:** Reachable from userspace via RDMA devlink netlink
(`nldev.c`) and from QP modification during IB/RDMA workload setup.
Unprivileged users with RDMA device access can trigger counter bind
operations.
### Step 5.5: Similar patterns
**Record:** Correct cleanup already exists in `rdma_counter_free()`;
this fix adds the missing mirror on the alloc/bind error path.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Does buggy code exist?
**Record:** **YES.** Current tree at lines 191–201 increments
`num_counters` then `goto err_mode` on bind failure without decrement:
```191:201:drivers/infiniband/core/counters.c
port_counter->num_counters++;
mutex_unlock(&port_counter->lock);
// ...
ret = __rdma_counter_bind_qp(counter, qp, port);
if (ret)
goto err_mode;
```
### Step 6.2: Backport complications
**Record:** Clean apply expected — file matches pre-patch blob index
from the patch (`c3aa6d7fc66b6`). Sibling fix from same series already
applied without conflict.
### Step 6.3: Related fixes already present?
**Record:** `9420871183eab` (rdma_counter_init port-index fix) is
present. This `num_counters` leak fix is **not** present.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** **RDMA/InfiniBand core** — IMPORTANT for HPC, cloud, and
RoCE deployments using hardware counters (mlx5, ionic, etc.)
### Step 7.2: Subsystem activity
**Record:** Actively maintained; recent stable backport activity in this
tree for same file/author.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users of RDMA hardware counters on devices with
`counter_bind_qp` support (notably mlx5). Config-dependent on
`CONFIG_INFINIBAND` and counter-capable hardware.
### Step 8.2: Trigger conditions
**Record:** Any `__rdma_counter_bind_qp()` failure after
`alloc_and_bind()` increments `num_counters` — e.g. mlx5 hardware
counter allocation failure (`mlx5_cmd_exec_inout`) or op-counter flow
binding failure (`mlx5r_fs_bind_op_fc`). Repeated failures accumulate
the leak.
### Step 8.3: Failure mode severity
**Record:** No kernel crash/oops, but **permanent functional breakage**
until reboot:
- `-EBUSY` when trying to enable AUTO mode
- Port stuck in MANUAL when it should revert to NONE
- Counter management via devlink becomes unusable
**Severity: MEDIUM-HIGH** (persistent admin/operational failure, not
data corruption or security)
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** Restores correct counter state on bind failure; completes
the already-started backport of this 2-patch series
- **Risk:** Very low — 9 lines mirroring existing `rdma_counter_free()`
logic
- **Ratio:** Favorable for backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real, verified state leak on error path in production RDMA counter
code
- User-visible permanent `-EBUSY` / stuck MANUAL mode until reboot
- Small, obviously correct fix reviewed by RDMA maintainer
- Buggy code confirmed present in Linux 6.18.44
- Companion patch from same series already backported to this tree
- Reachable from userspace devlink and QP creation paths
- `mlx5_ib_counter_bind_qp()` has multiple real failure paths
**AGAINST backport:**
- Not a crash, security issue, or data corruption
- Only affects RDMA counter users (subset of kernel users)
- Requires bind failure (not every-day path)
- No syzbot/user bug report
**Unresolved:** Exact upstream commit SHA not in local tree; precise
introduction commit of `alloc_and_bind()` error path not determinable
from shallow stable history (but code clearly present and long-
standing).
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — mirrors
`rdma_counter_free()`; maintainer applied to for-next
2. Fixes real bug affecting users? **PASS** — state leak with permanent
counter-mode breakage
3. Important issue? **PASS (moderate)** — persistent functional failure
of RDMA counter subsystem, not crash-level but operationally
significant
4. Small and contained? **PASS** — 9 lines, 1 file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — code present, clean apply
expected
### Step 9.3: Exception categories
**Record:** N/A — standard error-path bug fix, not device
ID/quirk/build/doc exception.
### Step 9.4: Decision rationale
This commit fixes a genuine error-path state leak in `alloc_and_bind()`
that leaves `num_counters` inflated and can permanently block AUTO mode
(`-EBUSY`) or leave ports stuck in MANUAL mode. The bug is present in
this 6.18.44 tree, the fix is minimal and mirrors existing cleanup
logic, and the sibling patch from the same 2-patch series is already
backported here. While the failure mode is operational rather than a
kernel panic, the impact is persistent until reboot and affects real
RDMA counter management paths used in production InfiniBand/RoCE
environments.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body from provided commit message
- **[Phase 1]** Confirmed part of 2-patch series via lkml cover letter
(https://lkml.iu.edu/2605.2/07985.html)
- **[Phase 2]** Read diff: +9/-1 in `alloc_and_bind()`, new `err_bind`
label
- **[Phase 2]** Read current `counters.c` lines 145–232: confirmed bug
at 200–201 (`goto err_mode` without decrement)
- **[Phase 2]** Read `rdma_counter_free()` lines 215–225: confirmed fix
mirrors existing cleanup
- **[Phase 2]** Read `__counter_set_mode()` lines 13–28: confirmed
`-EBUSY` when `num_counters != 0` in AUTO mode
- **[Phase 3]** `git describe HEAD` → v6.18.44; `make kernelversion` →
6.18.44
- **[Phase 3]** `git blame -L 191,201`: lines present in tree
- **[Phase 3]** `git log --grep="num_counters leak"` → empty (fix not
applied)
- **[Phase 3]** `git show 9420871183eab`: sibling patch already
backported to this tree
- **[Phase 4]** lkml.iu.edu/2605.2/07986.html: patch content matches
- **[Phase 4]** lists.openwall.net reply: Jason Gunthorpe "Applied to
for-next"
- **[Phase 4]** `b4 dig -c <hash>`: failed (commit not in tree) —
UNVERIFIED via b4
- **[Phase 4]** lore.kernel.org: blocked by bot protection — UNVERIFIED
via lore
- **[Phase 5]** `grep alloc_and_bind`: callers in
`rdma_counter_bind_qp_auto()` and `rdma_counter_bind_qpn_alloc()`
- **[Phase 5]** `verbs.c:1854`: `rdma_counter_bind_qp_auto()` on QP
RST→INIT
- **[Phase 5]** `nldev.c:2050-2064`: netlink paths to counter bind/auto-
mode
- **[Phase 5]** `mlx5/counters.c:624-669`: `mlx5_ib_counter_bind_qp()`
has failure paths returning errors
- **[Phase 6]** Confirmed buggy code exists at lines 191–201 in local
tree
- **[Phase 6]** Confirmed fix NOT applied (`grep err_bind` in counters.c
→ no match)
- **[Phase 6]** Confirmed sibling fix IS applied (rdma_counter_init uses
`port_data[i]` at line 664)
- **[Phase 8]** Assessed failure mode: permanent `-EBUSY`/stuck MANUAL,
severity MEDIUM-HIGH
**YES**
drivers/infiniband/core/counters.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/counters.c b/drivers/infiniband/core/counters.c
index 5dad5d77ce274..a9e189194c130 100644
--- a/drivers/infiniband/core/counters.c
+++ b/drivers/infiniband/core/counters.c
@@ -198,12 +198,20 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u32 port,
ret = __rdma_counter_bind_qp(counter, qp, port);
if (ret)
- goto err_mode;
+ goto err_bind;
rdma_restrack_parent_name(&counter->res, &qp->res);
rdma_restrack_add(&counter->res);
return counter;
+err_bind:
+ mutex_lock(&port_counter->lock);
+ port_counter->num_counters--;
+ if (!port_counter->num_counters &&
+ port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL)
+ __counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0,
+ false);
+ mutex_unlock(&port_counter->lock);
err_mode:
rdma_free_hw_stats_struct(counter->stats);
err_stats:
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.10] rds: annotate data-race around rs_seen_congestion
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (5 preceding siblings ...)
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18] RDMA/counter: Fix num_counters leak on bind_qp failure in alloc_and_bind() Sasha Levin
@ 2026-08-31 13:24 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] net/mlx5e: Verify unique vhca_id count instead of range Sasha Levin
` (10 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:24 UTC (permalink / raw)
To: patches, stable
Cc: Jiayuan Chen, syzbot+fbf3648ae7f5bdb05c59, Allison Henderson,
Jakub Kicinski, Sasha Levin, davem, edumazet, pabeni, netdev,
linux-rdma, rds-devel, linux-kernel
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 67636cab273ed0c0b0f2adab6c9369a471cb7966 ]
rs_seen_congestion is read in rds_poll() and written in rds_sendmsg()
and rds_poll() without any lock. Use READ_ONCE()/WRITE_ONCE() to
annotate these lockless accesses and silence KCSAN.
Reported-by: syzbot+fbf3648ae7f5bdb05c59@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a0f8d94.050a0220.6b33c.0000.GAE@google.com/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Allison Henderson <achender@kernel.org>
Tested-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260522011621.304470-1-jiayuan.chen@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The backport check finished: prepared stable commit `95ef1f3da4846`
(upstream `67636cab273ed`) exists on the `autosel` branch but is not in
current HEAD (`v6.18.44`), where the unannotated `rs_seen_congestion`
accesses are still present. That supports the **YES** backport
recommendation.
net/rds/af_rds.c | 4 ++--
net/rds/send.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index cc3a898bf5d51..a9445937d225b 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -217,7 +217,7 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
poll_wait(file, sk_sleep(sk), wait);
- if (rs->rs_seen_congestion)
+ if (READ_ONCE(rs->rs_seen_congestion))
poll_wait(file, &rds_poll_waitq, wait);
read_lock_irqsave(&rs->rs_recv_lock, flags);
@@ -245,7 +245,7 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
/* clear state any time we wake a seen-congested socket */
if (mask)
- rs->rs_seen_congestion = 0;
+ WRITE_ONCE(rs->rs_seen_congestion, 0);
return mask;
}
diff --git a/net/rds/send.c b/net/rds/send.c
index 071c5dca969a2..d474c9cda65ae 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1339,7 +1339,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs);
if (ret) {
- rs->rs_seen_congestion = 1;
+ WRITE_ONCE(rs->rs_seen_congestion, 1);
goto out;
}
while (!rds_send_queue_rm(rs, conn, cpath, rm, rs->rs_bound_port,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-6.12] net/mlx5e: Verify unique vhca_id count instead of range
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (6 preceding siblings ...)
2026-08-31 13:24 ` [PATCH AUTOSEL 6.18-5.10] rds: annotate data-race around rs_seen_congestion Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] net/mlx5: HWS, Handle destroying table that has a miss table Sasha Levin
` (9 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Shay Drory, Mark Bloch, Tariq Toukan, Jakub Kicinski, Sasha Levin,
saeedm, andrew+netdev, davem, edumazet, pabeni, netdev,
linux-rdma, linux-kernel
From: Shay Drory <shayd@nvidia.com>
[ Upstream commit 0b1c4495aa007932e9cbd7b45a8037e7b4fe34b0 ]
Change verify_num_vhca_ids() to count the number of unique vhca_ids
and verify this count doesn't exceed max_num_vhca_id, rather than
validating individual vhca_id values are within a specific range.
The previous implementation checked if each vhca_id was in the range
[0, max_num_vhca_id - 1], which is overly restrictive. The hardware
capability max_rqt_vhca_id represents the maximum number of unique
vhca_ids that can be used, not a range constraint on individual IDs.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260531113954.395443-14-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
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: `[net/mlx5e] [verify/change] Verify unique vhca_id count instead
of range` — mlx5e RQT validation correction.
**Step 1.2 — Tags**
Record:
- `Signed-off-by: Shay Drory <shayd@nvidia.com>` (author)
- `Reviewed-by: Mark Bloch <mbloch@nvidia.com>`
- `Signed-off-by: Tariq Toukan <tariqt@nvidia.com>`
- `Link:
https://patch.msgid.link/20260531113954.395443-14-tariqt@nvidia.com`
(patch 14 of a series)
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev maintainer
merge)
- No `Fixes:`, `Reported-by:`, `Cc: stable@vger.kernel.org`, or syzbot
tags
- Notable: NVIDIA internal review + netdev maintainer merge; no
user/fuzzer reports
**Step 1.3 — Body analysis**
Record:
- **Bug:** `verify_num_vhca_ids()` treats `max_rqt_vhca_id` as an upper
bound on each individual `vhca_id` value (`[0, max-1]`), but hardware
defines it as the maximum number of *distinct* `vhca_id` values
allowed in an RQT.
- **Symptom:** Valid cross-vHCA RQT configurations are rejected when
actual hardware `vhca_id` values exceed that numeric limit, even when
the number of unique IDs is within capability.
- **Root cause:** Semantic mismatch between driver validation and
hardware capability definition.
- **Versions:** Not stated in the commit message.
**Step 1.4 — Hidden bug fix?**
Record: Yes. Despite no "fix" in the subject, this corrects broken
validation logic introduced with cross-vHCA RSS. It is a functional bug
fix, not a refactor or optimization.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `drivers/net/ethernet/mellanox/mlx5/core/en/rqt.c` (+15 / -5
net)
- **Function modified:** `verify_num_vhca_ids()` only
- **Scope:** Single-file, single-function surgical change
**Step 2.2 — Code flow change**
Record:
- **Hunk 1 (before):** Loop all entries; reject if any `vhca_ids[i] >=
max_num_vhca_id`.
- **Hunk 1 (after):** Count unique `vhca_ids` via nested loop; accept if
`unique_count <= max_num_vhca_id`.
- **Affected paths:** All callers of `rqt_verify_vhca_ids()`:
- `mlx5e_rqt_init()` — returns `-EOPNOTSUPP` on failure
- `mlx5e_rqt_redirect()` — returns `-EINVAL` on failure
- `mlx5e_rqt_redirect_indir()` — pre-check before RSS indirection
redirect
**Step 2.3 — Bug mechanism**
Record:
- **Category:** Logic / correctness fix (incorrect parameter semantics)
- **Mechanism:** `max_rqt_vhca_id` is a *count* cap, not a per-ID range.
Actual `vhca_id` values come from `MLX5_CAP_GEN(mdev, vhca_id)`
(firmware-assigned), while `sd.c` already compares `host_buses >
max_rqt_vhca_id` as a count. The RQT validator used the wrong
interpretation, rejecting configurations that `sd.c` already approved.
**Step 2.4 — Fix quality**
Record:
- Fix is obviously correct and consistent with `mlx5_sd_is_supported()`
in `sd.c`.
- Minimal scope; no API changes.
- **Regression risk:** Low. Worst case is allowing configurations
hardware already supports. Uniqueness counting is O(n²), but `n` is
bounded by channel count (SD max group size is 2).
- No new locking or memory management changes.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record:
- Buggy validation introduced in `40e6ad9182b48` ("net/mlx5e: Support
cross-vhca RSS", Tariq Toukan, 2024-02-14, merged 2024-03-07).
- Present in local tree `v6.18.44` (confirmed ancestor of HEAD).
- Bug has existed since the cross-vHCA RSS feature landed.
**Step 3.2 — Fixes: tag**
Record: N/A — no `Fixes:` tag in commit message.
**Step 3.3 — Related file history**
Record:
- `rqt.c` history: cross-vHCA RSS (`40e6ad9182b48`), XOR hash channel
limit (`49e6c93870517`), earlier RQT object conversion.
- SD support added separately in `sd.c` (2023–2024 commits); uses
correct count semantics for `max_rqt_vhca_id`.
- Standalone fix; not part of a multi-patch dependency chain for this
specific change.
**Step 3.4 — Author context**
Record: Tariq Toukan authored the original cross-vHCA RSS code and is a
regular mlx5/mlx5e contributor. Shay Drory (fix author) is also an
NVIDIA mlx5 contributor.
**Step 3.5 — Dependencies**
Record: No prerequisite commits required. The diff only modifies an
existing static function in code already present in this tree. Applies
cleanly to current `rqt.c`.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: `b4 dig -c <commit>` could not be run — the fix commit is not in
this checkout. `Link:` URL and lore.kernel.org fetch blocked by Anubis
bot protection. **UNVERIFIED:** full mailing list thread content and any
explicit stable nominations.
**Step 4.2 — Reviewers**
Record: **UNVERIFIED** via `b4 dig -w`. From commit message: Mark Bloch
(NVIDIA reviewer), Tariq Toukan, Jakub Kicinski (netdev maintainer).
**Step 4.3 — Bug reports**
Record: No `Reported-by:` or bugzilla/syzbot links. No external crash
report — this is a driver logic bug found/reviewed internally.
**Step 4.4 — Series context**
Record: Link indicates patch 14/N of a larger tariqt series
(`20260531113954.395443-14`). This specific patch is self-contained (one
function in one file); no evidence other series patches are required.
**Step 4.5 — Stable list history**
Record: **UNVERIFIED** — could not search lore stable archive due to bot
protection.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `verify_num_vhca_ids()` (modified); callers via
`rqt_verify_vhca_ids()`.
**Step 5.2 — Callers**
Record:
- `mlx5e_rqt_init()` — RQT creation during RSS setup
- `mlx5e_rqt_redirect()` — RQT modification during channel activation
- `mlx5e_rqt_redirect_indir()` — RSS indirection table updates
In SD multi-vHCA mode (`MLX5E_RX_RES_FEATURE_MULTI_VHCA`, enabled when
`mlx5_get_sd()` is set in `en_main.c`):
- `mlx5e_channels_get_regular_rqn()` / `mlx5e_channels_get_xsk_rqn()`
populate `vhca_id` from `MLX5_CAP_GEN(c->mdev, vhca_id)`
- SD channels map to different `mlx5_core_dev` instances via
`mlx5_sd_ch_ix_get_dev()` in `en_main.c`
- `mlx5e_rx_res_channels_activate()` drives RSS enable and per-channel
direct RQT redirect
**Step 5.3 — Callees**
Record: Uses `MLX5_CAP_GEN_2(mdev, max_rqt_vhca_id)` only; no
allocations or locks.
**Step 5.4 — Reachability**
Record:
- Triggered during netdev open/channel activation on mlx5e devices with
Socket Direct + `cross_vhca_rqt` hardware.
- Not a direct syscall path, but reached during normal driver operation
on supported enterprise NIC configurations.
- SD is niche but is a supported, production feature path.
**Step 5.5 — Similar patterns**
Record: `mlx5_sd_is_supported()` in `sd.c:116` correctly uses
`host_buses > MLX5_CAP_GEN_2(dev, max_rqt_vhca_id)` as a count
comparison. The RQT validator was the outlier using range semantics.
---
## Phase 6: Cross-Reference Against Local Tree (v6.18.44)
**Step 6.1 — Buggy code present?**
Record: **Yes.** Current `rqt.c` lines 7–17 contain the range-based
check. Fix commit is **not** yet applied. Bug introduced in
`40e6ad9182b48`, which is an ancestor of HEAD.
**Step 6.2 — Backport complications**
Record: Expected **clean apply** — single hunk in an unchanged function
with no surrounding churn in recent `rqt.c` history.
**Step 6.3 — Related fixes already present?**
Record: No alternate fix for this issue found in tree. `git log
--grep="unique vhca_id"` returned nothing.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: `drivers/net/ethernet/mellanox/mlx5` — mlx5e NIC driver.
**Criticality: IMPORTANT** (enterprise NIC driver, not core kernel, but
networking data path).
**Step 7.2 — Activity**
Record: mlx5/mlx5e actively maintained; SD and cross-vHCA RSS are
relatively recent additions (2023–2024).
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users of Mellanox/NVIDIA ConnectX **Socket Direct** multi-PF
setups with `cross_vhca_rqt` hardware capability. Config-specific,
platform-specific — not universal.
**Step 8.2 — Trigger conditions**
Record:
- SD group configured (`mlx5_get_sd()` non-NULL)
- `MLX5E_RX_RES_FEATURE_MULTI_VHCA` enabled
- Actual firmware-assigned `vhca_id` values ≥ `max_rqt_vhca_id` (common
when IDs are not 0-based indices)
- Triggered on channel activation / RSS RQT redirect — not a race;
deterministic validation failure
**Step 8.3 — Failure mode severity**
Record:
- `mlx5e_rqt_init()` → `-EOPNOTSUPP`
- `mlx5e_rqt_redirect()` / `mlx5e_rqt_redirect_indir()` → `-EINVAL`
- `mlx5e_rx_res_channel_activate_direct()` logs warning on redirect
failure
- **Result:** Cross-vHCA RSS and RX steering from primary to secondaries
broken — **functional networking failure** for SD users
- **Severity: HIGH** for affected deployments (broken networking), but
**not CRITICAL** (no kernel crash, no memory corruption, no security
issue)
**Step 8.4 — Risk vs benefit**
Record:
- **Benefit:** Restores a supported hardware feature that has been
broken since introduction whenever `vhca_id` values exceed the
capability number; aligns driver with hardware semantics and with
`sd.c`.
- **Risk:** Very low — ~20 lines, vendor-reviewed, no structural
changes.
- **Ratio:** Good benefit for SD users at minimal risk, but narrow
audience.
---
## Phase 9: Final Synthesis
**Step 9.1 — Evidence summary**
**FOR backport:**
- Real, verified logic bug since cross-vHCA RSS landed (`40e6ad9182b48`)
- Buggy code confirmed present in local v6.18.44 tree
- Breaks Socket Direct cross-vHCA RX steering (production networking
failure for affected hardware)
- Small, surgical, vendor-reviewed fix
- Consistent with existing `sd.c` interpretation of `max_rqt_vhca_id`
- No dependencies; clean apply expected
- No new APIs or features
**AGAINST backport:**
- Very niche hardware (Socket Direct, max 2 PFs per
`MLX5_SD_MAX_GROUP_SZ`)
- No crash, corruption, deadlock, or security impact
- No syzbot/user bug reports
- Some SD configs may coincidentally pass the old check if `vhca_id`
values happen to be small
- Mailing list/stable discussion not verified
**Unresolved:**
- Whether the bug manifests on all real SD deployments (depends on
firmware `vhca_id` assignment)
- Full lore review thread content
**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — semantics match `sd.c` and
commit explanation; NVIDIA-reviewed.
2. Fixes a real bug affecting users? **PASS** — incorrect validation
rejects valid HW configs on SD+cross-vHCA path.
3. Important issue? **PASS (borderline)** — functional networking
breakage for SD users, not crash/corruption.
4. Small and contained? **PASS** — one function, ~20 lines.
5. No new features or APIs? **PASS**.
6. Can apply to local tree? **PASS** — code exists, fix not yet present,
clean apply expected.
**Step 9.3 — Exception categories**
Record: Hardware workaround / driver correctness fix for an existing
feature — analogous to quirk/correctness fixes for supported enterprise
hardware. Not a device-ID addition, build fix, or docs fix.
**Step 9.4 — Decision rationale**
This is a genuine driver bug that has been present since cross-vHCA RSS
was added to this tree. It causes Socket Direct multi-PF RX steering to
fail when firmware-assigned `vhca_id` values do not fall in `[0,
max_rqt_vhca_id)`, which is the expected interpretation of a *count*
capability. The fix is minimal, low-risk, vendor-authored, and restores
functionality for a supported enterprise NIC configuration. While the
audience is narrow and the failure mode is functional rather than a
kernel panic, broken networking on production SD deployments meets the
stable bar for driver correctness fixes to existing hardware support.
---
## Verification
- [Phase 1] Parsed commit message tags from user-provided commit text
- [Phase 2] Read current `rqt.c` and traced `rqt_verify_vhca_ids()` call
chain
- [Phase 3] `git blame -L 7,18 rqt.c`: buggy code from `40e6ad9182b48`
(2024-02-14)
- [Phase 3] `git show 40e6ad9182b48`: confirmed original range-based
validation at introduction
- [Phase 3] `git merge-base --is-ancestor 40e6ad9182b48 HEAD`: buggy
commit IS in v6.18.44 tree
- [Phase 3] `git log --oneline -20 -- rqt.c`: no conflicting later
changes
- [Phase 4] `b4 dig`: could not run — fix commit not in checkout
- [Phase 4] WebFetch lore/patch.msgid.link: blocked by Anubis —
**UNVERIFIED** mailing list discussion
- [Phase 5] `grep vhca_ids` in `en/`: traced population via `channels.c`
→ `MLX5_CAP_GEN(c->mdev, vhca_id)`
- [Phase 5] Read `en_main.c:2769` — SD channels use
`mlx5_sd_ch_ix_get_dev()` for per-PF `mdev`
- [Phase 5] Read `sd.c:116` — `max_rqt_vhca_id` used as count limit for
`host_buses`
- [Phase 5] Read `rx_res.c:578-598` — channel activation populates
vhca_ids and enables RSS
- [Phase 6] `git describe HEAD` / `make kernelversion`: **v6.18.44 /
6.18.44**
- [Phase 6] Current `rqt.c` lines 13-16: range check still present (fix
NOT applied)
- [Phase 6] `git log --grep="unique vhca_id"`: no existing fix in tree
- [Phase 8] `MLX5_SD_MAX_GROUP_SZ` = 2 in `sd.h` — bounded input size
for uniqueness loop
- [Phase 8] Failure paths verified: `-EOPNOTSUPP` in `mlx5e_rqt_init`,
`-EINVAL` in redirect paths
**YES**
.../net/ethernet/mellanox/mlx5/core/en/rqt.c | 27 ++++++++++++++-----
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rqt.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rqt.c
index 8d9a3b5ec973b..c845ed8f9ebfa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rqt.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rqt.c
@@ -8,13 +8,28 @@ static bool verify_num_vhca_ids(struct mlx5_core_dev *mdev, u32 *vhca_ids,
unsigned int size)
{
unsigned int max_num_vhca_id = MLX5_CAP_GEN_2(mdev, max_rqt_vhca_id);
- int i;
+ unsigned int unique_count = 0;
+ int i, j;
+
+ /* Count unique vhca_ids */
+ for (i = 0; i < size; i++) {
+ bool is_unique = true;
+
+ /* Check if vhca_ids[i] was already seen */
+ for (j = 0; j < i; j++) {
+ if (vhca_ids[j] == vhca_ids[i]) {
+ is_unique = false;
+ break;
+ }
+ }
+ if (is_unique)
+ unique_count++;
+ }
- /* Verify that all vhca_ids are in range [0, max_num_vhca_ids - 1] */
- for (i = 0; i < size; i++)
- if (vhca_ids[i] >= max_num_vhca_id)
- return false;
- return true;
+ /* Verify that number of unique vhca_ids doesn't exceed
+ * max_num_vhca_id
+ */
+ return unique_count <= max_num_vhca_id;
}
static bool rqt_verify_vhca_ids(struct mlx5_core_dev *mdev, u32 *vhca_ids,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-6.12] net/mlx5: HWS, Handle destroying table that has a miss table
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (7 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] net/mlx5e: Verify unique vhca_id count instead of range Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.10] rds: filter RDS_INFO_* getsockopt by caller's netns Sasha Levin
` (8 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Yevgeny Kliteynik, Erez Shitrit, Moshe Shemesh, Tariq Toukan,
Jakub Kicinski, Sasha Levin, saeedm, mbloch, andrew+netdev, davem,
edumazet, pabeni, netdev, linux-rdma, linux-kernel
From: Yevgeny Kliteynik <kliteyn@nvidia.com>
[ Upstream commit 60e9e82f162ab7399373ff2185119289e4f6dc06 ]
If a table has a miss table that was created by
'mlx5hws_table_set_default_miss' API function, its miss_tbl
keeps the table that points to it in a list.
If such table is deleted, we need to also remove it from the
miss_tbl list, otherwise the node in miss_tbl list will contain
garbage.
Signed-off-by: Erez Shitrit <erezsh@nvidia.com>
Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260507173443.320465-3-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background `b4 dig` run finished without useful results: looking up
the wrong commit (`5d324e5159d9e`, the USB merge) found no lore match,
and the subject-line search failed because `b4 dig` doesn’t accept a
patch title as a positional argument.
That doesn’t change the earlier conclusion. The patch content and review
context came from the local mbox
(`20260507_tariqt_net_mlx5_steering_misc_enhancements.mbx`), and the
backport recommendation for this 6.18.43 tree remains **YES**.
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
index 6113383ae47bb..07a3dd1248c77 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
@@ -282,6 +282,9 @@ int mlx5hws_table_destroy(struct mlx5hws_table *tbl)
goto unlock_err;
}
+ if (tbl->default_miss.miss_tbl)
+ list_del_init(&tbl->default_miss.next);
+
list_del_init(&tbl->tbl_list_node);
mutex_unlock(&ctx->ctrl_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.10] rds: filter RDS_INFO_* getsockopt by caller's netns
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (8 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] net/mlx5: HWS, Handle destroying table that has a miss table Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] net/mlx5: HWS, Check if device is down while polling for completion Sasha Levin
` (7 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Maoyi Xie, Allison Henderson, Simon Horman, Praveen Kakkolangara,
Jakub Kicinski, Sasha Levin, davem, edumazet, pabeni, netdev,
linux-rdma, rds-devel, linux-kernel
From: Maoyi Xie <maoyixie.tju@gmail.com>
[ Upstream commit c96a5209dda666004b8ee1ed7f0d493d09a4f200 ]
The RDS_INFO_* family of getsockopt(2) options reads several
file-scope global lists that are not per-netns:
rds_sock_info / rds6_sock_info,
rds_sock_inc_info / rds6_sock_inc_info -> rds_sock_list
rds_tcp_tc_info / rds6_tcp_tc_info -> rds_tcp_tc_list
rds_conn_info / rds6_conn_info,
rds_conn_message_info_cmn (for the *_SEND_MESSAGES and
*_RETRANS_MESSAGES variants),
rds_for_each_conn_info (for RDS_INFO_IB_CONNECTIONS)
-> rds_conn_hash[]
The handlers do not filter by the caller's network namespace.
rds_info_getsockopt() has no netns or capable() check, and
rds_create() has no capable() check, so AF_RDS is reachable from
an unprivileged user namespace. As a result, an unprivileged
caller in a fresh user_ns plus netns can read the bound address
and sock inode of every RDS socket on the host, the peer address
of incoming messages on every RDS socket on the host, the peer
address and TCP sequence numbers of every rds-tcp connection on
the host, and the peer address and RDS sequence numbers of every
RDS connection on the host.
The rds-tcp transport is reachable from a non-initial netns (see
rds_set_transport()), so a one-shot init_net gate at
rds_info_getsockopt() would deny legitimate per-netns visibility
to rds-tcp callers. Instead, filter at each handler by comparing
the netns of the caller's socket to the netns of the list entry,
or to rds_conn_net(conn) for connection paths. Only copy entries
whose netns matches the caller. Counters (RDS_INFO_COUNTERS) are
aggregate statistics and remain global.
Reproducer (KASAN VM, rds and rds_tcp loaded): an AF_RDS socket
binds 127.0.0.1:4242 in init_net as root. A child process enters
a fresh user_ns plus netns and opens AF_RDS there, then calls
getsockopt(SOL_RDS, RDS_INFO_SOCKETS). Before this change, the
child sees the init_net socket. After this change, the child
sees zero entries.
Drop the rds_sock_count, rds_tcp_tc_count, and rds6_tcp_tc_count
globals. v2 used them for the size precheck and lens->nr; v3
replaced the precheck with a per-ns count from a first pass over
the list, so the globals have no remaining readers. The matching
increments and decrements in rds_create()/rds_destroy_sock() and
rds_tcp_set_callbacks()/rds_tcp_restore_callbacks() go away with
them. Reported by the kernel test robot under clang W=1.
Suggested-by: Allison Henderson <achender@kernel.org>
Suggested-by: Simon Horman <horms@kernel.org>
Reviewed-by: Allison Henderson <achender@kernel.org>
Co-developed-by: Praveen Kakkolangara <praveen.kakkolangara@aumovio.com>
Signed-off-by: Praveen Kakkolangara <praveen.kakkolangara@aumovio.com>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://patch.msgid.link/20260520084236.2724349-1-maoyixie.tju@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `rds: filter RDS_INFO_* getsockopt by
caller's netns`
**Local tree:** `v6.18.44` (`linux-6.18.y` stable). The vulnerable code
is present; this fix is not yet applied.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: PARSE THE SUBJECT LINE
**Record:** `[net/rds]` `[filter]` — Restrict `RDS_INFO_*` getsockopt
handlers to return only data from the caller's network namespace.
### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
**Record:**
- **Suggested-by:** Allison Henderson `<achender@kernel.org>`, Simon
Horman `<horms@kernel.org>` — subsystem experts identified the issue
- **Reviewed-by:** Allison Henderson `<achender@kernel.org>` — RDS
maintainer review
- **Co-developed-by:** Praveen Kakkolangara
- **Signed-off-by:** Praveen Kakkolangara, Maoyi Xie, Jakub Kicinski
- **Link:** https://patch.msgid.link/20260520084236.2724349-1-
maoyixie.tju@gmail.com
- No `Fixes:`, `Reported-by: syzbot`, or `Cc: stable@vger.kernel.org`
(expected for pipeline candidates)
- Notable: Reviewed by subsystem maintainer; security issue identified
by maintainers, not a fuzzer report
### Step 1.3: ANALYZE THE COMMIT BODY TEXT
**Record:**
- **Bug:** `RDS_INFO_*` getsockopt handlers iterate global lists
(`rds_sock_list`, `rds_tcp_tc_list`, `rds_conn_hash[]`) without
filtering by the caller's netns
- **Symptom:** Unprivileged process in a fresh `user_ns` + `netns` can
read host-wide RDS socket addresses/inodes, peer addresses, TCP
sequence numbers, and RDS sequence numbers
- **Root cause:** `rds_info_getsockopt()` has no netns/capability check;
`rds_create()` has no `capable()` check; AF_RDS is reachable from
unprivileged user namespaces; global lists are not per-netns
- **Reproducer:** Documented — root binds AF_RDS in init_net; child in
new user_ns+netns calls `getsockopt(SOL_RDS, RDS_INFO_SOCKETS)` and
sees init_net sockets before fix, zero after
- **Design note:** Cannot use a blanket `init_net` gate because rds-tcp
legitimately works in non-init netns
### Step 1.4: DETECT HIDDEN BUG FIXES
**Record:** Not disguised — this is an explicit security/access-control
fix. Secondary cleanup drops unused global counters (`rds_sock_count`,
`rds_tcp_tc_count`, `rds6_tcp_tc_count`) after switching to per-netns
two-pass counting.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: INVENTORY THE CHANGES
**Record:**
- `net/rds/af_rds.c` — ~+80/-30 lines: netns filtering in
`rds_sock_inc_info`, `rds6_sock_inc_info`, `rds_sock_info`,
`rds6_sock_info`; remove `rds_sock_count` global and its inc/dec
- `net/rds/connection.c` — ~+20 lines: netns filter in
`rds_conn_message_info_cmn`, `rds_for_each_conn_info`,
`rds_walk_conn_path_info`
- `net/rds/tcp.c` — ~+50/-20 lines: netns filtering in
`rds_tcp_tc_info`, `rds6_tcp_tc_info`; remove
`rds_tcp_tc_count`/`rds6_tcp_tc_count` globals
- **Functions modified:** 9 info-export handlers + socket create/destroy
callback paths (counter removal only)
- **Scope:** Multi-file but single-purpose; no API changes
### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
**Record:**
- **Before:** Each handler walks entire global list and copies all
matching entries regardless of netns
- **After:** Each handler gets `struct net *net = sock_net(sock->sk)`,
skips entries where `!net_eq(sock_net(rds_rs_to_sk(rs)), net)` or
`!net_eq(rds_conn_net(conn), net)`, uses two-pass count-then-copy for
size precheck
- **Affected path:** `getsockopt(SOL_RDS, RDS_INFO_*)` — userspace
diagnostic path, but reachable from unprivileged netns
### Step 2.3: IDENTIFY THE BUG MECHANISM
**Record:**
- **Category:** Security — cross-network-namespace information
disclosure
- **Mechanism:** Global data structures shared across all netns;
getsockopt handlers lacked netns scoping. Unprivileged
container/namespace user reads host-wide connection metadata including
TCP/RDS sequence numbers useful for traffic analysis or hijacking
### Step 2.4: ASSESS THE FIX QUALITY
**Record:**
- Fix is obviously correct — standard `net_eq()` pattern already used in
this subsystem (`recv.c:377`)
- Minimal per-handler filtering; preserves legitimate per-netns rds-tcp
visibility
- Low regression risk: only restricts over-broad data export;
`RDS_INFO_COUNTERS` intentionally remains global per commit message
- Two-pass counting handles buffer sizing correctly; comment documents
benign race with concurrent `rds_bind()`
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: BLAME THE CHANGED LINES
**Record:** Info handlers in `af_rds.c` trace to long-standing RDS code
(blame shows merge commit `e664048784506` for current lines). Global
`rds_sock_list` without netns filtering is architectural debt from
before per-netns RDS-TCP support. RDS-TCP netns support added in
`d5a8ac28a7ff` (Aug 2015). Bug became exploitable when unprivileged user
namespaces could create isolated netns (Linux 3.8+) and open AF_RDS
sockets without capability checks.
### Step 3.2: FOLLOW THE FIXES: TAG
**Record:** No `Fixes:` tag present — N/A.
### Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
**Record:** Related fixes already in this tree:
- `a7494479757d6` — restrict RDS/IB transport to init_net (partial
mitigation, does not fix getsockopt leak)
- `9591042533140` — drop cross-netns incoming messages (UAF fix in recv
path)
- `91ce1bb6e4194` — zero per-item info buffers (stack leak fix,
complementary)
This fix is **standalone** — no series dependency.
### Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
**Record:** Maoyi Xie has multiple net-namespace security fixes in
networking (e.g., requiring `CAP_NET_ADMIN` for tunnel changelink). Co-
authors Praveen Kakkolangara and reviewer Allison Henderson are active
RDS contributors/maintainers.
### Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
**Record:** Requires `rds_conn_net()` helper — **present** in this tree
(`rds.h:174-177`). Requires `read_pnet`/`write_pnet` on `conn->c_net` —
**present**. No other prerequisites. Should apply cleanly.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
**Record:** `b4 dig -c <sha>` could not run — commit not in local tree.
Web search found patch series v3→v5 on netdev/linux-kernel lists (May
2026). Final version is v5. Reviewed-by Allison Henderson on committed
version. Could not fetch lore/patch.msgid.link (bot protection/timeout).
### Step 4.2: CHECK WHO REVIEWED THE PATCH
**Record:** CC list from v5 includes netdev, linux-rdma, rds-devel
maintainers (David Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni).
Reviewed-by Allison Henderson (RDS maintainer).
### Step 4.3: SEARCH FOR THE BUG REPORT
**Record:** No syzbot/bugzilla link. Issue identified by RDS maintainers
(Suggested-by Henderson, Horman). Reproducer included in commit message.
Kernel test robot noted unused globals (W=1), not the security bug
itself.
### Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
**Record:** Standalone 1-patch fix; evolved v1→v5 during review (v3
addressed two-pass counting feedback from Simon Horman). No other
patches required.
### Step 4.5: CHECK STABLE MAILING LIST HISTORY
**Record:** Not searched — commit not yet in stable tree. No evidence
against backport found.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
**Record:** `rds_sock_info`, `rds6_sock_info`, `rds_sock_inc_info`,
`rds6_sock_inc_info`, `rds_conn_message_info_cmn`,
`rds_for_each_conn_info`, `rds_walk_conn_path_info`, `rds_tcp_tc_info`,
`rds6_tcp_tc_info`
### Step 5.2: TRACE CALLERS
**Record:** All called from `rds_info_getsockopt()` (`info.c:208`) via
registered function table, which is invoked from `rds_getsockopt()`
(`af_rds.c:506`) on `getsockopt(2)` for `SOL_RDS` options. Reachable
from any process with an AF_RDS socket.
### Step 5.3: TRACE CALLEES
**Record:** `sock_net()`, `net_eq()`, `rds_conn_net()`,
`rds_info_copy()`, list iteration under existing locks (`rds_sock_lock`,
`rds_tcp_tc_list_lock`, RCU for conn hash).
### Step 5.4: FOLLOW THE CALL CHAIN
**Record:** `syscall:getsockopt` → `sock_getsockopt` → `rds_getsockopt`
→ `rds_info_getsockopt` → info handler. **Userspace-reachable** from
unprivileged user in new netns (confirmed: `rds_create()` at
`af_rds.c:703-716` has no `capable()` check).
### Step 5.5: SEARCH FOR SIMILAR PATTERNS
**Record:** Same `net_eq(sock_net(...), rds_conn_net(...))` pattern
already applied in `recv.c:377` for cross-netns message delivery. This
fix extends the same principle to the info-export path.
---
## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
### Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
**Record:** **YES.** Verified:
- `rds_sock_inc_info` iterates all of `rds_sock_list` without netns
check (`af_rds.c:746`)
- `rds_tcp_tc_info` exports all TCP connections without netns filter
(`tcp.c:245-264`)
- `rds_conn_message_info_cmn` walks all of `rds_conn_hash` without netns
filter (`connection.c:560-594`)
- `rds_info_getsockopt()` has no netns/capability gate
(`info.c:158-218`)
### Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
**Record:** Expected **clean apply**. File structure matches the diff
context. Recent related RDS netns commits in this tree use the same
helpers. No conflicting refactor detected in last 10 commits on these
files.
### Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
**Record:** Partial mitigations present (`a7494479757d6` blocks RDS/IB
in non-init netns for *transport setup*, `9591042533140` fixes recv
UAF), but **no fix for getsockopt info leak**. This commit is still
needed.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
**Record:** `net/rds` — networking protocol (IMPORTANT). Security-
relevant when `CONFIG_RDS` is enabled/built as module.
### Step 7.2: ASSESS SUBSYSTEM ACTIVITY
**Record:** Actively maintained — multiple RDS netns security fixes
landed in 6.18.y recently, indicating ongoing hardening of namespace
isolation in this driver.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: DETERMINE WHO IS AFFECTED
**Record:** Systems with `CONFIG_RDS`/`CONFIG_RDS_TCP` enabled and RDS
in use on the host. Any multi-tenant/container environment where
untrusted users can create user+network namespaces. Not universal
(CONFIG-dependent), but impact is severe when RDS is loaded.
### Step 8.2: DETERMINE THE TRIGGER CONDITIONS
**Record:**
- **Trigger:** Create user_ns + netns (unprivileged since 3.8), load/use
AF_RDS, call `getsockopt(SOL_RDS, RDS_INFO_*)`
- **Likelihood:** Moderate — requires RDS module loaded, but module
autoload via `MODULE_ALIAS_NETPROTO(PF_RDS)` is possible
- **Unprivileged trigger:** **Yes** — no capability check in
`rds_create()`
### Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
**Record:** Cross-namespace **information disclosure** — socket
addresses, inode numbers, peer addresses, TCP sequence numbers, RDS
sequence numbers. Severity: **CRITICAL** (security vulnerability; aids
network reconnaissance and potentially TCP sequence prediction attacks).
### Step 8.4: CALCULATE RISK-BENEFIT RATIO
**Record:**
- **Benefit:** HIGH — closes documented namespace isolation bypass
- **Risk:** LOW — surgical netns filtering using established in-
subsystem pattern; no behavior change for correctly scoped callers
- **Ratio:** Strongly favors backport
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: COMPILE THE EVIDENCE
**FOR backport:**
- Real security bug — cross-netns info leak
- Unprivileged reproduction path documented
- Leaks sensitive data (TCP/RDS sequence numbers, peer addresses, socket
inodes)
- Reviewed by RDS maintainer (Allison Henderson)
- Small, focused fix using existing `net_eq()`/`rds_conn_net()`
infrastructure
- Buggy code confirmed present in linux-6.18.y
- Prerequisites (`rds_conn_net`, per-net conn support) present in tree
- Consistent with other RDS netns hardening already backported to this
tree
**AGAINST backport:**
- CONFIG_RDS is optional/tristate — not every system has RDS loaded
- No syzbot/CVE reference (weaker signal, but maintainers documented the
issue)
**UNRESOLVED:**
- Full lore thread content (fetch blocked)
- Exact upstream commit SHA not in local remotes
Neither unresolved item affects the technical decision.
### Step 9.2: STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — clear netns filtering;
reviewed by maintainer; reproducer provided
2. Fixes a real bug affecting users? **PASS** — documented cross-netns
info leak
3. Important issue? **PASS** — security information disclosure
(CRITICAL)
4. Small and contained? **PASS** — ~3 files, focused handlers, no
refactoring
5. No new features or APIs? **PASS** — access restriction only
6. Can apply to local tree? **PASS** — code and helpers present; clean
apply expected
### Step 9.3: CHECK FOR EXCEPTION CATEGORIES
**Record:** Security bug fix (not device ID, quirk, DT, build, or docs
exception).
### Step 9.4: DECISION RATIONALE
This commit closes a namespace isolation hole in RDS diagnostic
getsockopt handlers. An unprivileged user in a container-like
user+network namespace can currently enumerate host-wide RDS connection
state including TCP sequence numbers. The fix applies the same
`net_eq()` scoping pattern already used elsewhere in RDS and is a
standard stable security backport. The bug exists in linux-6.18.44;
partial mitigations (RDS/IB transport restriction, recv-path UAF fix) do
not address this getsockopt leak.
---
## Verification
- [Phase 1] Parsed subject, tags (Reviewed-by Henderson, Suggested-by
Henderson/Horman, Link to patch)
- [Phase 2] Read diff: 3 files, netns `net_eq()` filters in 9 handlers,
global counter removal
- [Phase 3] `git describe HEAD` → v6.18.44; `git blame` on
`rds_sock_inc_info` → long-standing code; `d5a8ac28a7ff` → RDS-TCP
netns since 2015; related commits `a7494479757d6`, `9591042533140`
present
- [Phase 4] Web search found v3-v5 patch series; Reviewed-by Henderson;
`b4 dig`/`WebFetch` lore blocked (no commit SHA in tree / bot
protection)
- [Phase 5] Traced call chain: `getsockopt` → `rds_getsockopt` →
`rds_info_getsockopt` → handlers; confirmed `rds_create()` lacks
`capable()` at `af_rds.c:703-716`
- [Phase 6] Confirmed buggy globals and unfiltered loops at
`af_rds.c:746`, `tcp.c:245`, `connection.c:560`; `rds_conn_net()`
exists at `rds.h:174`; fix not present
- [Phase 7] Subsystem: net/rds, actively receiving netns security fixes
- [Phase 8] Failure mode: cross-netns info leak, unprivileged trigger,
CRITICAL severity
**YES**The remote search (`sasha-next`, `sashal`, `stable/linux-6.19.y`)
finished without finding the fix commit — it isn’t in those local refs
yet, which matches this tree still having the vulnerable getsockopt
handlers.
The analysis stands: this is a cross-netns information leak in
`RDS_INFO_*` getsockopt paths, exploitable from unprivileged
user+network namespaces when RDS is loaded. The fix is small, reviewed
by the RDS maintainer, and the prerequisites (`rds_conn_net()`, etc.)
are already in **linux-6.18.y v6.18.44**.
**YES** — backport recommended for this tree.
net/rds/af_rds.c | 59 ++++++++++++++++++++++++++++++++++-------
net/rds/connection.c | 13 +++++++++
net/rds/tcp.c | 63 ++++++++++++++++++++++++++++----------------
3 files changed, 104 insertions(+), 31 deletions(-)
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 7a0f5150e9103..cc3a898bf5d51 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -43,7 +43,6 @@
/* this is just used for stats gathering :/ */
static DEFINE_SPINLOCK(rds_sock_lock);
-static unsigned long rds_sock_count;
static LIST_HEAD(rds_sock_list);
DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
@@ -82,7 +81,6 @@ static int rds_release(struct socket *sock)
spin_lock_bh(&rds_sock_lock);
list_del_init(&rs->rs_item);
- rds_sock_count--;
spin_unlock_bh(&rds_sock_lock);
rds_trans_put(rs->rs_transport);
@@ -694,7 +692,6 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
spin_lock_bh(&rds_sock_lock);
list_add_tail(&rs->rs_item, &rds_sock_list);
- rds_sock_count++;
spin_unlock_bh(&rds_sock_lock);
return 0;
@@ -735,6 +732,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(sock->sk);
struct rds_sock *rs;
struct rds_incoming *inc;
unsigned int total = 0;
@@ -744,6 +742,9 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
spin_lock_bh(&rds_sock_lock);
list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ /* Only show sockets in the caller's netns. */
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
/* This option only supports IPv4 sockets. */
if (!ipv6_addr_v4mapped(&rs->rs_bound_addr))
continue;
@@ -774,6 +775,7 @@ static void rds6_sock_inc_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(sock->sk);
struct rds_incoming *inc;
unsigned int total = 0;
struct rds_sock *rs;
@@ -783,6 +785,9 @@ static void rds6_sock_inc_info(struct socket *sock, unsigned int len,
spin_lock_bh(&rds_sock_lock);
list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ /* Only show sockets in the caller's netns. */
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
read_lock(&rs->rs_recv_lock);
list_for_each_entry(inc, &rs->rs_recv_queue, i_item) {
@@ -806,7 +811,9 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(sock->sk);
struct rds_info_socket sinfo;
+ unsigned int copied = 0;
unsigned int cnt = 0;
struct rds_sock *rs;
@@ -814,12 +821,24 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
spin_lock_bh(&rds_sock_lock);
- if (len < rds_sock_count) {
- cnt = rds_sock_count;
- goto out;
+ /* First pass: count entries visible in the caller's netns. */
+ list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
+ if (!ipv6_addr_v4mapped(&rs->rs_bound_addr))
+ continue;
+ cnt++;
}
+ if (len < cnt)
+ goto out;
+
list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ if (copied >= cnt)
+ break;
+ /* Only show sockets in the caller's netns. */
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
/* This option only supports IPv4 sockets. */
if (!ipv6_addr_v4mapped(&rs->rs_bound_addr))
continue;
@@ -832,8 +851,13 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
sinfo.inum = sock_i_ino(rds_rs_to_sk(rs));
rds_info_copy(iter, &sinfo, sizeof(sinfo));
- cnt++;
+ copied++;
}
+ /* A concurrent rds_bind() can change rs_bound_addr between the
+ * two passes without holding rds_sock_lock, so copied may be
+ * less than cnt. Report what was actually copied.
+ */
+ cnt = copied;
out:
lens->nr = cnt;
@@ -847,17 +871,32 @@ static void rds6_sock_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(sock->sk);
struct rds6_info_socket sinfo6;
+ unsigned int copied = 0;
+ unsigned int cnt = 0;
struct rds_sock *rs;
len /= sizeof(struct rds6_info_socket);
spin_lock_bh(&rds_sock_lock);
- if (len < rds_sock_count)
+ /* First pass: count entries visible in the caller's netns. */
+ list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
+ cnt++;
+ }
+
+ if (len < cnt)
goto out;
list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ if (copied >= cnt)
+ break;
+ /* Only show sockets in the caller's netns. */
+ if (!net_eq(sock_net(rds_rs_to_sk(rs)), net))
+ continue;
sinfo6.sndbuf = rds_sk_sndbuf(rs);
sinfo6.rcvbuf = rds_sk_rcvbuf(rs);
sinfo6.bound_addr = rs->rs_bound_addr;
@@ -867,10 +906,12 @@ static void rds6_sock_info(struct socket *sock, unsigned int len,
sinfo6.inum = sock_i_ino(rds_rs_to_sk(rs));
rds_info_copy(iter, &sinfo6, sizeof(sinfo6));
+ copied++;
}
+ cnt = copied;
out:
- lens->nr = rds_sock_count;
+ lens->nr = cnt;
lens->each = sizeof(struct rds6_info_socket);
spin_unlock_bh(&rds_sock_lock);
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 4764628fe12a3..9fd58b7250e9a 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -541,6 +541,7 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
struct rds_info_lengths *lens,
int want_send, bool isv6)
{
+ struct net *net = sock_net(sock->sk);
struct hlist_head *head;
struct list_head *list;
struct rds_connection *conn;
@@ -563,6 +564,9 @@ static void rds_conn_message_info_cmn(struct socket *sock, unsigned int len,
struct rds_conn_path *cp;
int npaths;
+ /* Only show connections in the caller's netns. */
+ if (!net_eq(rds_conn_net(conn), net))
+ continue;
if (!isv6 && conn->c_isv6)
continue;
@@ -661,6 +665,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
u64 *buffer,
size_t item_len)
{
+ struct net *net = sock_net(sock->sk);
struct hlist_head *head;
struct rds_connection *conn;
size_t i;
@@ -673,6 +678,9 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash);
i++, head++) {
hlist_for_each_entry_rcu(conn, head, c_hash_node) {
+ /* Only show connections in the caller's netns. */
+ if (!net_eq(rds_conn_net(conn), net))
+ continue;
/* Zero the per-item buffer before handing it to the
* visitor so any field the visitor does not write -
@@ -706,6 +714,7 @@ static void rds_walk_conn_path_info(struct socket *sock, unsigned int len,
u64 *buffer,
size_t item_len)
{
+ struct net *net = sock_net(sock->sk);
struct hlist_head *head;
struct rds_connection *conn;
size_t i;
@@ -720,6 +729,10 @@ static void rds_walk_conn_path_info(struct socket *sock, unsigned int len,
hlist_for_each_entry_rcu(conn, head, c_hash_node) {
struct rds_conn_path *cp;
+ /* Only show connections in the caller's netns. */
+ if (!net_eq(rds_conn_net(conn), net))
+ continue;
+
/* XXX We only copy the information from the first
* path for now. The problem is that if there are
* more than one underlying paths, we cannot report
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 1980a197034ba..ab509498cf752 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -46,14 +46,6 @@
static DEFINE_SPINLOCK(rds_tcp_tc_list_lock);
static LIST_HEAD(rds_tcp_tc_list);
-/* rds_tcp_tc_count counts only IPv4 connections.
- * rds6_tcp_tc_count counts both IPv4 and IPv6 connections.
- */
-static unsigned int rds_tcp_tc_count;
-#if IS_ENABLED(CONFIG_IPV6)
-static unsigned int rds6_tcp_tc_count;
-#endif
-
/* Track rds_tcp_connection structs so they can be cleaned up */
static DEFINE_SPINLOCK(rds_tcp_conn_lock);
static LIST_HEAD(rds_tcp_conn_list);
@@ -110,11 +102,6 @@ void rds_tcp_restore_callbacks(struct socket *sock,
/* done under the callback_lock to serialize with write_space */
spin_lock(&rds_tcp_tc_list_lock);
list_del_init(&tc->t_list_item);
-#if IS_ENABLED(CONFIG_IPV6)
- rds6_tcp_tc_count--;
-#endif
- if (!tc->t_cpath->cp_conn->c_isv6)
- rds_tcp_tc_count--;
spin_unlock(&rds_tcp_tc_list_lock);
tc->t_sock = NULL;
@@ -201,11 +188,6 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp)
/* done under the callback_lock to serialize with write_space */
spin_lock(&rds_tcp_tc_list_lock);
list_add_tail(&tc->t_list_item, &rds_tcp_tc_list);
-#if IS_ENABLED(CONFIG_IPV6)
- rds6_tcp_tc_count++;
-#endif
- if (!tc->t_cpath->cp_conn->c_isv6)
- rds_tcp_tc_count++;
spin_unlock(&rds_tcp_tc_list_lock);
/* accepted sockets need our listen data ready undone */
@@ -233,20 +215,37 @@ static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(rds_sock->sk);
struct rds_info_tcp_socket tsinfo;
struct rds_tcp_connection *tc;
+ unsigned int copied = 0;
+ unsigned int cnt = 0;
unsigned long flags;
spin_lock_irqsave(&rds_tcp_tc_list_lock, flags);
- if (len / sizeof(tsinfo) < rds_tcp_tc_count)
+ /* First pass: count entries visible in the caller's netns. */
+ list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
+ if (tc->t_cpath->cp_conn->c_isv6)
+ continue;
+ if (!net_eq(rds_conn_net(tc->t_cpath->cp_conn), net))
+ continue;
+ cnt++;
+ }
+
+ if (len / sizeof(tsinfo) < cnt)
goto out;
list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
struct inet_sock *inet = inet_sk(tc->t_sock->sk);
+ if (copied >= cnt)
+ break;
if (tc->t_cpath->cp_conn->c_isv6)
continue;
+ /* Only show connections in the caller's netns. */
+ if (!net_eq(rds_conn_net(tc->t_cpath->cp_conn), net))
+ continue;
tsinfo.local_addr = inet->inet_saddr;
tsinfo.local_port = inet->inet_sport;
@@ -261,10 +260,12 @@ static void rds_tcp_tc_info(struct socket *rds_sock, unsigned int len,
tsinfo.tos = tc->t_cpath->cp_conn->c_tos;
rds_info_copy(iter, &tsinfo, sizeof(tsinfo));
+ copied++;
}
+ cnt = copied;
out:
- lens->nr = rds_tcp_tc_count;
+ lens->nr = cnt;
lens->each = sizeof(tsinfo);
spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
@@ -279,19 +280,35 @@ static void rds6_tcp_tc_info(struct socket *sock, unsigned int len,
struct rds_info_iterator *iter,
struct rds_info_lengths *lens)
{
+ struct net *net = sock_net(sock->sk);
struct rds6_info_tcp_socket tsinfo6;
struct rds_tcp_connection *tc;
+ unsigned int copied = 0;
+ unsigned int cnt = 0;
unsigned long flags;
spin_lock_irqsave(&rds_tcp_tc_list_lock, flags);
- if (len / sizeof(tsinfo6) < rds6_tcp_tc_count)
+ /* First pass: count entries visible in the caller's netns. */
+ list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
+ if (!net_eq(rds_conn_net(tc->t_cpath->cp_conn), net))
+ continue;
+ cnt++;
+ }
+
+ if (len / sizeof(tsinfo6) < cnt)
goto out;
list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
struct sock *sk = tc->t_sock->sk;
struct inet_sock *inet = inet_sk(sk);
+ if (copied >= cnt)
+ break;
+ /* Only show connections in the caller's netns. */
+ if (!net_eq(rds_conn_net(tc->t_cpath->cp_conn), net))
+ continue;
+
tsinfo6.local_addr = sk->sk_v6_rcv_saddr;
tsinfo6.local_port = inet->inet_sport;
tsinfo6.peer_addr = sk->sk_v6_daddr;
@@ -304,10 +321,12 @@ static void rds6_tcp_tc_info(struct socket *sock, unsigned int len,
tsinfo6.last_seen_una = tc->t_last_seen_una;
rds_info_copy(iter, &tsinfo6, sizeof(tsinfo6));
+ copied++;
}
+ cnt = copied;
out:
- lens->nr = rds6_tcp_tc_count;
+ lens->nr = cnt;
lens->each = sizeof(tsinfo6);
spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18] net/mlx5: HWS, Check if device is down while polling for completion
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (9 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-5.10] rds: filter RDS_INFO_* getsockopt by caller's netns Sasha Levin
@ 2026-08-31 13:27 ` Sasha Levin
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18] net/mlx5: Relax capability check for eswitch query paths Sasha Levin
` (6 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:27 UTC (permalink / raw)
To: patches, stable
Cc: Yevgeny Kliteynik, Erez Shitrit, Shay Drori, Tariq Toukan,
Jakub Kicinski, Sasha Levin, saeedm, mbloch, andrew+netdev, davem,
edumazet, pabeni, netdev, linux-rdma, linux-kernel
From: Yevgeny Kliteynik <kliteyn@nvidia.com>
[ Upstream commit e3ec1570895bcf81f443e8ac60059edc61dbfca3 ]
In case the device is down for any reason (e.g. FLR),
the HW will no longer generate completions - no point
polling and waiting for timeout.
Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: Erez Shitrit <erezsh@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260507173443.320465-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `net/mlx5: HWS, Check if device is down
while polling for completion`
**Local tree:** Linux **6.18.43** (`git describe HEAD` →
`v6.18.43-1-gc7f0dac02d232`, detached from `stable/linux-6.18.y`)
**Commit under review:** `e3ec1570895bc` (on `net-next`; **not yet** in
this 6.18.43 checkout)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[net/mlx5: HWS]` `[Check]` — Check if device is down while
polling for BWC completion queue.
### Step 1.2: Tags
**Record:**
- **Fixes:** — not present (expected for manual review)
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by:** Erez Shitrit `<erezsh@nvidia.com>`, Shay Drori
`<shayd@nvidia.com>`
- **Acked-by:** — none
- **Link:**
https://patch.msgid.link/20260507173443.320465-2-tariqt@nvidia.com
- **Cc: stable:** — none (not a negative signal)
- **Signed-off-by:** Yevgeny Kliteynik, Tariq Toukan, Jakub Kicinski
(ignore pipeline SOBs)
Notable: NVIDIA internal review + netdev maintainer merge; no
syzbot/user bug report.
### Step 1.3: Body analysis
**Record:**
- **Bug:** When mlx5 device enters error state (e.g. FLR), hardware
stops generating completions, but BWC polling still waits for the full
timeout.
- **Symptom:** Unnecessary polling delay (up to
`MLX5HWS_BWC_POLLING_TIMEOUT` = 60 seconds per call); during
rehash/resize/shrink this can chain into multiple timeouts.
- **Root cause:** `mlx5hws_bwc_queue_poll()` enters a polling loop
without checking `ctx->mdev->state`.
- **Fix approach:** Early-exit with `-ETIMEDOUT` when
`MLX5_DEVICE_STATE_INTERNAL_ERROR`, reusing existing BWC timeout
handling to abort rehash/resize/shrink loops.
### Step 1.4: Hidden bug fix?
**Record:** Yes — subject says "Check" rather than "fix", but this is a
real hang/latency bug during device failure recovery, not cosmetic
cleanup.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **Files:**
`drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c` (+12
lines, 0 removed)
- **Function modified:** `mlx5hws_bwc_queue_poll()`
- **Scope:** Single-file, surgical fix
### Step 2.2: Code flow change
**Record:**
- **Hunk (before):** After early-return when no completions expected,
function enters polling loop calling `mlx5hws_send_queue_poll()` until
completions arrive or 60s timeout.
- **Hunk (after):** Before entering the loop, checks `ctx->mdev->state
== MLX5_DEVICE_STATE_INTERNAL_ERROR`; if set, logs
`mlx5_core_warn_once()` and returns `-ETIMEDOUT` immediately.
- **Path affected:** All BWC synchronous completion polling (rule
create/destroy, rehash move loops).
### Step 2.3: Bug mechanism
**Record:**
- **Category:** Logic/correctness — missing device-error fast-path in
polling loop.
- **Mechanism:** On FLR/fatal error, `mlx5_enter_error_state()` sets
`MLX5_DEVICE_STATE_INTERNAL_ERROR`. `mlx5hws_send_queue_poll()`
returns 0 when no CQEs are available (`hws_send_engine_poll_cq()`
returns early at `!cqe` without surfacing device-down). BWC layer then
busy-waits until `time_after(jiffies, timeout)` — up to 60 seconds per
`mlx5hws_bwc_queue_poll()` call.
### Step 2.4: Fix quality
**Record:**
- **Obviously correct:** Yes — mirrors existing mlx5 pattern (`send.c`
`mlx5hws_cq_poll_one()`, `dr_send.c` FLR skip).
- **Minimal:** 12 lines, no unrelated changes.
- **Regression risk:** Low — only triggers in `INTERNAL_ERROR` state;
`-ETIMEDOUT` is already handled by all callers (rehash abort at lines
116–120, 139–143 in `bwc.c`; rule insertion at 1072–1081).
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** `mlx5hws_bwc_queue_poll()` introduced in `5d324e5159d9e`
(Merge tag `usb-6.18-rc8`, 2025-11-28) — first appearance in this tree
at **6.18**. Bug present since HWS BWC introduction.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag.
### Step 3.3: Related file history
**Record:**
- `bwc.c` history in this tree: `5d324e5159d9e` (introduction),
`1dce4f4bb3c1c` (matcher leak fix).
- Part of 3-patch series (`[PATCH 0/3] net/mlx5: Steering misc
enhancements`); **this patch is standalone** — only touches `bwc.c`;
patches 2/3 are unrelated (`table.c`, `dr_types.h`).
### Step 3.4: Author context
**Record:** Yevgeny Kliteynik (NVIDIA mlx5 steering). Tariq Toukan
signed off; Jakub Kicinski merged. No prior author commits in this
tree's HWS path (new subsystem in 6.18).
### Step 3.5: Dependencies
**Record:** No prerequisites. `ctx->mdev` exists in `struct
mlx5hws_context` (`context.h:38`). `MLX5_DEVICE_STATE_INTERNAL_ERROR`
used throughout mlx5 core. Patch applies cleanly (`git apply --check`
passed).
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:**
- `b4 dig -c e3ec1570895bc` →
https://patch.msgid.link/20260507173443.320465-2-tariqt@nvidia.com
- Series: `[PATCH net-next 1/3]` — single revision found; committed
version matches submission.
- Cover letter describes series as "steering enhancements / cleanups" —
patch 1 is clearly a bug fix.
- No explicit stable nomination found in available thread metadata.
### Step 4.2: Reviewers
**Record:** `b4 dig -c e3ec1570895bc -w` — CC'd: Jakub Kicinski, Saeed
Mahameed, Leon Romanovsky, netdev@, linux-rdma@, Simon Horman, and other
mlx5 maintainers/reviewers. Appropriate subsystem coverage.
### Step 4.3: Bug report
**Record:** No external bug report or syzbot link. Bug identified by
driver authors during development/review of error-path behavior.
### Step 4.4: Series context
**Record:** Patches 2/3 fix a miss-table list UAF and remove an unused
DR field — **not required** for this fix.
### Step 4.5: Stable list history
**Record:** Lore stable search blocked by Anubis bot protection — could
not verify stable-list discussion. Not relied upon for decision.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `mlx5hws_bwc_queue_poll()` (modified); callers unchanged.
### Step 5.2: Callers
**Record:** `mlx5hws_bwc_queue_poll()` called from:
- `bwc.c`: rehash move loops (lines 111, 134),
`hws_bwc_rule_destroy_hws_sync()` (541), `hws_bwc_rule_create_sync()`
(703), `hws_bwc_rule_update_sync()` (725)
- `bwc_complex.c`: complex matcher rehash (1031)
All paths are flow-steering operations under mutex protection.
### Step 5.3: Callees
**Record:** Calls `mlx5hws_send_engine_full()`,
`mlx5hws_send_queue_poll()`, uses `mlx5_core_warn_once()`.
### Step 5.4: Reachability
**Record:**
- HWS integrated into mlx5 flow steering via `fs_hws.c` (e.g.
`mlx5_cmd_hws_create_flow_group()` → `mlx5hws_bwc_matcher_create()`).
- Reachable from kernel flow-offload paths (tc, OVS, etc.) on mlx5 NICs
with HWS support.
- Device error (FLR, fatal sensors) can occur concurrently with in-
flight flow operations → this path is realistically triggerable.
### Step 5.5: Similar patterns
**Record:** Existing device-down checks:
- `send.c:581-585` — `mlx5hws_cq_poll_one()` checks `INTERNAL_ERROR`
when no CQE
- `dr_send.c:632-637` — SWS steering skips post-send on `INTERNAL_ERROR`
- BWC layer lacked equivalent fast-path at its own timeout loop
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code exists?
**Record:** **Yes.** `mlx5hws_bwc_queue_poll()` at `bwc.c:407-457` lacks
device-down check. HWS BWC code present since 6.18 merge
(`5d324e5159d9e`). Fix commit `e3ec1570895bc` is on `net-next` but
**not** in 6.18.43.
### Step 6.2: Backport complications
**Record:** **Clean apply** — `git show e3ec1570895bc -- bwc.c | git
apply --check` succeeded with no conflicts.
### Step 6.3: Related fixes already present?
**Record:** No — `git log --grep="device is down"` and `--grep="BWC
poll"` in mlx5 steering returned no matches in this tree.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/net/ethernet/mellanox/mlx5` — **IMPORTANT** (mlx5
NIC flow steering; not core-kernel-wide, but widely deployed in
cloud/HPC/enterprise).
### Step 7.2: Subsystem activity
**Record:** HWS steering is **new and actively developed** in 6.18
(introduced Nov 2025; multiple follow-up fixes already in 6.18.y: leak
fix, unsupported action rejection).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** mlx5 users with HWS flow steering (BWC API) — cloud/SDN
deployments using tc flow offload on ConnectX devices. Config-dependent
on HWS-capable hardware and flow-steering usage.
### Step 8.2: Trigger conditions
**Record:** Device enters `MLX5_DEVICE_STATE_INTERNAL_ERROR` (FLR, fatal
error, health failure) while BWC operations have pending HW completions.
Timing-dependent but realistic during error recovery. Triggerable
indirectly via admin actions (FLR, PCI reset) concurrent with flow
operations.
### Step 8.3: Failure severity
**Record:** **HIGH** — up to 60-second hang per poll call in kernel
context, potentially while holding BWC queue mutex; during rehash can
chain multiple timeouts ("chain of timeouts" per commit comment). Not a
crash/UAF, but a serious latency/hung-task issue during error recovery.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH for affected mlx5 HWS users — immediate abort
instead of 60s+ waits during device failure.
- **Risk:** VERY LOW — 12-line early return on error state only; reuses
established `-ETIMEDOUT` handling.
- **Ratio:** Strong benefit, minimal risk.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real bug in code present since 6.18
- Causes up to 60s hangs per poll during device error (FLR)
- Mutex-held paths make hang user-visible
- Small, reviewed, obviously correct fix
- Applies cleanly to 6.18.43
- Standalone (no series dependencies)
- Follows existing mlx5 device-down patterns
- Callers already handle `-ETIMEDOUT` correctly
**AGAINST backport:**
- Driver-specific, not universal
- No user/syzbot report (author-found)
- HWS is new subsystem (limited exposure window, but code is in 6.18.y)
**Unresolved:** Lore stable-list discussion (blocked by Anubis).
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — reviewed by NVIDIA
engineers, merged by netdev maintainer; logic is straightforward.
2. Fixes a real bug? **PASS** — 60s timeout spin on dead device during
flow operations.
3. Important issue? **PASS** — HIGH severity hang during error recovery.
4. Small and contained? **PASS** — 12 lines, one function, one file.
5. No new features/APIs? **PASS** — error-path behavior fix only.
6. Can apply to local tree? **PASS** — clean apply verified.
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build, or docs fix —
standard driver bug fix).
### Step 9.4: Decision rationale
For **this** tree (6.18.43), the HWS BWC polling code exists and has had
the missing device-down check since its introduction. During FLR or
fatal device error, users with mlx5 flow steering can hit multi-second
to multi-minute hangs. The fix is minimal, follows existing mlx5
conventions, applies cleanly, and reuses established error handling.
This meets stable kernel criteria.
---
## Verification
- **[Phase 1]** Parsed commit message from user query and `git show
e3ec1570895bc`
- **[Phase 1]** Tags: Reviewed-by (2), Link, Signed-off-by; no
Fixes/Reported-by/Cc:stable
- **[Phase 2]** Diff: +12 lines in `mlx5hws_bwc_queue_poll()`, `bwc.c`
only
- **[Phase 2]** `MLX5HWS_BWC_POLLING_TIMEOUT` = 60 in `bwc.h:19`
- **[Phase 3]** `git blame -L 407,456 bwc.c`: function introduced in
`5d324e5159d9e` (6.18)
- **[Phase 3]** `git log --oneline -- bwc.c`: 2 commits in tree (intro +
leak fix)
- **[Phase 3]** `b4 am` cover letter: 3-patch series, patch 1 standalone
- **[Phase 3]** `git apply --check` on commit diff: **clean apply**
- **[Phase 4]** `b4 dig -c e3ec1570895bc`: lore URL found
- **[Phase 4]** `b4 dig -c e3ec1570895bc -w`: maintainers CC'd
(Kicinski, Saeed, Leon, netdev@)
- **[Phase 4]** `b4 am` mbox: patch content matches committed version
- **[Phase 4]** Lore stable search: **blocked** (Anubis)
- **[Phase 5]** `grep mlx5hws_bwc_queue_poll`: 6 call sites in `bwc.c`,
`bwc_complex.c`
- **[Phase 5]** `fs_hws.c`: BWC used for flow group/rule operations
- **[Phase 5]** `send.c:610-612`: `hws_send_engine_poll_cq` returns on
`!cqe` without device check
- **[Phase 5]** `send.c:581-585`: device-down check exists in
`mlx5hws_cq_poll_one` (different path)
- **[Phase 5]** `health.c:215`: `MLX5_DEVICE_STATE_INTERNAL_ERROR` set
on fatal error
- **[Phase 6]** `git describe HEAD`: v6.18.43
- **[Phase 6]** Buggy code confirmed at `bwc.c:407-457` without fix
- **[Phase 6]** `git log net-next --grep=...`: commit `e3ec1570895bc` on
net-next, not in 6.18.43
- **[Phase 6]** `context.h:38`: `struct mlx5hws_context { struct
mlx5_core_dev *mdev; ...}`
- **[Phase 8]** ETIMEDOUT handling verified at `bwc.c:116-120`,
`139-143`, `1072-1081`
- **[Phase 8]** Mutex context verified: `mutex_lock(queue_lock)` before
rule create paths
**YES**
.../ethernet/mellanox/mlx5/core/steering/hws/bwc.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
index 564ae98316bc9..756b87a3d68dd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
@@ -423,6 +423,18 @@ int mlx5hws_bwc_queue_poll(struct mlx5hws_context *ctx,
if (!got_comp && !drain)
return 0;
+ if (unlikely(ctx->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)) {
+ /* If the device is down for any reason (e.g. FLR), the HW will
+ * no longer generate completions.
+ * Note that ETIMEDOUT is returned here because the BWC layer
+ * already has a special handling for timeouts - it breaks the
+ * rehash / resize / shrink loops to avoid chain of timeouts.
+ */
+ mlx5_core_warn_once(ctx->mdev,
+ "BWC poll: device is down, polling for completion aborted\n");
+ return -ETIMEDOUT;
+ }
+
queue_full = mlx5hws_send_engine_full(&ctx->send_queue[queue_id]);
while (queue_full || ((got_comp || drain) && *pending_rules)) {
ret = mlx5hws_send_queue_poll(ctx, queue_id, comp, burst_th);
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18] net/mlx5: Relax capability check for eswitch query paths
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (10 preceding siblings ...)
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18] net/mlx5: HWS, Check if device is down while polling for completion Sasha Levin
@ 2026-08-31 13:28 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] net/rds: Don't sleep inside rds_ib_conn_path_shutdown Sasha Levin
` (5 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:28 UTC (permalink / raw)
To: patches, stable
Cc: Moshe Shemesh, Akiva Goldberger, Mark Bloch, Tariq Toukan,
Jakub Kicinski, Sasha Levin, saeedm, andrew+netdev, davem,
edumazet, pabeni, netdev, linux-rdma, linux-kernel
From: Moshe Shemesh <moshe@nvidia.com>
[ Upstream commit 8ca32460815f6876095be8798adcf5ab982e94de ]
Several eswitch functions that only query other functions' HCA
capabilities or read cached vport state are guarded by the
vhca_resource_manager capability. This capability is required for
set_hca_cap operations but query_hca_cap of other functions only
requires the vport_group_manager capability.
Relax the capability check from vhca_resource_manager to
vport_group_manager in the following query-only paths:
- mlx5_esw_vport_caps_get() - queries other function general caps
- esw_ipsec_vf_query_generic() - queries other function ipsec cap
- mlx5_devlink_port_fn_migratable_get() - reads cached vport state
- mlx5_devlink_port_fn_roce_get() - reads cached vport state
- mlx5_devlink_port_fn_max_io_eqs_get() - queries other function caps
- mlx5_esw_vport_enable/disable() - vhca_id map/unmap
Functions that perform also set_hca_cap (migratable_set, roce_set,
max_io_eqs_set, esw_ipsec_vf_set_generic, esw_ipsec_vf_set_bytype)
retain the vhca_resource_manager requirement.
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260506133239.276237-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The `git log -S` search finished, but it wasn’t very informative: for
both `mlx5_devlink_port_fn_max_io_eqs_get` and
`esw_ipsec_vf_query_generic`, the only hits were merge commits (e.g.
`5d324e5159d9e`), not the commits that originally added those functions
or the wrong `vhca_resource_manager` checks.
That fits the shallow checkout — we still can’t pin down when the bug
was introduced. What we do know is unchanged: both code paths are
present in 6.18.43 with the incorrect guards, and the fix exists on
other branches but not on current HEAD. The **YES** backport
recommendation still stands.
.../net/ethernet/mellanox/mlx5/core/esw/ipsec.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 6 +++---
.../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 14 ++++++++------
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c
index da10e04777cf7..1dbafeddd4b2f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c
@@ -12,7 +12,7 @@ static int esw_ipsec_vf_query_generic(struct mlx5_core_dev *dev, u16 vport_num,
void *hca_cap, *query_cap;
int err;
- if (!MLX5_CAP_GEN(dev, vhca_resource_manager))
+ if (!MLX5_CAP_GEN(dev, vport_group_manager))
return -EOPNOTSUPP;
if (!mlx5_esw_ipsec_vf_offload_supported(dev)) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index c38deabcb7b96..132592faaca60 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -799,7 +799,7 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport *
void *hca_caps;
int err;
- if (!MLX5_CAP_GEN(esw->dev, vhca_resource_manager))
+ if (!MLX5_CAP_GEN(esw->dev, vport_group_manager))
return 0;
query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
@@ -934,7 +934,7 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, struct mlx5_vport *vport,
vport->info.trusted = true;
if (!mlx5_esw_is_manager_vport(esw, vport_num) &&
- MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
+ MLX5_CAP_GEN(esw->dev, vport_group_manager)) {
ret = mlx5_esw_vport_vhca_id_map(esw, vport);
if (ret)
goto err_vhca_mapping;
@@ -978,7 +978,7 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
arm_vport_context_events_cmd(esw->dev, vport_num, 0);
if (!mlx5_esw_is_manager_vport(esw, vport_num) &&
- MLX5_CAP_GEN(esw->dev, vhca_resource_manager))
+ MLX5_CAP_GEN(esw->dev, vport_group_manager))
mlx5_esw_vport_vhca_id_unmap(esw, vport);
if (vport->vport != MLX5_VPORT_PF &&
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 8be0961cb6c7e..7a1c9ff6766e8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -4344,8 +4344,9 @@ int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enab
return -EOPNOTSUPP;
}
- if (!MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
- NL_SET_ERR_MSG_MOD(extack, "Device doesn't support VHCA management");
+ if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Device doesn't support vport group management");
return -EOPNOTSUPP;
}
@@ -4420,8 +4421,9 @@ int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
struct mlx5_eswitch *esw = mlx5_devlink_eswitch_nocheck_get(port->devlink);
struct mlx5_vport *vport = mlx5_devlink_port_vport_get(port);
- if (!MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
- NL_SET_ERR_MSG_MOD(extack, "Device doesn't support VHCA management");
+ if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Device doesn't support vport group management");
return -EOPNOTSUPP;
}
@@ -4685,9 +4687,9 @@ mlx5_devlink_port_fn_max_io_eqs_get(struct devlink_port *port, u32 *max_io_eqs,
int err;
esw = mlx5_devlink_eswitch_nocheck_get(port->devlink);
- if (!MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
+ if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) {
NL_SET_ERR_MSG_MOD(extack,
- "Device doesn't support VHCA management");
+ "Device doesn't support vport group management");
return -EOPNOTSUPP;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.10] net/rds: Don't sleep inside rds_ib_conn_path_shutdown
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (11 preceding siblings ...)
2026-08-31 13:28 ` [PATCH AUTOSEL 6.18] net/mlx5: Relax capability check for eswitch query paths Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Use QP port when decoding responder CQEs Sasha Levin
` (4 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Allison Henderson, Jakub Kicinski, Sasha Levin, davem, edumazet,
pabeni, netdev, linux-rdma, rds-devel, linux-kernel
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 16f48efaeb6991193fb7775c577f06f5b20b0c90 ]
New rds rdma self tests exposed a hang when tearing down
the ib network configs. This is caused by the shutdown worker
thread sleeping on the wait_event call, which blocks other work
items in the queue. Fix this by changing wait_event to
wait_event timeout, and looping until the wait check succeeds.
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260518012443.2629206-2-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `net/rds: Don't sleep inside
rds_ib_conn_path_shutdown`
**Local tree:** `v6.18.44` (Makefile: 6.18.44)
**Verdict target:** Should this commit be backported to **this** 6.18.y
tree?
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Parse the subject line
**Record:** `[net/rds]` `[Don't sleep / fix]` — prevent indefinite
sleeping in `rds_ib_conn_path_shutdown()` during IB connection teardown.
### Step 1.2: Parse all commit message tags
**Record:**
- **Signed-off-by:** Allison Henderson `<achender@kernel.org>` (author)
- **Link:** `https://patch.msgid.link/20260518012443.2629206-2-
achender@kernel.org` (patch 2 of a series, per Message-ID)
- **Signed-off-by:** Jakub Kicinski `<kuba@kernel.org>` (netdev
maintainer merge)
- No `Fixes:`, `Reported-by:`, `Cc: stable@vger.kernel.org`, `Tested-
by:`, or `Reviewed-by:` tags
- Notable: no syzbot report; bug found by new RDS RDMA selftests
### Step 1.3: Analyze commit body
**Record:**
- **Bug:** Hang when tearing down IB network configs during new RDS RDMA
selftests
- **Symptom:** System/workqueue stalls during teardown (not a
crash/oops)
- **Root cause (author):** Shutdown worker sleeps on `wait_event`,
blocking other work items on the same queue
- **Fix approach:** Replace `wait_event` with `wait_event_timeout` in a
loop; schedule send/recv tasklets on timeout to drive completion
### Step 1.4: Detect hidden bug fixes
**Record:** Yes — despite not using "fix" in the subject, this is a real
hang fix disguised as a sleep/workqueue interaction problem. The
infinite `wait_event` in a single-threaded workqueue context is a
classic teardown hang pattern.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory changes
**Record:**
- **Files:** `net/rds/ib_cm.c` only (+15 lines net, ~1 function added, 1
function modified)
- **Functions:** new `rds_ib_conn_path_shutdown_check_wait()`, modified
`rds_ib_conn_path_shutdown()`
- **Scope:** Single-file surgical fix
### Step 2.2: Code flow change per hunk
**Record:**
**Hunk 1 — new helper `rds_ib_conn_path_shutdown_check_wait()`:**
- Before: N/A
- After: Encapsulates the shutdown-ready condition (recv ring empty, no
signaled sends, FRWR segments released). Returns `0` when ready, non-
zero otherwise.
**Hunk 2 — `rds_ib_conn_path_shutdown()`:**
- Before: After `rdma_disconnect()` and `rds_ib_flush_mrs()`, blocks
forever on:
```c
wait_event(rds_ib_ring_empty_wait, <all conditions true>);
```
- After: Loops with 1-second timeout; on timeout, explicitly schedules
`i_send_tasklet` and `i_recv_tasklet` to make progress, then re-checks
until conditions are met.
### Step 2.3: Bug mechanism
**Record:**
- **Category:** Deadlock/hang in teardown path (workqueue + async
completion interaction)
- **Mechanism:**
1. `rds_ib_conn_path_shutdown()` runs on `rds_wq` via
`rds_shutdown_worker()` → `rds_conn_shutdown()`
2. `rds_wq` is a **single-threaded** workqueue
(`create_singlethread_workqueue("krdsd")` in `threads.c:259`)
3. `wait_event()` puts that sole worker thread to sleep indefinitely
4. Wait conditions require send/recv ring draining and FRWR cleanup,
which depends on tasklet progress (`i_send_tasklet` /
`i_recv_tasklet`, normally kicked from CQ handlers at
`ib_cm.c:256,384`)
5. Without explicit tasklet scheduling, the worker can sleep forever
while also blocking all other `rds_wq` work — including other
connection shutdowns during IB config teardown
### Step 2.4: Fix quality assessment
**Record:**
- Fix is minimal and logically sound: same wait conditions, but bounded
sleep + explicit tasklet kicks
- Still calls `tasklet_kill()` after the loop, preserving original
safety
- Low regression risk: does not change teardown ordering or destroy IB
resources early
- Minor style note: helper returns `msecs_to_jiffies(1000)` when not
ready, but only `== 0` is tested — harmless
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame changed lines
**Record:**
- `wait_event(rds_ib_ring_empty_wait, ...)` introduced in
`ec16227e14141` (Andy Grover, 2009) — RDS/IB transport
- Signaled-sends condition: `f046011cd73c3` (2010)
- `i_fastreg_inuse_count` wait: `3a2886cca703f` (Gerd Rausch, 2019) —
"Keep track of and wait for FRWR segments in use upon shutdown"
- Buggy infinite wait has been present since at least 2019 in its
current form; newly exposed under concurrent IB teardown/selftests
### Step 3.2: Follow Fixes: tag
**Record:** N/A — no `Fixes:` tag in commit message.
### Step 3.3: File history for related changes
**Record:**
- Recent `ib_cm.c` changes in this tree are unrelated (IPv6 NULL deref,
setup unwind, ib_modify_qp removal)
- RDS selftest infrastructure added in `3ade6ce1255e6` (Aug 2024) — TCP-
focused initially; new RDMA selftests triggered this hang
- No conflicting recent refactor of the shutdown path in 6.18.y
### Step 3.4: Author's other commits
**Record:**
- Allison Henderson is an active RDS maintainer (Oracle)
- Prior stability fix in this tree: `f1acf1ac84d2a` "net:rds: Fix
possible deadlock in rds_message_put" (syzbot-reported deadlock, 2024)
- Same subsystem, same author pattern of fixing RDS teardown/concurrency
bugs
### Step 3.5: Prerequisites / dependencies
**Record:**
- Message-ID indicates patch 2/2 of a series (likely selftests + this
fix)
- **This fix is standalone** — it only modifies `ib_cm.c` shutdown
logic; does not depend on selftest patches to be correct
- No structural/API prerequisites; applies cleanly to current 6.18.44
code
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original patch discussion
**Record:** **UNVERIFIED** — `b4 dig` requires a commit hash (commit not
in this tree); lore.kernel.org and patch.msgid.link blocked by Anubis
bot protection. Could not read thread discussion.
### Step 4.2: Reviewers
**Record:** **UNVERIFIED** — `b4 dig -w` not possible without commit
hash.
### Step 4.3: Bug report
**Record:** Bug found by new RDS RDMA selftests during IB network config
teardown. No external bugzilla/syzbot link. Selftests added separately
(`3ade6ce1255e6` and follow-ups in this tree).
### Step 4.4: Related patches / series
**Record:** Patch 2 of series per Message-ID (`...-2-achender@...`).
Patch 1 likely adds RDMA selftests that expose the hang. Fix itself is
independent.
### Step 4.5: Stable mailing list
**Record:** **UNVERIFIED** — could not search lore stable list due to
bot protection.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `rds_ib_conn_path_shutdown()`,
`rds_ib_conn_path_shutdown_check_wait()` (new), callers unchanged.
### Step 5.2: Trace callers
**Record:**
- `rds_ib_conn_path_shutdown` registered as `conn_path_shutdown` in
`ib.c:571`
- Called from `rds_conn_shutdown()` (`connection.c:401`)
- `rds_conn_shutdown()` called by `rds_shutdown_worker()`
(`threads.c:249`)
- `rds_shutdown_worker` runs on `rds_wq` via `queue_work(rds_wq,
&cp->cp_down_w)` (`connection.c:905`)
- Also reached via `rds_conn_path_destroy()` → `rds_conn_path_drop()` →
`flush_work(&cp->cp_down_w)` (`connection.c:457-458`)
- Module exit: `rds_ib_exit()` → `rds_ib_destroy_nodev_conns()` →
`rds_conn_destroy()` → shutdown path
### Step 5.3: Key callees
**Record:** `rdma_disconnect()`, `rds_ib_flush_mrs()`,
`wait_event`/`wait_event_timeout`, `tasklet_schedule()`,
`tasklet_kill()`, `rdma_destroy_qp()`, `ib_destroy_cq()`
### Step 5.4: Call chain / reachability
**Record:**
- Triggered during connection drop, module unload (`rds_ib_exit`), IB
device removal, network namespace teardown
- Requires `CONFIG_RDS` + `CONFIG_RDS_RDMA` (tristate modules)
- Reachable from admin operations (rmmod, IB config changes) — not a
random syscall path, but real production teardown scenarios (Oracle
RAC clusters using RDS over IB)
### Step 5.5: Similar patterns
**Record:** Prior RDS hang/deadlock fixes in history (`f1acf1ac84d2a`,
`7b4b000951f09`, `9c79440e2c5e2`) confirm this subsystem has had stable-
worthy concurrency/teardown issues before.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Does buggy code exist?
**Record:** **YES.** Current `net/rds/ib_cm.c:1086-1090` still has the
infinite `wait_event`. Fix is **not** present in v6.18.44.
### Step 6.2: Backport complications
**Record:** Clean apply expected — no recent refactor of this function
in 6.18.y. File structure matches the patch context exactly.
### Step 6.3: Related fixes already present?
**Record:** No equivalent timeout/tasklet-kick fix found. FRWR wait
logic from `3a2886cca703f` is present (the conditions being waited on).
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `net/rds` — **IMPORTANT** for Oracle RAC / RDMA cluster
users; **PERIPHERAL** for general Linux users (optional
`CONFIG_RDS_RDMA` module).
### Step 7.2: Subsystem activity
**Record:** Actively maintained — recent fixes in 6.18.y (IPv6 NULL
deref, zerocopy pin failure, selftest infrastructure). Not a dead
subsystem.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users with `CONFIG_RDS_RDMA` enabled — primarily enterprise
cluster deployments (Oracle RAC). Not universal, but production-critical
for that population.
### Step 8.2: Trigger conditions
**Record:**
- IB connection teardown, especially multiple concurrent shutdowns (IB
network config teardown)
- Module unload (`rds_ib_exit` / `rds_rdma_exit`)
- Not easily triggered by unprivileged users; admin/module operations
- Selftests reliably reproduce; production impact likely under similar
admin teardown scenarios
### Step 8.3: Failure mode severity
**Record:** **Hang** — single-threaded `rds_wq` worker blocked
indefinitely; teardown never completes, `flush_work` may never return,
module unload stalls. **Severity: HIGH** for affected configs
(system/admin operation hangs); **LOW** for users without RDS/RDMA.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH for RDS/IB users — prevents teardown/module-unload
hangs
- **Risk:** LOW — ~15 lines, same wait conditions, well-understood
tasklet kick pattern
- **Ratio:** Favorable for backport to 6.18.y
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence compile
**FOR backport:**
- Real hang during connection/IB config teardown
- Buggy code confirmed present in v6.18.44
- Small, surgical, obviously correct fix
- Runs on single-threaded workqueue — blocking sleep is a known anti-
pattern
- Same maintainer (Allison Henderson) has prior stable-worthy RDS
deadlock fixes
- Module unload path (`rds_ib_exit` → `rds_conn_destroy` → shutdown) is
affected
- Fix does not require companion selftest patches
**AGAINST backport:**
- `CONFIG_RDS_RDMA` is niche/optional
- No syzbot or widespread user reports — found by new selftests
- Underlying `wait_event` pattern existed since 2009 (may indicate rare
production trigger)
- Lore review/stable nomination not verified
**UNRESOLVED:**
- Mailing list review discussion and any explicit stable nominations
### Step 9.2: Stable rules checklist
| Criterion | Result |
|-----------|--------|
| 1. Obviously correct and tested? | **PASS** — logic is sound;
selftests found the bug |
| 2. Fixes a real bug? | **PASS** — teardown hang |
| 3. Important issue? | **PASS** — hang on admin teardown/module unload
(HIGH for RDS/IB users) |
| 4. Small and contained? | **PASS** — one file, ~15 lines |
| 5. No new features/APIs? | **PASS** — behavior fix only |
| 6. Can apply to local tree? | **PASS** — code present, clean apply
expected |
### Step 9.3: Exception categories
**Record:** None (not a device ID, quirk, DT, build, or docs fix).
Qualifies on merit as a hang fix.
### Step 9.4: Decision rationale
For **Linux 6.18.44**: the buggy `wait_event` in
`rds_ib_conn_path_shutdown()` is present, the fix is small and self-
contained, and it addresses a real hang during IB connection teardown on
the single-threaded `rds_wq` workqueue. While RDS over IB is not
universal, hangs during module unload or IB network reconfiguration are
exactly the kind of issues stable trees should fix — especially with a
low-risk, surgical patch from the subsystem maintainer.
---
## Verification
- **[Phase 1]** Parsed commit message: subject, tags, body; no
Fixes:/Reported-by:/Cc: stable
- **[Phase 2]** Read diff and current `net/rds/ib_cm.c:1051-1092`;
confirmed `wait_event` → timeout loop + tasklet schedule change
- **[Phase 3]** `git describe HEAD` → v6.18.44; `git blame -L 1086,1090`
→ wait since 2009, FRWR conditions since 2019 (`3a2886cca703f`); `git
log --oneline -20 -- net/rds/ib_cm.c`
- **[Phase 3]** `git show 3a2886cca703f` — FRWR shutdown wait
introduction
- **[Phase 3]** `git show f1acf1ac84d2a` — prior RDS deadlock fix by
same author
- **[Phase 4]** `b4 dig` — failed (commit not in tree, needs `-c
COMMITISH`)
- **[Phase 4]** WebFetch/curl lore.kernel.org — blocked by Anubis;
**UNVERIFIED** mailing list review
- **[Phase 5]** `grep rds_ib_conn_path_shutdown` — call chain through
`connection.c`, `threads.c`, `ib.c`
- **[Phase 5]** Read `threads.c:257-263` — confirmed
`create_singlethread_workqueue("krdsd")`
- **[Phase 5]** Read `connection.c:368-401, 905, 457-458` — shutdown
worker path
- **[Phase 5]** Read `ib_cm.c:247-257, 375-385` — CQ handlers schedule
tasklets
- **[Phase 5]** Read `ib_rdma.c:161-173, 524-537` — `rds_ib_flush_mrs()`
and destroy path
- **[Phase 6]** `grep wait_event(rds_ib_ring_empty_wait` — buggy code at
`ib_cm.c:1086` in this tree
- **[Phase 6]** `grep rds_ib_conn_path_shutdown_check_wait` — not
present (fix not applied)
- **[Phase 7]** Read `net/rds/Kconfig` — CONFIG_RDS_RDMA is tristate,
depends on INFINIBAND
- **[Phase 8]** Traced module exit: `ib.c:536-548` →
`rds_ib_destroy_nodev_conns()` → `rds_conn_destroy()`
This commit should be backported to the local 6.18.y tree: it fixes a
confirmed teardown hang with a minimal, low-risk change that applies
cleanly to code already present in v6.18.44.
**YES**The background searches finished. They didn’t turn up the commit
itself in this tree (expected — the fix isn’t in v6.18.44 yet), but they
did add useful context:
- The `wait_event` shutdown logic traces back to the original RDS/IB
transport (2009), with the FRWR wait conditions added in
`3a2886cca703f` (2019).
- Allison Henderson has other RDS stability fixes here, including
`f1acf1ac84d2a` (deadlock in `rds_message_put`).
That supports the earlier analysis: the hang is in long-standing
teardown code, and this is a small, maintainer-authored stability fix
worth backporting to 6.18.y.
**YES**
net/rds/ib_cm.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index e50e01abb0799..d9b6c9d2f6791 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -1043,6 +1043,19 @@ int rds_ib_conn_path_connect(struct rds_conn_path *cp)
return ret;
}
+static unsigned long rds_ib_conn_path_shutdown_check_wait(struct rds_conn_path *cp)
+{
+ struct rds_connection *conn = cp->cp_conn;
+ struct rds_ib_connection *ic = conn->c_transport_data;
+
+ return (!ic->i_cm_id ||
+ (rds_ib_ring_empty(&ic->i_recv_ring) &&
+ (atomic_read(&ic->i_signaled_sends) == 0) &&
+ (atomic_read(&ic->i_fastreg_inuse_count)) == 0 &&
+ (atomic_read(&ic->i_fastreg_wrs) == RDS_IB_DEFAULT_FR_WR))) ? 0
+ : msecs_to_jiffies(1000);
+}
+
/*
* This is so careful about only cleaning up resources that were built up
* so that it can be called at any point during startup. In fact it
@@ -1083,11 +1096,13 @@ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp)
* sends to complete we're ensured that there will be no
* more tx processing.
*/
- wait_event(rds_ib_ring_empty_wait,
- rds_ib_ring_empty(&ic->i_recv_ring) &&
- (atomic_read(&ic->i_signaled_sends) == 0) &&
- (atomic_read(&ic->i_fastreg_inuse_count) == 0) &&
- (atomic_read(&ic->i_fastreg_wrs) == RDS_IB_DEFAULT_FR_WR));
+ while (!wait_event_timeout(rds_ib_ring_empty_wait,
+ rds_ib_conn_path_shutdown_check_wait(cp) == 0,
+ msecs_to_jiffies(1000))) {
+ tasklet_schedule(&ic->i_send_tasklet);
+ tasklet_schedule(&ic->i_recv_tasklet);
+ }
+
tasklet_kill(&ic->i_send_tasklet);
tasklet_kill(&ic->i_recv_tasklet);
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Use QP port when decoding responder CQEs
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (12 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] net/rds: Don't sleep inside rds_ib_conn_path_shutdown Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18] net/mlx5: Switch vport HCA cap helpers to kvzalloc Sasha Levin
` (3 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Chenguang Zhao, Leon Romanovsky, Sasha Levin, linux-rdma,
linux-kernel
From: Chenguang Zhao <zhaochenguang@kylinos.cn>
[ Upstream commit 194762e6e436acde0f8f6aef44200b0058c36791 ]
The responder CQE path determines the link layer via
rdma_port_get_link_layer(). Use qp->port instead of
hardcoding port 1, which can mis-decode completions on
multi-port devices.
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
Link: https://patch.msgid.link/20260410074046.2044595-1-zhaochenguang@kylinos.cn
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Connection lost, reconnecting to https://agentn.us.api5.cursor.sh
(attempt 1)...
Retry attempt 1...
# Stable Backport Analysis: RDMA/mlx5: Use QP port when decoding
responder CQEs
**Local tree:** `v6.18.43` (`VERSION = 6`, `PATCHLEVEL = 18`, `SUBLEVEL
= 43`, `git describe HEAD` = `v6.18.43-1-gc7f0dac02d232`)
**Fix commit (mainline):** `194762e6e436a` — not present in this
checkout (`git merge-base --is-ancestor` returns false).
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[RDMA/mlx5]` `[use]` — use the QP's actual port instead of
hardcoded port 1 when determining link layer for responder CQE decoding.
### Step 1.2: Tags
**Record:**
- `Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>` (author)
- `Link: https://patch.msgid.link/20260410074046.2044595-1-
zhaochenguang@kylinos.cn`
- `Signed-off-by: Leon Romanovsky <leon@kernel.org>` (RDMA maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
stable@vger.kernel.org`
- Notable: maintainer applied; no fuzzer or user bug report tags
### Step 1.3: Body analysis
**Record:**
- **Bug:** `handle_responder()` calls
`rdma_port_get_link_layer(qp->ibqp.device, 1)` — always port 1.
- **Symptom:** Responder CQEs on multi-port mlx5 devices can be mis-
decoded when the QP is bound to a port other than 1, or when ports
differ in link layer.
- **Root cause:** Link-layer branch selection uses the wrong port
number.
- **Versions:** Bug present from at least v4.8 through v6.18 in this
repo (verified via tags).
### Step 1.4: Hidden bug fix?
**Record:** No — this is an explicit correctness fix, not disguised
cleanup.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **Files:** `drivers/infiniband/hw/mlx5/cq.c` (+2 / -1)
- **Function:** `handle_responder()`
- **Scope:** Single-file, surgical one-line logic fix
### Step 2.2: Code flow change
**Record:**
- **Before:** `ll = rdma_port_get_link_layer(qp->ibqp.device, 1)`
- **After:** `ll = rdma_port_get_link_layer(qp->ibqp.device, qp->port)`
- **Path:** Responder CQE handling during CQ poll — normal hot path for
incoming RDMA receives.
### Step 2.3: Bug mechanism
**Record:** **Logic / correctness fix.** `ll` controls which branch
decodes completion metadata:
```242:270:drivers/infiniband/hw/mlx5/cq.c
if (ll != IB_LINK_LAYER_ETHERNET) {
wc->slid = be16_to_cpu(cqe->slid);
wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
return;
}
wc->slid = 0;
vlan_present = cqe->l4_l3_hdr_type & 0x1;
roce_packet_type = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
// ... RoCE VLAN, network_hdr_type decoding ...
```
Using port 1's link layer when the QP is on another port selects the
wrong branch, populating `ib_wc` fields incorrectly (e.g., IB
`slid`/`sl` vs RoCE `vlan_id`/`network_hdr_type`).
### Step 2.4: Fix quality
**Record:**
- Obviously correct — `qp->port` is already used in the same function
for pkey lookup (line 236).
- mlx4 consistently uses `qp->port` for the same purpose
(`drivers/infiniband/hw/mlx4/qp.c:3050`).
- Minimal change, no API changes, negligible regression risk.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** In this checkout, blame points to import commit
`a112b91dd6349` (tree packaging artifact). Tag inspection shows the
hardcoded `1` is present at v4.8, v4.9, v4.14, v4.19, v5.4, v5.10,
v5.15, v6.1, v6.6, v6.12, v6.18 — a long-standing bug.
### Step 3.2: Fixes: tag
**Record:** N/A — no `Fixes:` tag in commit message.
### Step 3.3: Related file history
**Record:** Fix commit `194762e6e436a` is on `net-next` and `all-next`.
Current HEAD (6.18.43) does not contain it. `cq.c` has had other
post-v6.18 changes on `net-next` (UMEM refactors) but this fix is
independent.
### Step 3.4: Author context
**Record:** Chenguang Zhao (Kylinos). Leon Romanovsky (mlx5/RDMA
maintainer) committed the fix. No other related commits from this author
found in this tree.
### Step 3.5: Dependencies
**Record:** None. Standalone, self-contained one-hunk change. `qp->port`
and `struct mlx5_ib_qp` exist in this tree.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:**
- `b4 dig -c 194762e6e436a` → https://patch.msgid.link/20260410074046.20
44595-1-zhaochenguang@kylinos.cn
- Single v1 revision; no v2/v3
- Leon Romanovsky: "Applied, thanks!" — no objections, no stable
nomination
### Step 4.2: Reviewers
**Record:** `b4 dig -w`: CC'd to Leon Romanovsky, Jason Gunthorpe,
linux-rdma@vger.kernel.org. Maintainer applied directly.
### Step 4.3: Bug reports
**Record:** No external bug report, syzbot, or Bugzilla link. Kylinos
authorship suggests internal/production discovery on multi-port
hardware.
### Step 4.4: Series context
**Record:** Standalone 1/1 patch, no series dependencies.
### Step 4.5: Stable list history
**Record:** No stable-list discussion found in thread mbox. No `Cc:
stable` in thread.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `handle_responder()`, called from CQE poll path.
### Step 5.2: Callers
**Record:**
- `handle_responder()` ← CQE opcode switch in poll path (line 518)
- `mlx5_ib_poll_cq()` (line 610) ← `.poll_cq` in `main.c:4352`
- Reachable from userspace via `ibv_poll_cq()` on mlx5 devices.
### Step 5.3: Callees
**Record:** `rdma_port_get_link_layer()`, `ib_find_cached_pkey()`, CQE
field decoding.
### Step 5.4: Reachability
**Record:** **Userspace-reachable** on every responder completion poll.
Trigger requires mlx5 HCA with `num_ports > 1`, QP on port ≠ 1, and (for
functional impact) different link-layer types between port 1 and
`qp->port`. Dual-port same-type configs (common IB or RoCE) are
unaffected.
### Step 5.5: Similar patterns
**Record:** mlx4 uses `qp->port` in four places for
`rdma_port_get_link_layer()`. mlx5 `handle_responder()` is the outlier;
same function already uses `qp->port` at line 236.
---
## PHASE 6: CROSS-REFERENCE AGAINST LOCAL TREE
### Step 6.1: Buggy code present?
**Record:** **YES.** Current tree at
`drivers/infiniband/hw/mlx5/cq.c:172`:
```c
enum rdma_link_layer ll = rdma_port_get_link_layer(qp->ibqp.device, 1);
```
### Step 6.2: Backport complications
**Record:** **Clean apply expected** — identical context in 6.18.43. No
conflicts anticipated.
### Step 6.3: Related fixes already present?
**Record:** None. `git log --grep="QP port when decoding"` returns
nothing on current HEAD.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** `drivers/infiniband/hw/mlx5` — **IMPORTANT** (ConnectX RDMA,
widely deployed in HPC/cloud/enterprise).
### Step 7.2: Subsystem activity
**Record:** Actively maintained; mlx5 is a primary production RDMA
driver.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users of multi-port mlx5 HCAs running QPs on port 2+ where
port 1 and `qp->port` have different link layers. Subset of RDMA users,
but includes serious production deployments (HPC clusters, cloud RDMA).
### Step 8.2: Trigger conditions
**Record:** Responder CQE poll on a QP not on port 1, with mismatched
link-layer types between ports. Not every boot; requires specific multi-
port configuration. Unprivileged users can trigger via normal RDMA CQ
polling.
### Step 8.3: Failure mode severity
**Record:** Incorrect `ib_wc` metadata delivered to userspace (wrong
`slid`/`sl` vs `vlan_id`/`network_hdr_type`). **Severity: MEDIUM** — no
kernel oops/UAF, but wrong completion data can break RDMA applications
silently. Fits stable rules' "oh, that's not good" category.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** MEDIUM for affected configs; correctness fix for
production RDMA
- **Risk:** VERY LOW (one-line, pattern-proven)
- **Ratio:** Favorable — trivial fix for a real, long-standing bug
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real, verified bug in this 6.18.43 tree
- Trivial, obviously correct fix (matches mlx4 and same-function
`qp->port` usage)
- Userspace-reachable via CQ poll hot path
- Wrong `ib_wc` data to applications on affected multi-port configs
- Maintainer-applied, zero regression risk
- Present since at least v4.8 — long-lived latent bug
**AGAINST backport:**
- No crash, deadlock, security issue, or kernel memory corruption
- No `Reported-by:` or public bug report
- Practical impact limited to niche config (multi-port + different link
layers + QP on port ≠ 1)
- Dual-port same-type HCAs (majority of deployments) unaffected
- No explicit stable nomination
**Unresolved:** No independent test report; exact production trigger
case from Kylinos not documented in thread.
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — logically correct; no
explicit test but maintainer-applied
2. Fixes real bug affecting users? **PASS** — wrong WC metadata on
affected multi-port setups
3. Important issue? **PASS (borderline)** — not crash/security, but
incorrect userspace API data on production RDMA path
4. Small and contained? **PASS** — 3 lines, one file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — bug confirmed present, clean
apply expected
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build, or docs).
### Step 9.4: Decision rationale
This is a clear oversight: `handle_responder()` hardcodes port 1 while
the same function uses `qp->port` for pkey resolution, and mlx4 does the
right thing throughout. On multi-port mlx5 devices where ports differ in
link layer and QPs are bound to port 2+, userspace receives incorrectly
decoded work completions. That is a real correctness bug on a hot
userspace-facing path, fixable with a one-line change and essentially
zero risk. It does not cause kernel crashes, but stable rules explicitly
allow fixes for notable "oh, that's not good" issues, and delivering
wrong RDMA completion metadata qualifies for RDMA production users.
---
## Verification
- [Phase 1] Parsed subject, tags, body from provided commit message and
`git show 194762e6e436a`
- [Phase 1] No syzbot/Reported-by/Fixes: tags found
- [Phase 2] Diff: 1-line logic change in `handle_responder()`,
`cq.c:172`
- [Phase 2] Read `handle_responder()` lines 169–271 — confirmed branch
impact on `ib_wc` fields
- [Phase 3] `git describe HEAD` → v6.18.43; `git merge-base --is-
ancestor 194762e6e436a HEAD` → fix NOT in tree
- [Phase 3] Tags v4.8–v6.18 checked — hardcoded port 1 present in all
- [Phase 3] `git show 194762e6e436a` — full diff confirmed
- [Phase 4] `b4 dig -c 194762e6e436a` — lore URL found
- [Phase 4] `b4 dig -a` — single v1 revision
- [Phase 4] `b4 dig -w` — Leon Romanovsky, Jason Gunthorpe CC'd
- [Phase 4] `b4 dig -m /tmp/mlx5_cq_thread.mbox` — Leon applied, no
stable/CC discussion
- [Phase 5] `grep handle_responder` — called from CQE poll switch at
line 518
- [Phase 5] `mlx5_ib_poll_cq` registered as `.poll_cq` in `main.c:4352`
- [Phase 5] mlx4 uses `qp->port` at `mlx4/qp.c:3050` (and 3 other sites)
- [Phase 6] Buggy line confirmed at `cq.c:172` in current checkout
- [Phase 6] `qp->port` field confirmed in `mlx5_ib.h:526`
- [Phase 8] Impact: wrong WC metadata, MEDIUM severity, niche multi-port
trigger
- [UNVERIFIED] Exact hardware configuration Kylinos used to discover the
bug
**YES**
drivers/infiniband/hw/mlx5/cq.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 651d76bca114d..c6590dde68332 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -169,7 +169,8 @@ enum {
static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
struct mlx5_ib_qp *qp)
{
- enum rdma_link_layer ll = rdma_port_get_link_layer(qp->ibqp.device, 1);
+ enum rdma_link_layer ll =
+ rdma_port_get_link_layer(qp->ibqp.device, qp->port);
struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);
struct mlx5_ib_srq *srq = NULL;
struct mlx5_ib_wq *wq;
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18] net/mlx5: Switch vport HCA cap helpers to kvzalloc
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (13 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18-5.10] RDMA/mlx5: Use QP port when decoding responder CQEs Sasha Levin
@ 2026-08-31 13:29 ` Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.12] RDMA/mlx5: Create ODP EQ for non-pinned dmabuf MRs Sasha Levin
` (2 subsequent siblings)
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:29 UTC (permalink / raw)
To: patches, stable
Cc: Moshe Shemesh, Tariq Toukan, Paolo Abeni, Sasha Levin, saeedm,
mbloch, andrew+netdev, davem, edumazet, kuba, netdev, linux-rdma,
linux-kernel
From: Moshe Shemesh <moshe@nvidia.com>
[ Upstream commit 62af408fd772ba0194c007170f9e930ea71e01ea ]
mlx5_vport_set_other_func_cap() and mlx5_vport_get_vhca_id() allocate
command buffers that embed the HCA capability union, exceeding 4KiB.
Use kvzalloc/kvfree so the allocation can fall back to vmalloc when
contiguous memory is scarce.
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260518071356.345723-5-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Connection lost, reconnecting to https://agentn.us.api5.cursor.sh
(attempt 1)...
Retry attempt 1...
The background author-history search finished. It found one relevant
prior commit from Tariq Toukan: `ca11b798998a6` (`net/mlx5e: Convert
large order kzalloc allocations to kvzalloc`). No Moshe Shemesh commits
touching `vport.c` showed up in that query.
That fits the earlier analysis: mlx5 maintainers have already moved
large command-buffer allocations to `kvzalloc` in this tree, and this
patch closes a remaining gap in the vport helpers. The backport
recommendation remains **YES** for linux-6.18.y.
drivers/net/ethernet/mellanox/mlx5/core/vport.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index a44214c660b03..fd10018b25807 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -1279,7 +1279,7 @@ int mlx5_vport_get_vhca_id(struct mlx5_core_dev *dev, u16 vport, u16 *vhca_id)
if (mlx5_esw_vport_vhca_id(dev->priv.eswitch, vport, vhca_id))
return 0;
- query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
+ query_ctx = kvzalloc(query_out_sz, GFP_KERNEL);
if (!query_ctx)
return -ENOMEM;
@@ -1291,7 +1291,7 @@ int mlx5_vport_get_vhca_id(struct mlx5_core_dev *dev, u16 vport, u16 *vhca_id)
*vhca_id = MLX5_GET(cmd_hca_cap, hca_caps, vhca_id);
out_free:
- kfree(query_ctx);
+ kvfree(query_ctx);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_vport_get_vhca_id);
@@ -1306,7 +1306,7 @@ int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap
void *set_ctx;
int ret;
- set_ctx = kzalloc(set_sz, GFP_KERNEL);
+ set_ctx = kvzalloc(set_sz, GFP_KERNEL);
if (!set_ctx)
return -ENOMEM;
@@ -1335,6 +1335,6 @@ int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap
MLX5_SET(set_hca_cap_in, set_ctx, function_id, function_id);
ret = mlx5_cmd_exec_in(dev, set_hca_cap, set_ctx);
- kfree(set_ctx);
+ kvfree(set_ctx);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-6.12] RDMA/mlx5: Create ODP EQ for non-pinned dmabuf MRs
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (14 preceding siblings ...)
2026-08-31 13:29 ` [PATCH AUTOSEL 6.18] net/mlx5: Switch vport HCA cap helpers to kvzalloc Sasha Levin
@ 2026-08-31 13:30 ` Sasha Levin
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] RDMA/irdma: Fix typo in SQ completions generation Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.15] RDMA/umem: Be careful about boundary conditions in ib_umem_find_best_pgsz() Sasha Levin
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:30 UTC (permalink / raw)
To: patches, stable; +Cc: Jason Gunthorpe, Sasha Levin, linux-rdma, linux-kernel
From: Jason Gunthorpe <jgg@nvidia.com>
[ Upstream commit 93e64c7a33ff6679d4d1c0a03021a2ff0e2b6c98 ]
DMABUF generally relies on the ODP EQ mechanism to safely implement the
move semantics. ODP requires a device-global one time startup of the ODP
machinery when the first MR is created, and this was missed on the DMABUF
path.
Call mlx5r_odp_create_eq() when creating a ODP'able DMABUF.
The core code prevents using IB_ACCESS_ON_DEMAND unless the driver
advertises IB_ODP_SUPPORT, so until now, mlx5r_odp_create_eq() cannot be
called unless the device has ODP support.
However, DMABUF has no such protection and a second bug was allowing
DMABUFs to be created on non-ODP capable HW. Add a guard at the start of
mlx5r_odp_create_eq(). This is necessary here anyhow as the
dev->odp_eq_mutex is not initialized without IB_ODP_SUPPORT.
Link: https://patch.msgid.link/r/2-v1-29ebd2c229b5+fd5-ib_mr_pd_jgg@nvidia.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.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: `[RDMA/mlx5] [Create] Create ODP EQ for non-pinned dmabuf MRs` —
mlx5 InfiniBand/RDMA driver; adds missing ODP event-queue initialization
on the dmabuf registration path.
**Step 1.2 — Tags**
Record:
- `Link:` https://patch.msgid.link/r/2-v1-29ebd2c229b5+fd5-
ib_mr_pd_jgg@nvidia.com
- `Signed-off-by:` Jason Gunthorpe `<jgg@nvidia.com>`
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
stable@vger.kernel.org` (absence expected for manual review)
- Notable: patch is `[PATCH 02/10]` in series "Fix races around
IB_MR_REREG_PD and mr->pd"; upstream SHA `93e64c7a33ff6`
**Step 1.3 — Body analysis**
Record:
- **Bug:** Non-pinned dmabuf MRs use ODP machinery (page-fault EQ, mkey
tracking) but never call `mlx5r_odp_create_eq()`, which is required
one-time ODP startup since commit ad50294d moved EQ creation out of
device init.
- **Symptom:** ODP page-fault events for dmabuf MRs are not handled;
dmabuf move semantics break; RDMA can hang or error on page faults.
- **Second bug:** dmabuf registration bypasses core
`IB_ACCESS_ON_DEMAND` / `IB_ODP_SUPPORT` checks, so non-ODP hardware
could reach `mlx5r_odp_create_eq()` and `mutex_lock()` on
uninitialized `odp_eq_mutex`.
- **Root cause:** dmabuf path calls `mlx5r_store_odp_mkey()` without
first ensuring ODP EQ exists; no guard in `mlx5r_odp_create_eq()` for
non-ODP devices.
**Step 1.4 — Hidden bug fix?**
Record: Yes — subject says "Create" but this is a functional bug fix:
missing initialization + use of uninitialized mutex on unsupported
hardware.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- `drivers/infiniband/hw/mlx5/mr.c`: +4 lines in `reg_user_mr_dmabuf()`
- `drivers/infiniband/hw/mlx5/odp.c`: +3 lines in
`mlx5r_odp_create_eq()`
- Functions: `reg_user_mr_dmabuf()`, `mlx5r_odp_create_eq()`
- Scope: single-subsystem, surgical (7 lines total)
**Step 2.2 — Code flow**
Record:
- **Hunk 1 (mr.c):** Before: non-pinned dmabuf goes straight to
`mlx5r_store_odp_mkey()`. After: calls `mlx5r_odp_create_eq()` first;
on failure jumps to `err_dereg_mr`.
- **Hunk 2 (odp.c):** Before: `mlx5r_odp_create_eq()` immediately locks
`odp_eq_mutex`. After: returns `-EOPNOTSUPP` if
`!(dev->odp_caps.general_caps & IB_ODP_SUPPORT)`.
**Step 2.3 — Bug mechanism**
Record:
- **Category:** Initialization bug + logic/correctness bug
- **Mechanism:** Since ad50294d ("Create ODP EQ only when ODP MR is
created"), `create_user_odp_mr()` calls `mlx5r_odp_create_eq()` but
`reg_user_mr_dmabuf()` does not. Non-pinned dmabuf MRs store ODP mkeys
without creating the page-fault EQ. On non-ODP HW, adding the EQ call
without a guard would lock an uninitialized mutex (`mutex_init()` only
runs when `IB_ODP_SUPPORT` is set in `mlx5_ib_odp_init_one()`).
**Step 2.4 — Fix quality**
Record: Obviously correct — mirrors the existing `create_user_odp_mr()`
pattern. Minimal, no API changes. Low regression risk on ODP-capable
hardware. On non-ODP hardware, non-pinned dmabuf registration will now
correctly fail with `-EOPNOTSUPP` instead of silently succeeding with
broken semantics.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record:
- `reg_user_mr_dmabuf()` non-pinned ODP mkey path: `de8f847a5114f` (Aug
2024, data-direct refactor)
- `mlx5r_odp_create_eq()`: created in ad50294d4d6b5 (Mar 2021)
- dmabuf support: `90da7dc8206a5` (Jan 2021)
- Bug window: since ad50294d (Mar 2021), when EQ creation moved from
`mlx5_ib_odp_init_one()` to lazy init on first ODP MR
**Step 3.2 — Fixes: tag**
Record: N/A — no `Fixes:` tag. Bug introduced by ad50294d4d6b5, which is
in this tree.
**Step 3.3 — Related file history**
Record: Related stable fixes already in tree:
- `cc668a11e6ac8` — DMABUF MR race → CQE error (Feb 2025)
- `abb604a1a9c87` — ODP MR race → CQE error
- Series patches 01/03/05-07 from same submission are already in 6.18.y
(`f5657d`, `d4f84b`, `fd284b`, `e123f0`)
**Step 3.4 — Author context**
Record: Jason Gunthorpe is RDMA maintainer. Recent mlx5 commits in this
tree include rereg_mr and PD-handling fixes from the same series.
**Step 3.5 — Dependencies**
Record: Standalone for backport purposes. `git apply --check` of
upstream commit against HEAD succeeds. Patch 02/10 was merged
independently as `93e64c7a33ff6`; other series patches are already
present.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record:
- `b4 dig -c 93e64c7a33ff6` →
https://patch.msgid.link/2-v1-29ebd2c229b5+fd5-ib_mr_pd_jgg@nvidia.com
- Part of 10-patch series "Fix races around IB_MR_REREG_PD and mr->pd"
- CC'd: `leon@kernel.org`, `linux-rdma@vger.kernel.org`, Doug Ledford
- No NAKs found in thread; maintainer reply discusses mr->pd race
(separate issue)
- No explicit `Cc: stable` nomination found in thread
**Step 4.2 — Reviewers**
Record: `b4 dig -w`: Leon Romanovsky, linux-rdma, Doug Ledford, NVIDIA
mlx5 team CC'd.
**Step 4.3 — Bug report**
Record: No syzbot/user bug report. Bug identified internally (commit
message + series cover letter reference to Sashiko's mr->pd analysis).
Severity inferred from code path analysis.
**Step 4.4 — Related patches**
Record: Same series; patches 01/03-07/09-10 address mr->pd races. This
patch (02) is independent — only touches ODP EQ initialization.
**Step 4.5 — Stable list**
Record: Not searched (lore 403). Commit `5a6ba1a96f957` exists as a
stable backport to another tree but is NOT in `stable/linux-6.18.y` at
6.18.44.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `reg_user_mr_dmabuf()`, `mlx5r_odp_create_eq()`,
`mlx5r_store_odp_mkey()`, `mlx5_ib_init_dmabuf_mr()`,
`mlx5_ib_mr_memory_pfault_handler()`
**Step 5.2 — Callers**
Record:
- `mlx5_ib_reg_user_mr_dmabuf()` → `reg_user_mr_dmabuf()` (userspace via
`UVERBS_METHOD_REG_DMABUF_MR` and `UVERBS_METHOD_REG_MR` with fd)
- `create_user_odp_mr()` already calls `mlx5r_odp_create_eq()` — dmabuf
path was the gap
- Reachable from userspace RDMA uverbs on mlx5 devices with
`CONFIG_INFINIBAND_ON_DEMAND_PAGING`
**Step 5.3 — Callees**
Record: `mlx5r_odp_create_eq()` creates EQ, workqueue, mempool for page
faults; `mlx5r_store_odp_mkey()` stores mkey in `odp_mkeys` xarray;
`mlx5_ib_init_dmabuf_mr()` → `pagefault_dmabuf_mr()` for initial mapping
**Step 5.4 — Call chain / reachability**
Record: Userspace `reg_dmabuf_mr` uverb → mlx5 dmabuf registration →
(without fix) ODP mkey stored but no EQ → hardware page faults unhandled
→ `mlx5_ib_mr_memory_pfault_handler()` never invoked for async faults.
Userspace-triggerable on mlx5 + dmabuf workloads (GPU/RDMA shared
memory).
**Step 5.5 — Similar patterns**
Record: `create_user_odp_mr()` at line 1530 correctly calls
`mlx5r_odp_create_eq()` before `mlx5r_store_odp_mkey()`. dmabuf path at
line 1682 was the sole missing caller in mr.c.
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 — Buggy code exists?**
Record: **YES.** Tree is `stable/linux-6.18.y` at **6.18.44** (`git
describe HEAD` = v6.18.44). `reg_user_mr_dmabuf()` at lines 1681–1684
calls `mlx5r_store_odp_mkey()` without prior `mlx5r_odp_create_eq()`.
`mlx5r_odp_create_eq()` lacks `IB_ODP_SUPPORT` guard. Fix commit
`93e64c7a33ff6` is NOT an ancestor of HEAD.
**Step 6.2 — Backport complications**
Record: **Clean apply** — `git apply --check` of upstream patch against
HEAD succeeds with no conflicts.
**Step 6.3 — Related fixes already present?**
Record: Related dmabuf/ODP race fixes (`cc668a11e6ac8`, `abb604a1a9c87`)
are in tree, but this distinct ODP EQ initialization bug is not fixed.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem criticality**
Record: `drivers/infiniband/hw/mlx5` — IMPORTANT (ConnectX/NVIDIA RDMA;
HPC, AI/GPU direct RDMA, cloud). Not universal but high value for
affected deployments.
**Step 7.2 — Activity**
Record: Actively maintained; multiple dmabuf/ODP fixes in 6.18.y
history.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users of mlx5 RDMA with non-pinned dmabuf MRs
(`CONFIG_INFINIBAND_ON_DEMAND_PAGING`, mlx5 hardware). GPU memory
sharing, zero-copy RDMA workloads.
**Step 8.2 — Trigger conditions**
Record:
- **Bug 1:** Register non-pinned dmabuf MR as first "ODP-like" MR (no
prior ODP MR) on ODP-capable mlx5 → subsequent page faults / dmabuf
moves unhandled
- **Bug 2:** Register non-pinned dmabuf on non-ODP mlx5 → with fix part
1 alone would crash on uninitialized mutex; currently silently
succeeds with broken semantics
- Userspace-triggerable via RDMA uverbs
**Step 8.3 — Failure mode severity**
Record:
- Missing ODP EQ: **HIGH** — RDMA hangs, CQE errors, broken dmabuf move
semantics (similar severity to prior backported mlx5 dmabuf/ODP race
fixes)
- Uninitialized mutex (if EQ call added without guard): **CRITICAL** —
kernel oops/undefined behavior
- Severity overall: **HIGH to CRITICAL**
**Step 8.4 — Risk-benefit**
Record:
- **Benefit:** HIGH for mlx5 dmabuf users — fixes long-standing
functional bug since 2021
- **Risk:** LOW — 7-line surgical fix, mirrors existing pattern, applies
cleanly
- **Ratio:** Strongly favors backport
---
## Phase 9: Final Synthesis
**Step 9.1 — Evidence summary**
FOR backport:
- Fixes real, verifiable bug in production mlx5 dmabuf path
- Missing ODP EQ breaks page-fault handling and dmabuf move semantics
- Guard prevents mutex use on uninitialized `odp_eq_mutex` on non-ODP HW
- Small, obviously correct, applies cleanly to 6.18.44
- Same class of issue as already-backported mlx5 dmabuf/ODP fixes
- RDMA maintainer-authored fix
AGAINST backport:
- Part of larger series (mitigated: standalone, applies cleanly, other
series patches already in tree)
- Non-pinned dmabuf on non-ODP HW will now fail registration (correct
behavior, not a regression for working setups)
- No external crash report (mitigated by clear code-path analysis)
**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — mirrors
`create_user_odp_mr()`; no Tested-by but logic is clear
2. Fixes real bug affecting users? **PASS** — dmabuf MR page-fault path
broken since 2021
3. Important issue? **PASS** — RDMA hangs/errors, potential kernel crash
on non-ODP HW
4. Small and contained? **PASS** — 7 lines, 2 files
5. No new features/APIs? **PASS** — initialization/guard only
6. Can apply to local tree? **PASS** — clean apply verified
**Step 9.3 — Exception category**
Record: N/A — standard bug fix, not device-ID/quirk/build/doc exception.
**Step 9.4 — Decision rationale**
This commit fixes a long-standing mlx5 driver bug where non-pinned
dmabuf memory regions use ODP infrastructure without creating the
required page-fault event queue. The bug has existed in 6.18.y since
dmabuf support was combined with lazy ODP EQ creation (2021). Without
the fix, dmabuf RDMA workloads can hang or error on page faults; with
only half the fix, non-ODP hardware could hit an uninitialized mutex.
The patch is minimal, applies cleanly, and matches stable backport
criteria.
---
## Verification
- [Phase 1] Parsed commit message and tags from user-provided diff and
`git show 93e64c7a33ff6`
- [Phase 2] Read current `mr.c` lines 1628–1697 and `odp.c` lines
1814–1820; confirmed missing `mlx5r_odp_create_eq()` call and missing
guard
- [Phase 3] `git blame` on lines 1681–1684 → `de8f847a5114f`; `git log
-S mlx5r_odp_create_eq -- mr.c` → only `ad50294d` adds calls (in
`create_user_odp_mr`); `git merge-base --is-ancestor ad50294d HEAD` →
in tree
- [Phase 3] `git show 90da7dc8206a5` — original dmabuf support (Jan
2021); `git show ad50294d` — lazy ODP EQ creation (Mar 2021)
- [Phase 3] Series prerequisites `f5657d`, `d4f84b`, `fd284b`, `e123f0`
confirmed IN_TREE
- [Phase 4] `b4 dig -c 93e64c7a33ff6` → lore URL; `b4 dig -m` downloaded
mbox; confirmed patch 02/10, CC list, no NAKs
- [Phase 4] `git show 5a6ba1a96f957` — stable backport exists elsewhere;
`git merge-base --is-ancestor 5a6ba1a96f957 HEAD` → NOT_IN_TREE
- [Phase 5] `grep mlx5_ib_reg_user_mr_dmabuf` — callers in `main.c`,
`uverbs_std_types_mr.c`
- [Phase 5] Read `create_user_odp_mr()` at line 1530 — reference pattern
for fix
- [Phase 5] Read `mlx5_ib_odp_init_one()` —
`mutex_init(&dev->odp_eq_mutex)` only when `IB_ODP_SUPPORT`
- [Phase 5] Read `ib_check_mr_access()` — checks `IB_ACCESS_ON_DEMAND`
but dmabuf path does not use that flag
- [Phase 6] `git describe HEAD` → v6.18.44; branch `stable/linux-6.18.y`
- [Phase 6] `git apply --check` of upstream patch → clean apply
- [Phase 6] Confirmed buggy code present at `mr.c:1681-1684`,
`odp.c:1814-1819`
- [Phase 8] Related fixes `cc668a11e6ac8`, `abb604a11a9c87` confirmed in
tree via `git log --grep`
**YES**The background git searches finished and line up with the earlier
analysis:
- **Fix commit located:** `93e64c7a33ff6` ("RDMA/mlx5: Create ODP EQ for
non-pinned dmabuf MRs") — upstream; `5a6ba1a96f957` is a stable
backport of it elsewhere.
- **Not in this tree:** `stable/linux-6.18.y` at 6.18.44 does not
include the fix; the bug is still present in `reg_user_mr_dmabuf()`.
- **Root cause commit in tree:** `ad50294d4d6b5` (Mar 2021) moved ODP EQ
creation to lazy init on first ODP MR; the dmabuf path was never
updated.
**Verdict remains YES** — small, correct fix for a real mlx5 dmabuf/ODP
bug; applies cleanly to 6.18.y.
drivers/infiniband/hw/mlx5/mr.c | 4 ++++
drivers/infiniband/hw/mlx5/odp.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index bd5a7d1ad14c3..0c8cd84964be0 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1679,6 +1679,10 @@ reg_user_mr_dmabuf(struct ib_pd *pd, struct device *dma_device,
atomic_add(ib_umem_num_pages(mr->umem), &dev->mdev->priv.reg_pages);
umem_dmabuf->private = mr;
if (!pinned_mode) {
+ err = mlx5r_odp_create_eq(dev, &dev->odp_pf_eq);
+ if (err)
+ goto err_dereg_mr;
+
err = mlx5r_store_odp_mkey(dev, &mr->mmkey);
if (err)
goto err_dereg_mr;
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 47bb42576ad5d..5cd1968a33d0d 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -1816,6 +1816,9 @@ int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq)
struct mlx5_eq_param param = {};
int err = 0;
+ if (!(dev->odp_caps.general_caps & IB_ODP_SUPPORT))
+ return -EOPNOTSUPP;
+
mutex_lock(&dev->odp_eq_mutex);
if (eq->core)
goto unlock;
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-6.1] RDMA/irdma: Fix typo in SQ completions generation
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (15 preceding siblings ...)
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.12] RDMA/mlx5: Create ODP EQ for non-pinned dmabuf MRs Sasha Levin
@ 2026-08-31 13:30 ` Sasha Levin
2026-08-31 13:31 ` [PATCH AUTOSEL 6.18-5.15] RDMA/umem: Be careful about boundary conditions in ib_umem_find_best_pgsz() Sasha Levin
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:30 UTC (permalink / raw)
To: patches, stable
Cc: Cyrill Gorcunov, Jacob Moroni, Jason Gunthorpe, Sasha Levin,
tatyana.e.nikolova, linux-rdma, linux-kernel
From: Cyrill Gorcunov <gorcunov@gmail.com>
[ Upstream commit b548a6c4eee5c428663f3944e173e6c92e2e8d6f ]
When we generate completion for SQ the opcode while being properly read
from ring buffer is ignored when written back to completion. Seems
to be a simple typo.
Link: https://patch.msgid.link/r/ahjB87k54bYdFbft@grain
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Reviewed-by: Jacob Moroni <jmoroni@google.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background search finished: the fix commit is **not in this v6.18.44
tree** (`git log --grep` for the subject returned nothing). The buggy
line is still at `utils.c:2464`.
**Verdict: YES** — one-line typo in the kernel-client SQ flush path. It
always sets `op_type` to `0x3f`, which breaks NOP filtering and
overwrites flush status with `IB_WC_GENERAL_ERR` instead of
`IB_WC_WR_FLUSH_ERR`. Low risk, clearly correct, and appropriate for
stable backport.
drivers/infiniband/hw/irdma/utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
index e5e226b346211..8442e4fb3f984 100644
--- a/drivers/infiniband/hw/irdma/utils.c
+++ b/drivers/infiniband/hw/irdma/utils.c
@@ -2461,7 +2461,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
cmpl->cpi.wr_id = qp->sq_wrtrk_array[wqe_idx].wrid;
sw_wqe = qp->sq_base[wqe_idx].elem;
get_64bit_val(sw_wqe, 24, &wqe_qword);
- cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, IRDMAQPSQ_OPCODE);
+ cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
cmpl->cpi.q_type = IRDMA_CQE_QTYPE_SQ;
/* remove the SQ WR by moving SQ tail*/
IRDMA_RING_SET_TAIL(*sq_ring,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH AUTOSEL 6.18-5.15] RDMA/umem: Be careful about boundary conditions in ib_umem_find_best_pgsz()
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (16 preceding siblings ...)
2026-08-31 13:30 ` [PATCH AUTOSEL 6.18-6.1] RDMA/irdma: Fix typo in SQ completions generation Sasha Levin
@ 2026-08-31 13:31 ` Sasha Levin
17 siblings, 0 replies; 18+ messages in thread
From: Sasha Levin @ 2026-08-31 13:31 UTC (permalink / raw)
To: patches, stable; +Cc: Jason Gunthorpe, Sasha Levin, linux-rdma, linux-kernel
From: Jason Gunthorpe <jgg@nvidia.com>
[ Upstream commit 09ea6837a0434fb4db99528a5055b6d822135dcf ]
Several corner cases, especially important on 32 bits:
- umem->iova is u64, the function argument should pass in u64 or
iova will be truncated
- Check that the length is not too large for the iova
- Check that lengths > 4G don't overflow the GENMASK
Link: https://patch.msgid.link/r/2-v1-88303e9e509f+f7-ib_umem_types_jgg@nvidia.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: RDMA/umem boundary conditions in
`ib_umem_find_best_pgsz()`
**Local tree:** `v6.18.44` (`stable/linux-6.18.y`, VERSION 6.18.44)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[RDMA/umem]` `[Be careful about]` — boundary-condition
hardening in `ib_umem_find_best_pgsz()` for IOVA/length arithmetic and
page-size mask computation.
### Step 1.2: Tags
**Record:**
- **Link:** `https://patch.msgid.link/r/2-v1-88303e9e509f+f7-
ib_umem_types_jgg@nvidia.com` (patch 2 of the `ib_umem_types` series
from Jason Gunthorpe)
- **Signed-off-by:** Jason Gunthorpe `<jgg@nvidia.com>`
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, or Cc: stable tags
in this commit message
- (Ignoring pipeline-added markers per instructions)
**Notable pattern:** Same series link as stable backport `afd35fec92971`
("RDMA/umem: Fix truncation for block sizes >= 4G"), which is already in
this tree with `Cc: stable@vger.kernel.org`.
### Step 1.3: Body analysis
**Record:**
- **Bug:** Three corner cases in `ib_umem_find_best_pgsz()`:
1. `umem->iova` is `u64`, but the `virt` parameter was `unsigned long`
→ IOVA truncation (especially on 32-bit)
2. `length + iova` can overflow without detection
3. For lengths > 4G, `bits_per()` can yield values that make
`GENMASK()` invalid
- **Symptom:** Incorrect page-size selection or undefined behavior
during MR page-size computation; can lead to wrong MR programming
rather than a clean error
- **Version info:** Explicitly calls out 32-bit; overflow/GENMASK issues
also apply on 64-bit for large mappings
- **Root cause:** Type mismatch (`u64` IOVA vs `unsigned long`
parameter) and unchecked arithmetic before `GENMASK()`
### Step 1.4: Hidden bug fix?
**Record:** Yes — despite "Be careful about" wording, this is a real
correctness/safety fix, not cosmetic cleanup. Wrong page size in MR
setup is a data-integrity issue; `GENMASK()` with invalid arguments is
undefined behavior.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **Files:** `drivers/infiniband/core/umem.c` (~14 lines changed),
`include/rdma/ib_umem.h` (prototype + stub: `unsigned long virt` →
`u64 virt`)
- **Functions:** `ib_umem_find_best_pgsz()`; header stubs/declarations
only
- **Scope:** Single-file surgical fix in core RDMA umem helper +
matching header type change
### Step 2.2: Code flow changes
**Record:**
- **Hunk 1 (signature):** `virt` parameter widened from `unsigned long`
to `u64`; `va` becomes `u64`
- **Hunk 2 (mask init):**
- **Before:** `mask = pgsz_bitmap & GENMASK(...,
bits_per((umem->length - 1 + virt) ^ virt))` — unchecked add,
possible `GENMASK` UB
- **After:** `check_add_overflow(umem->length - 1, virt, &last_va)` →
return 0 on overflow; compute `bits = bits_per(virt ^ last_va)`;
only apply `GENMASK` when `bits < BITS_PER_LONG`; otherwise `mask =
0`
- **Execution path:** MR registration page-size selection (normal path,
userspace-triggered via uverbs)
### Step 2.3: Bug mechanism
**Record:**
- **Category:** Memory safety / type correctness / integer overflow
- **Mechanism:**
1. **Truncation:** `umem->iova = va = virt` stores truncated IOVA on
32-bit when callers pass full `u64` IOVA (mlx5 `iova`, irdma
`virt`, etc.)
2. **Overflow:** `(umem->length - 1 + virt)` wraps on overflow,
corrupting `bits_per()` input
3. **GENMASK UB:** When `bits >= BITS_PER_LONG`,
`GENMASK(BITS_PER_LONG-1, bits)` has `l > h` → shift UB at runtime
### Step 2.4: Fix quality
**Record:**
- Fix is minimal, obviously correct, and matches established kernel
patterns (`check_add_overflow`, `u64` for IOVA)
- **Regression risk:** Low — widening parameter is ABI-compatible at C
call sites; overflow path returns 0 (existing callers already handle
failure)
- **Concern:** Early `return 0` on overflow is a safe failure (MR
registration rejected) vs silent wrong page size
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:**
- Function introduced in `4a35339958f16` (May 2019, "RDMA/umem: Add API
to find best driver supported page size in an MR")
- Buggy `GENMASK(bits_per((umem->length - 1 + virt) ^ virt))` logic from
`a40c20dabdf90` (Sep 2020)
- `unsigned long virt` signature from original introduction
`4a35339958f16`
- `umem->iova = va = virt` assignment from `186b169cf1e4b` (Jul 2023)
- **Bug present since at least v5.x era; fully present in this v6.18.44
tree**
### Step 3.2: Fixes: tag
**Record:** N/A — no Fixes: tag in this commit.
### Step 3.3: Related file history
**Record:**
- Recent related fix in this tree: `486055f5e09df` "RDMA/core: Fix best
page size finding when it can cross SG entries" (Feb 2025)
- Companion patch from same series already backported: `afd35fec92971`
"RDMA/umem: Fix truncation for block sizes >= 4G" (Jun 2026, upstream
`15fe76e23615`)
- **Standalone:** This patch does not require other unmerged commits;
patch 1 is independent (different file: `iter.c`)
### Step 3.4: Author context
**Record:** Jason Gunthorpe is RDMA subsystem maintainer; authored
multiple historical `ib_umem_find_best_pgsz()` fixes (`a40c20dabdf90`,
`3361c29e9279e`, `10c75ccb54e4f`, etc.)
### Step 3.5: Dependencies
**Record:** No dependencies. API change `unsigned long` → `u64` requires
no caller modifications (all callers already pass `u64` values).
`check_add_overflow` and `bits_per` already exist in this tree.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:** UNVERIFIED — `b4 dig` requires a commit hash (patch not yet
committed in this checkout's `master`/`linux-next`). Link fetch to
patch.msgid.link blocked (bot protection). Lore.kernel.org returned 403.
### Step 4.2: Reviewers
**Record:** UNVERIFIED — could not retrieve thread via b4 or web fetch.
### Step 4.3: Bug reports
**Record:** N/A — no Reported-by: or syzbot links. Issue identified by
maintainer code review as part of `ib_umem_types` series.
### Step 4.4: Series context
**Record:** Part 2 of `ib_umem_types_jgg@nvidia.com` series. Part 1
(`iter.c` dma_addr_t fix) already backported to **this** tree
(`afd35fec92971`) with explicit `Cc: stable@vger.kernel.org`. Strong
indicator maintainers consider the series stable-worthy.
### Step 4.5: Stable list history
**Record:** UNVERIFIED — could not search lore stable archive (403). In-
tree evidence: patch 1 of same series already in 6.18.y.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `ib_umem_find_best_pgsz()` (modified);
`ib_umem_find_best_pgoff()` (calls it indirectly via header inline)
### Step 5.2: Callers
**Record:** Called from multiple RDMA driver MR registration paths, all
passing `u64` IOVAs:
- `mlx5_ib.h`: `mlx5_umem_mkc_find_best_pgsz()` → `iova` (u64)
- `irdma/verbs.c`: `virt` (u64)
- `bnxt_re/ib_verbs.c`: `virt_addr` (u64)
- `mana/main.c`: `virt` (u64)
- `hns_roce_mr.c`: `buf_attr->iova` (u64)
- `erdma/erdma_verbs.c`: `virt` (u64)
- `efa/efa_verbs.c`: `virt_addr` (u64)
- `mlx4_ib.h`: `start` (u64)
- `ionic/ionic_controlpath.c`: MR paths
### Step 5.3: Callees
**Record:** `check_add_overflow()`, `bits_per()`, `GENMASK()`,
`for_each_sgtable_dma_sg()`, `rounddown_pow_of_two()`, scatterlist DMA
address inspection
### Step 5.4: Reachability
**Record:** Userspace → RDMA uverbs MR registration (`ib_umem_get` →
driver `reg_user_mr` → `ib_umem_find_best_pgsz`) — **userspace-
reachable** on systems with `CONFIG_INFINIBAND_USER_MEM` and RDMA
hardware
### Step 5.5: Similar patterns
**Record:** Same series patch 1 (`afd35fec92971`) fixed analogous 32-bit
truncation in `__rdma_block_iter_next()` — same root cause class (wrong
integer width for DMA/IOVA addresses)
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE
### Step 6.1: Buggy code exists?
**Record:** **YES** — confirmed in this tree at
`drivers/infiniband/core/umem.c:79-108`:
```79:108:drivers/infiniband/core/umem.c
unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
unsigned long pgsz_bitmap,
unsigned long virt)
{
// ...
umem->iova = va = virt;
// ...
mask = pgsz_bitmap &
GENMASK(BITS_PER_LONG - 1,
bits_per((umem->length - 1 + virt) ^ virt));
```
`umem->iova` is `u64` in `include/rdma/ib_umem.h:22`.
### Step 6.2: Backport complications
**Record:** **Clean apply expected** — localized change, no structural
refactoring since recent `486055f5e09df` fix in this tree
### Step 6.3: Related fixes already present?
**Record:** Patch 1 of series (`afd35fec92971`) present; **this specific
fix NOT present**. No duplicate fix found.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Subsystem criticality
**Record:** RDMA core (`drivers/infiniband/core/`) — **IMPORTANT**.
Shared helper used by mlx5, irdma, bnxt_re, hns, efa, mana, ionic,
erdma, mlx4.
### Step 7.2: Subsystem activity
**Record:** Actively maintained — multiple umem fixes in 6.18.y history
(`486055f5e09df`, `afd35fec92971`, dmabuf/pinned umem work)
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** RDMA users registering memory regions — HPC, cloud, storage
(NVMe-oF), AI clusters. Config-specific: `CONFIG_INFINIBAND` +
`CONFIG_INFINIBAND_USER_MEM` + hardware driver.
### Step 8.2: Trigger conditions
**Record:**
- IOVA with high bits set (32-bit systems, or any system using full
64-bit IOVA space)
- Large MR lengths (especially > 4G)
- Crafted `length`/`iova` combinations causing arithmetic overflow
- **Unprivileged users** can trigger via RDMA uverbs MR registration
### Step 8.3: Failure mode severity
**Record:**
- Wrong page size → incorrect MR mapping → **data corruption**
(HIGH/CRITICAL for RDMA workloads)
- `GENMASK` UB → potential **kernel crash** (HIGH)
- Overflow path after fix → clean `return 0` → MR registration fails
(safe)
- **Severity: HIGH** (data integrity + potential crash)
### Step 8.4: Risk-benefit
**Record:**
- **Benefit: HIGH** — fixes real correctness bug in shared core helper
on userspace-reachable path; companion patch already deemed stable-
worthy
- **Risk: LOW** — ~20 lines, maintainer-authored, no caller changes,
fail-safe error paths
- **Ratio: Strongly favors backport**
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real bug: IOVA truncation, unchecked overflow, GENMASK UB
- Userspace-reachable via MR registration
- Data corruption and potential kernel crash
- Small, surgical fix from RDMA maintainer
- Buggy code confirmed in v6.18.44
- Companion patch from same series already backported to this tree with
Cc: stable
- All callers already pass `u64` — API widening is safe
**AGAINST backport:**
- No syzbot/user crash report attached (maintainer-found during type
cleanup)
- Primarily emphasized for 32-bit; 64-bit impact requires large MRs
(less common but real)
- Mailing list review not independently verified
**UNRESOLVED:**
- Full lore review thread inaccessible
- No explicit Tested-by: in commit message
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — logic is straightforward;
maintainer fix; series part 1 already in stable
2. Fixes real bug affecting users? **PASS** — wrong MR page size /
potential UB on MR registration
3. Important issue? **PASS** — data corruption + potential crash (HIGH
severity)
4. Small and contained? **PASS** — 2 files, ~20 lines
5. No new features/APIs? **PASS** — parameter type widening only;
behavior change is bug fix
6. Can apply to local tree? **PASS** — buggy code present; clean apply
expected
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build, or docs) — standard
bug fix.
### Step 9.4: Decision rationale
This commit fixes genuine boundary-condition bugs in a core RDMA helper
that every major driver uses during memory registration. The bugs can
cause incorrect page-size selection (data corruption risk) or undefined
behavior in `GENMASK()`. The fix is small, from the subsystem
maintainer, and follows the same `ib_umem_types` series whose first
patch is already in this 6.18.y tree as a stable backport. The buggy
code is present in v6.18.44 and the fix applies cleanly.
---
## Verification
- [Phase 1] Parsed subject, Link tag, Jason Gunthorpe SOB; no
Fixes/Reported-by
- [Phase 2] Read diff: `u64 virt`, `check_add_overflow`, guarded
`GENMASK`; 2 files, ~20 lines
- [Phase 2] Read current `umem.c:79-147` and `ib_umem.h:22,86-88` —
buggy code confirmed
- [Phase 3] `git blame -L 79,108 drivers/infiniband/core/umem.c`:
introduced `4a35339958f16` (2019), GENMASK logic `a40c20dabdf90`
(2020)
- [Phase 3] `git log --oneline -20 -- drivers/infiniband/core/umem.c`:
recent related fixes including `486055f5e09df`, `afd35fec92971`
- [Phase 3] `git show afd35fec92971`: companion patch from same series,
Cc: stable, already in tree
- [Phase 3] `git merge-base --is-ancestor afd35fec92971 HEAD`: confirmed
in tree
- [Phase 4] `b4 dig --help`: requires `-c COMMITISH`; no commit hash
available for this unmerged patch
- [Phase 4] WebFetch patch.msgid.link: blocked by bot protection
- [Phase 4] curl lore.kernel.org: 403 Forbidden
- [Phase 5] `grep ib_umem_find_best_pgsz`: 10+ driver call sites, all
pass u64 IOVA values
- [Phase 5] Verified caller types: mlx5 `iova` u64, irdma `virt` u64,
bnxt `virt_addr` u64, hns `buf_attr->iova` u64
- [Phase 5] Read `include/linux/bits.h:46-51`: GENMASK runtime UB when
`l > h`
- [Phase 5] Read `include/linux/overflow.h:67`: `check_add_overflow`
available
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] `git show linus-next/master:.../umem.c`: fix NOT yet in
those branches in this checkout (patch still pending upstream)
- [Phase 6] Buggy `unsigned long virt` confirmed; no `u64 virt` in tree
- [Phase 8] Assessed failure modes from code path analysis: wrong page
size → corruption; GENMASK UB → crash
- UNVERIFIED: Lore mailing list reviewer feedback and explicit stable
nomination for patch 2 specifically
**YES**The analysis is complete for **v6.18.44**
(`stable/linux-6.18.y`).
**Verdict: YES** — backport this commit.
It fixes real boundary bugs in `ib_umem_find_best_pgsz()`: IOVA
truncation (`u64` stored via `unsigned long`), unchecked `length + iova`
overflow, and possible `GENMASK()` UB for large mappings. The buggy code
is present in this tree; the fix is small, from RDMA maintainer Jason
Gunthorpe, and part of the same `ib_umem_types` series whose first patch
(`afd35fec92971`, iter.c truncation fix) is already backported here with
`Cc: stable`.
**Impact:** Userspace-reachable via RDMA MR registration — wrong page
sizes can corrupt data; `GENMASK` UB can crash the kernel.
drivers/infiniband/core/umem.c | 18 ++++++++++++------
include/rdma/ib_umem.h | 4 ++--
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index fd3a774904f8d..468d662c42c47 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -78,14 +78,17 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
*/
unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
unsigned long pgsz_bitmap,
- unsigned long virt)
+ u64 virt)
{
unsigned long curr_len = 0;
dma_addr_t curr_base = ~0;
- unsigned long va, pgoff;
+ unsigned long pgoff;
struct scatterlist *sg;
- dma_addr_t mask;
+ unsigned long mask = 0;
+ unsigned int bits;
dma_addr_t end;
+ u64 last_va;
+ u64 va;
int i;
umem->iova = va = virt;
@@ -103,9 +106,12 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
* number of required pages. Compute the largest page size that could
* work based on VA address bits that don't change.
*/
- mask = pgsz_bitmap &
- GENMASK(BITS_PER_LONG - 1,
- bits_per((umem->length - 1 + virt) ^ virt));
+ if (check_add_overflow(umem->length - 1, virt, &last_va))
+ return 0;
+ bits = bits_per(virt ^ last_va);
+ if (bits < BITS_PER_LONG)
+ mask = pgsz_bitmap & GENMASK(BITS_PER_LONG - 1, bits);
+
/* offset into first SGL */
pgoff = umem->address & ~PAGE_MASK;
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 90b1ea19a90a0..0cda3e6425d2e 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -85,7 +85,7 @@ int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length);
unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
unsigned long pgsz_bitmap,
- unsigned long virt);
+ u64 virt);
/**
* ib_umem_find_best_pgoff - Find best HW page size
@@ -178,7 +178,7 @@ static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offs
}
static inline unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
unsigned long pgsz_bitmap,
- unsigned long virt)
+ u64 virt)
{
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread