Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
@ 2026-10-19 13:44 ` Sasha Levin
  2026-10-19 14:00   ` sashiko-bot
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context Sasha Levin
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:44 UTC (permalink / raw)
  To: patches, stable
  Cc: Seyeong Kim, Leon Romanovsky, Sasha Levin, tatyana.e.nikolova,
	linux-rdma, linux-kernel

From: Seyeong Kim <seyeong.kim@canonical.com>

[ Upstream commit 4dc9c884c0aafac1e8d37536d88d485135e26883 ]

The irdma driver currently issues an unconditional PF reset whenever the
HMC Error interrupt (PFINT_OICR bit 26) fires:

	if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) {
		ibdev_err(&iwdev->ibdev, "HMC Error\n");
		iwdev->rf->reset = true;
	}

request_reset() issues an IIDC_PFR to ice. In practice a single HMC_ERR
can trigger cascading PF resets, IOMMU faults during teardown, and
teardown of every RDMA connection on the device.

i40e handles the identically-named interrupt by reading
PFHMC_ERRORINFO and PFHMC_ERRORDATA and logging them without touching
device state; see commit 9c010ee0ea5f ("i40e: Suppress HMC error to
Interrupt message level") which removed the reset as "not necessary".
This patch mirrors that handling on irdma.

With this change, repeated HMC_ERR no longer produces a reset storm and
RDMA traffic on the device continues uninterrupted.

Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com>
Link: https://patch.msgid.link/20260619050044.1807044-1-seyeong.kim@canonical.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
irdma GEN2 HMC-error path exists here, and this change is a real
production fix for Intel E810 PF-reset storms. Analysis below is for
this tree only.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[RDMA/irdma] [Suppress] [stop issuing a PF reset when the HMC
Error interrupt fires]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected for this review)
- **Reported-by:** none in the commit message
- **Tested-by:** none tagged (author did describe hardware testing in
  the RFC/v2 cover)
- **Reviewed-by / Acked-by:** none
- **Link:** `https://patch.msgid.link/20260619050044.1807044-1-
  seyeong.kim@canonical.com`
- **Cc: stable:** none (expected)
- **Signed-off-by:** Seyeong Kim (author); Leon Romanovsky (RDMA
  maintainer). The pipeline’s “Sasha Levin” SOB is ignored.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `icrdma_iidc_event_handler()` sets `iwdev->rf->reset = true`
  on `IRDMAPFINT_OICR_HMC_ERR_M` (PFINT_OICR bit 26). That calls
  `request_reset()` → `ice_rdma_request_reset(..., IIDC_FUNC_RESET)` →
  `ICE_RESET_PFR`.
- **Symptom:** cascading PF resets, IOMMU/DMAR faults during teardown,
  every RDMA connection on the device torn down. On newer NVM a single
  forced HMC_ERR still caused a full PF reset and aborted RDMA traffic.
- **Root cause (author):** HMC_ERR was treated as fatal; i40e stopped
  resetting on the same interrupt in 9c010ee0ea5f (“reset that was not
  necessary”).
- **Version info:** author tested Ubuntu 6.8 (NVM 3.10, cascading resets
  + DMAR) and mainline 7.1-rc4 (NVM 4.51, single reset). Driver path has
  existed since irdma GEN2 was added.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** This is an explicit error-handling fix: stop a
destructive reset. Diagnostic MMIO reads are extra, not a cleanup
disguised as a fix.

===============================================================
PHASE 2: DIFF ANALYSIS
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- `drivers/infiniband/hw/irdma/icrdma_if.c`: HMC_ERR branch (stop reset;
  log errinfo/errdata)
- `drivers/infiniband/hw/irdma/irdma.h`: `IRDMA_PFHMC_ERRORINFO`,
  `IRDMA_PFHMC_ERRORDATA` before `IRDMA_MAX_REGS`
- `drivers/infiniband/hw/irdma/icrdma_hw.h` / `icrdma_hw.c`: GEN2
  offsets `0x00520400` / `0x00520500`
- `drivers/infiniband/hw/irdma/i40iw_hw.c`: matching `0xffffffff`
  placeholders so GEN1 array length still matches the enum
**+15 / −3**, five files. **Surgical, single-subsystem.** Function:
`icrdma_iidc_event_handler`.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: **Before:** HMC_ERR → `ibdev_err("HMC Error")` → `rf->reset =
true` → `request_reset()`. **After:** HMC_ERR → `readl`
ERRORINFO/ERRORDATA → `ibdev_warn` → **do not set reset**. PE_CRITERR
(except Q1 resource check) and PE_PUSH still reset.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-error handling (over-aggressive recovery).**
Unconditional PF reset on a non-fatal (or at least non-reset-worthy)
interrupt causes reset storms, aux unplug, IOMMU faults, and full RDMA
teardown. Fix: log-only, matching i40e. ice itself already only
*forwards* HMC_ERR to the aux driver and does not reset on that bit.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Core change (clear `rf->reset = true`) is obviously correct
relative to i40e/ice. Diagnostic register plumbing is extra; offsets
were **inferred** from `PFHMC_PDINV` (+0x100/+0x200), same spacing as
i40e’s PDINV/ERRORINFO/ERRORDATA. Forced-interrupt tests read back 0, so
offsets are unverified against a datasheet, but they are **read-only**
and not the recovery change. GEN1/GEN2 arrays were updated together;
GEN3/GEN4 use `ig3rdma_init_hw()` and do not index `IRDMA_MAX_REGS`.
**Regression risk:** leaving a true HMC failure running without reset —
possible, but i40e has done this since 2014, ice does not reset on
HMC_ERR, and PE_CRITERR/PE_PUSH still reset. **Low risk** for the reset-
suppression itself.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: Unconditional HMC reset came from **8498a30e1b948**
(“RDMA/irdma: Register auxiliary driver…”, 2021-06-02), moved into
`icrdma_if.c` by **0c2b80cac96e1** (2025 refactor). Present since irdma
GEN2 (~5.14-era), not new 7.3 code.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No Fixes: tag.** Related precedent **9c010ee0ea5f** (i40e,
2014) is in this tree (`git merge-base --is-ancestor` succeeded). i40e
still logs HMC error info and does not reset.

**Step 3.3: CHECK FILE HISTORY**
Record: Recent irdma work is GEN3/GEN4 and udata hardening. This patch
is **standalone**, not “X/Y”. Later commits do not revert or replace
this HMC handling.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Seyeong Kim (Canonical) — one irdma commit here. Intel irdma
maintainer is Tatyana Nikolova (CC’d). Applied by Leon Romanovsky.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Needs `icrdma_if.c`, `IRDMA_GLINT_RATE` in the enum (so new
entries stay last), and ice `IIDC_RDMA_EVENT_CRIT_ERR`. All present in
this 7.3 tree. **Applies standalone** here.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 4dc9c884c0aaf`: RFC + v2. Applied version is **v2**
  (`20260619050044.1807044-1`).
- RFC: https://patch.msgid.link/20260416071541.3899471-1-
  seyeong.kim@canonical.com
- v2: https://patch.msgid.link/20260619050044.1807044-1-
  seyeong.kim@canonical.com
- RFC notes: offsets inferred; “every HMC_ERR is safe to continue” not
  datasheet-confirmed; repro via `/dev/mem` write to PFINT_OICR, not
  firmware HMC.
- May 22 follow-up: retested on **7.1-rc4**; patch applied unchanged.
- **No NAK** in the saved thread. lore.kernel.org HTML fetch returned
  403; thread recovered via `b4 dig -m`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): linux-rdma, Krzysztof Czurylo, Tatyana Nikolova,
Jason Gunthorpe, Leon Romanovsky. **No Reviewed-by** in the mbox (RFC,
author ping, then maintainer apply). Right maintainers were CC’d.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: Real-world HMC_ERR → “Requesting a reset” is widely reported:
- GitHub intel/ethernet-linux-ice#12: recurring OICR `0x06000803` / HMC
  Error / PF reset on multiple machines; workaround unload/blacklist
  irdma.
- Proxmox forum: E810 HMC Error → Corosync loss / node reboots.
- Alpine even blacklists `irdma` by default over this class of issue.
Author also cites a **customer report on NVM 3.10** (cascading PFR +
DMAR).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Single patch (RFC → v2). Not a multi-patch series.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search **403**. No evidence this commit
was NAK’d for stable. Unrelated 6.6 irdma reset patch
(`irdma_modify_qp_to_err`) is a different bug.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: KEY FUNCTIONS**
Record: `icrdma_iidc_event_handler` (behavior). Arrays/enum:
`icrdma_regs`, `i40iw_regs`, `enum irdma_registers`. Init:
`icrdma_init_hw` / `i40iw_init_hw` walk `IRDMA_MAX_REGS`.

**Step 5.2: TRACE CALLERS**
Record: Registered as `.event_handler` on the GEN2 auxiliary driver. ice
misc IRQ sets `ICE_AUX_ERR_PENDING` for `PFINT_OICR_HMC_ERR_M`; service
task sends `IIDC_RDMA_EVENT_CRIT_ERR` with the OICR value.
**Hardware/interrupt-driven**, not a syscall. Hits any system with ice +
irdma loaded (E810 and similar), including hosts that are not running
RDMA traffic.

**Step 5.3: TRACE CALLEES**
Record: After the patch, `readl` of two HMC diagnostic regs. Before,
`icrdma_request_reset` → `ice_rdma_request_reset` →
`ice_schedule_reset(ICE_RESET_PFR)` — full function reset, unplug aux,
drop the NIC datapath.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: ice OICR → service task → aux event → irdma handler → (old) PF
reset. Userspace cannot set OICR, but **firmware/hardware HMC_ERR is
common** on E810. Forced-bit tests still prove the handler’s reset is
what destroys connections.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same interrupt: i40e logs and does not reset; ice does not
reset, only notifies aux. irdma PE_CRITERR already special-cases Q1
resource errors as non-fatal. This HMC change is the same pattern.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `icrdma_iidc_event_handler` in
`drivers/infiniband/hw/irdma/icrdma_if.c`. Pre-fix parent still had
`rf->reset = true` on HMC_ERR. Bug introduced **2021** (8498a30e1b948),
long before 7.3. Current HEAD already contains **4dc9c884c0aaf** (that
is the mainline merge of this fix, not a reason to reject it on merit).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply on this tree.** Context matches. GEN1 placeholders
keep `IRDMA_MAX_REGS` arrays aligned. Would need more care on much older
stables if `IRDMA_GLINT_RATE` or `icrdma_if.c` were missing; **not an
issue here**.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This *is* the HMC-reset suppression. No alternate fix. i40e’s
older analogous change is present.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **RDMA/irdma (Intel E810 / ice GEN2).** **IMPORTANT** — not core
mm/VFS, but E810 is common in servers/clusters. A PF reset takes down
**Ethernet as well as RDMA**.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Actively developed (GEN3/GEN4, udata). This handler itself has
been stable since the 2021 introduction / 2025 file move.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: WHO IS AFFECTED**
Record: **Driver-specific** — ice + irdma (Intel E810 and related).
Includes clusters that load irdma by default even when they do not use
RDMA (Proxmox/ice GitHub reports).

**Step 8.2: TRIGGER CONDITIONS**
Record: Hardware HMC_ERR (OICR bit 26). Seen in the field without a
special RDMA workload. Not a userspace-triggered security bug. **Common
enough** that distros document blacklisting irdma.

**Step 8.3: FAILURE MODE SEVERITY**
Record: PF reset → link down, RDMA teardown, IOMMU faults, uverbs WARN
during aux unplug, cluster partition / reboot in reports. **Severity:
HIGH (hang/datapath loss); CRITICAL in HA/cluster setups.**

**Step 8.4: RISK-BENEFIT RATIO**
Record: **Benefit: high** (stops reset storms on a widely deployed NIC).
**Risk: low** for dropping the reset; **very low** extra risk from read-
only diagnostic MMIO (wrong offset would log junk or, at worst, a bad
read — tests did not blow up). Ratio favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, user-visible bug: PF reset storm, IOMMU faults, full
  RDMA/Ethernet disruption on E810.
- Field reports (customer, Proxmox, ice GitHub); Canonical engineer with
  before/after on 6.8 and 7.1-rc4.
- Small (+15/-3), contained in irdma.
- Matches i40e (2014, Intel: reset “not necessary”) and ice (forwards
  HMC_ERR, does not reset).
- Fatal PE_CRITERR / PE_PUSH paths unchanged.
- RDMA maintainer applied it; Intel irdma maintainers were CC’d.
- Code and prerequisites exist in this 7.3 tree.

AGAINST:
- Diagnostic register offsets inferred, not datasheet-confirmed (reads
  were 0 on a *forced* interrupt).
- Author RFC: not proven every firmware HMC_ERR is safe to run through.
- Repro used `/dev/mem` OICR injection, not a firmware HMC event
  (customer logs still show the same handler path).
- No Fixes/Cc stable, no Reviewed-by (absence is not a no-vote per the
  rules).

UNRESOLVED:
- Full public review text beyond the RFC mbox (lore HTML 403).
- Whether stable@ discussed this specific patch (stable search 403).
- Exact meaning of HMC_ERR on E810 silicon.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — drop destructive reset;
   tested on E810; i40e/ice precedent.
2. Fixes a real bug that affects users? **PASS** — production reset
   storms.
3. Important (crash/security/corruption/deadlock)? **PASS** — PF reset /
   datapath loss / IOMMU faults / cluster impact. HIGH.
4. Small and contained? **PASS** — 15 insertions, one handler.
5. No new features or APIs? **PASS** — error-path policy + diagnostic
   reads.
6. Can apply to the local tree? **PASS** — matching irdma GEN2 code in
   7.3.0-rc4.

**Step 9.3: EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. It is a
**hardware error-handling workaround** in an existing driver (same class
as USB/PCI quirks: stop a harmful default for real devices).

**Step 9.4: DECISION**
This tree has the irdma GEN2 HMC path. Suppressing PF reset on HMC_ERR
is a small, tested fix for a serious, widely seen E810 failure mode.
Diagnostic MMIO is best-effort; the stable-worthy part is not resetting.
Benefit clearly outweighs risk.

Verification:
- [Phase 1] Tags: Link to msgid 20260619050044; SOB Seyeong Kim + Leon
  Romanovsky; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: 5 files, +15/-3; HMC_ERR no longer sets `rf->reset`;
  GEN2 regs + GEN1 0xffffffff pads
- [Phase 2] Confirmed `ice_rdma_request_reset(IIDC_FUNC_RESET)` →
  `ICE_RESET_PFR`
- [Phase 3] Blame: reset from 8498a30e1b948 (2021); moved in
  0c2b80cac96e1
- [Phase 3] `git merge-base --is-ancestor 9c010ee0ea5f HEAD` = YES; i40e
  still log-only
- [Phase 3] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` = 7.3.0-rc4
- [Phase 3] `git merge-base --is-ancestor 4dc9c884c0aaf HEAD` = YES
  (mainline landing of this fix)
- [Phase 4] `b4 dig -c 4dc9c884c0aaf`: RFC then v2; v2 applied; `-w`
  CC’d Intel irdma + RDMA maintainers
- [Phase 4] `b4 dig -m`: RFC caveats + 7.1-rc4 retest; no NAK in mbox
- [Phase 4] External: ice GitHub #12 and Proxmox E810 HMC reset reports
- [Phase 4] lore.kernel.org WebFetch 403; stable@ search 403 — listed
  UNVERIFIED
- [Phase 5] Handler is ice aux `.event_handler`; GEN3/4 use a different
  event path (no HMC reset there)
- [Phase 6] Pre-fix HMC_ERR block present at 4dc9c884c0aaf^; arrays
  aligned with enum
- [Phase 8] Failure mode: PF reset / RDMA+Ethernet teardown / IOMMU
  faults, severity HIGH
- UNVERIFIED: datasheet-correctness of 0x00520400/0x00520500; public
  Intel Acked-by beyond CC

The patch is small, matches long-standing i40e/ice behavior, and
prevents a real E810 reset storm that takes down RDMA and the PF.

**YES**

 drivers/infiniband/hw/irdma/i40iw_hw.c  | 4 +++-
 drivers/infiniband/hw/irdma/icrdma_hw.c | 2 ++
 drivers/infiniband/hw/irdma/icrdma_hw.h | 2 ++
 drivers/infiniband/hw/irdma/icrdma_if.c | 8 ++++++--
 drivers/infiniband/hw/irdma/irdma.h     | 2 ++
 5 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/irdma/i40iw_hw.c b/drivers/infiniband/hw/irdma/i40iw_hw.c
index 60c1f2b1811de..8301938b45432 100644
--- a/drivers/infiniband/hw/irdma/i40iw_hw.c
+++ b/drivers/infiniband/hw/irdma/i40iw_hw.c
@@ -29,7 +29,9 @@ static u32 i40iw_regs[IRDMA_MAX_REGS] = {
 	I40E_PFHMC_PDINV,
 	I40E_GLHMC_VFPDINV(0),
 	I40E_GLPE_CRITERR,
-	0xffffffff      /* PFINT_RATEN not used in FPK */
+	0xffffffff,     /* PFINT_RATEN not used in FPK */
+	0xffffffff,     /* PFHMC_ERRORINFO not used in FPK */
+	0xffffffff      /* PFHMC_ERRORDATA not used in FPK */
 };
 
 static u32 i40iw_stat_offsets[] = {
diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.c b/drivers/infiniband/hw/irdma/icrdma_hw.c
index 32f26284a788b..b1f1b54857626 100644
--- a/drivers/infiniband/hw/irdma/icrdma_hw.c
+++ b/drivers/infiniband/hw/irdma/icrdma_hw.c
@@ -29,6 +29,8 @@ static u32 icrdma_regs[IRDMA_MAX_REGS] = {
 	GLHMC_VFPDINV(0),
 	GLPE_CRITERR,
 	GLINT_RATE(0),
+	PFHMC_ERRORINFO,
+	PFHMC_ERRORDATA,
 };
 
 static u64 icrdma_masks[IRDMA_MAX_MASKS] = {
diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.h b/drivers/infiniband/hw/irdma/icrdma_hw.h
index d97944ab45dac..0acdeda1236d1 100644
--- a/drivers/infiniband/hw/irdma/icrdma_hw.h
+++ b/drivers/infiniband/hw/irdma/icrdma_hw.h
@@ -40,6 +40,8 @@
 #define GLHMC_VFPDINV(_i)	(0x00528300 + ((_i) * 4)) /* _i=0...31 */
 #define GLPE_CRITERR		0x00534000
 #define GLINT_RATE(_INT)	(0x0015A000 + ((_INT) * 4)) /* _i=0...2047 */ /* Reset Source: CORER */
+#define PFHMC_ERRORINFO		0x00520400
+#define PFHMC_ERRORDATA		0x00520500
 
 #define ICRDMA_DB_ADDR_OFFSET		(8 * 1024 * 1024 - 64 * 1024)
 
diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c b/drivers/infiniband/hw/irdma/icrdma_if.c
index b49fd9cf24765..6c1d285d1c176 100644
--- a/drivers/infiniband/hw/irdma/icrdma_if.c
+++ b/drivers/infiniband/hw/irdma/icrdma_if.c
@@ -91,8 +91,12 @@ static void icrdma_iidc_event_handler(struct iidc_rdma_core_dev_info *cdev_info,
 			}
 		}
 		if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) {
-			ibdev_err(&iwdev->ibdev, "HMC Error\n");
-			iwdev->rf->reset = true;
+			u32 hmc_errinfo = readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORINFO]);
+			u32 hmc_errdata = readl(iwdev->rf->sc_dev.hw_regs[IRDMA_PFHMC_ERRORDATA]);
+
+			/* Log diagnostics; do not reset here. */
+			ibdev_warn(&iwdev->ibdev, "HMC Error: errinfo=0x%08x errdata=0x%08x\n",
+				   hmc_errinfo, hmc_errdata);
 		}
 		if (event->reg & IRDMAPFINT_OICR_PE_PUSH_M) {
 			ibdev_err(&iwdev->ibdev, "PE Push Error\n");
diff --git a/drivers/infiniband/hw/irdma/irdma.h b/drivers/infiniband/hw/irdma/irdma.h
index ff938a01d70c4..e8cda27d78543 100644
--- a/drivers/infiniband/hw/irdma/irdma.h
+++ b/drivers/infiniband/hw/irdma/irdma.h
@@ -66,6 +66,8 @@ enum irdma_registers {
 	IRDMA_GLHMC_VFPDINV,
 	IRDMA_GLPE_CRITERR,
 	IRDMA_GLINT_RATE,
+	IRDMA_PFHMC_ERRORINFO,
+	IRDMA_PFHMC_ERRORDATA,
 	IRDMA_MAX_REGS, /* Must be last entry */
 };
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error Sasha Levin
@ 2026-10-19 13:44 ` Sasha Levin
  2026-10-19 14:07   ` sashiko-bot
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock() Sasha Levin
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:44 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 d100966325f782aa7775e5f0e8fb04f66f56308e ]

rds_rdma_free_op() and rds_atomic_free_op() are reached from the IB
send completion path via

  rds_ib_tasklet_fn_send()
    rds_ib_send_cqe_handler()
      rds_message_put()
        rds_message_purge()
          rds_rdma_free_op() / rds_atomic_free_op()

which runs in tasklet (softirq) context.  Both functions unpin the
user pages of the op with unpin_user_pages_dirty_lock(), which uses
set_page_dirty_lock() and thus may take the folio lock and sleep.
Sleeping in softirq context is not allowed and can deadlock or crash.

Dirtying the pages with the non-sleeping set_page_dirty() instead
would just trade one bug for another, as pointed out during review:
the pinned range can be file-backed.  rds_pin_pages() pins with
FOLL_LONGTERM, which refuses fs-dax but takes the page-cache pages
of a MAP_SHARED file mapping just fine, and RDS does not restrict
what memory the caller registers as an RDMA destination.

For a file-backed page, set_page_dirty() from a tasklet can take
non-irq-safe filesystem locks (e.g. mapping->i_private_lock and
inode->i_lock in block_dirty_folio()) and deadlock against the task
it interrupted.  Without the folio lock, it races with truncation
clearing folio->mapping, which is the race set_page_dirty_lock()
exists to close.  The pre-pin_user_pages() version of this code
dirtied pages that way from the tasklet, so that bug is older than
the sleeping unpin.

The page dirtying therefore has to move to process context, not
merely avoid the folio lock.  When the final rds_message_put() runs
in atomic context, rds_rdma_free_op() and rds_atomic_free_op() now
leave the op's pages pinned and flag the op. Later, rds_message_put()
hands the message to a work item that unpins the flagged ops' pages
and frees the message from process context. Here,
unpin_user_pages_dirty_lock() is safe outside the atomic context.
Everything else keeps running in the caller's context exactly as
before: the rest of the purge - the zerocopy completion, the socket
put and the MR reference drops - as well as RDMA writes, whose pages
the remote side only reads and which unpin without dirtying,
everything on rds_tcp, and final puts that already happen in process
context (socket close, connection teardown).

Deferring only the unpin means the work item touches nothing but the
pinned pages and the rds module's own memory: it cannot call back
into a transport module, so it changes nothing about the transports'
shutdown and unload ordering.  rds_exit() drains any pending unpin
work via destroy_workqueue(rds_wq) before the module goes away.

The Oracle UEK kernel avoids the sleeping unpin by calling
set_page_dirty() directly from the tasklet, which is subject to the
file-backed page problem above, so this deliberately does not follow
UEK here.

Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260730041629.3512480-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:

This is a real sleep-in-softirq bug on the RDS IB completion path, and
the buggy code is present in this 5.10.270 tree. The fix is self-
contained and should be backported.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [net/rds] [don't use] don't call `unpin_user_pages_dirty_lock()`
from atomic/softirq context. "don't use" is a prevent/avoid-style fix.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Signed-off-by: Allison Henderson `<achender@kernel.org>` (author;
  ignore pipeline SOB)
- Signed-off-by: Jakub Kicinski `<kuba@kernel.org>` (netdev maintainer)
- Link: `https://patch.msgid.link/20260730041629.3512480-2-
  achender@kernel.org`
- No Reported-by, Tested-by, Reviewed-by, Acked-by, or Cc: stable in the
  provided message
- Mailing-list v4 **did** include `Fixes: 0d4597c8c5ab ("net/rds: Track
  user mapped pages through special API")`; that tag is in this tree
  (verified with `git merge-base --is-ancestor`)
- Message-ID `-2` is patch 1/4 of `[PATCH net v4 0/4] net/rds: Bug fix
  ports` (cover letter is `-1`)
- Assisted-by Claude appears on the lore submission only

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: `rds_rdma_free_op()` / `rds_atomic_free_op()` run from the IB
  send tasklet and call `unpin_user_pages_dirty_lock()`, which uses
  `set_page_dirty_lock()` → `lock_page()`, which may sleep.
- Symptom: sleep in softirq → deadlock or crash.
- Switching to `set_page_dirty()` from the tasklet is also wrong for
  file-backed pins (`FOLL_LONGTERM` MAP_SHARED): non-irq-safe fs locks
  and truncation races.
- Fix: if the final put is atomic and pages need dirtying, leave them
  pinned, set `op_unpin_deferred`, and finish unpin+free on `rds_wq`.
- Author notes this is older than the pin API (pre-pin code already
  dirtied from the tasklet) and that UEK’s `set_page_dirty()`-from-
  tasklet approach is intentionally not followed.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not hidden. Explicit sleep-in-atomic / deadlock fix.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- `net/rds/message.c`: add `rds_message_unpin_worker()`, defer `kfree`
  from `rds_message_put()` when unpin was deferred
- `net/rds/rdma.c`: split unpin helpers; `rds_rdma_free_op()` /
  `rds_atomic_free_op()` unpin inline only when safe (`in_task()` or
  RDMA write)
- `net/rds/rds.h`: `m_unpin_work`, `op_unpin_deferred` bitfields, helper
  prototypes
- Scope: ~74 insertions / 11 deletions, three RDS files, surgical

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: final `rds_message_put()` always purges and unpins (possibly
  dirtying) in the caller’s context, including the send CQ tasklet.
- After: purge still runs in the caller (zerocopy, sock_put, MR krefs).
  Dirtying unpin is deferred to process context. RDMA writes still unpin
  immediately (no dirty). Process-context final puts still unpin
  immediately.
- Error path `rds_cmsg_rdma_args()` → `rds_rdma_free_op()` is
  sendmsg/process context, so `in_task()` is true and pages are not
  leaked.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: [Deadlock / sleep-in-atomic] `lock_page()` from tasklet/softirq.
Workqueue deferral is the correct class of fix; dirtying cannot stay in
the tasklet.

Step 2.4: ASSESS THE FIX QUALITY
Record: v4 is the review-hardened design (v1 used `set_page_dirty()` in
the tasklet; v2/v3 deferred the whole purge and needed extra IB-module
flushes). Risk is the usual workqueue lifetime issues; mitigated because
the worker only unpins pages and `kfree`s the message, and `rds_exit()`
→ `rds_threads_exit()` → `destroy_workqueue(rds_wq)` drains it. Messages
are `kzalloc`’d, so new flags/work_struct start zeroed.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Sleeping unpin: `0d4597c8c5abd` ("net/rds: Track user mapped pages
  through special API", Leon Romanovsky, 2020) — **in this tree**
- Call from tasklet: `rds_rdma_free_op` / `rds_message_put` date to
  2009–2010 (Andy Grover)
- Pre-pin code already dirtied from this path

Step 3.2: FOLLOW THE FIXES: TAG
Record: `0d4597c8c5ab` is an ancestor of HEAD (`git merge-base --is-
ancestor` exit 0). No later in-tree substitute for this unpin-from-
tasklet bug. `338a3ba30c5ef` ("net:rds: Fix possible deadlock in
rds_message_put") is a different lock-order bug in `recv.c`.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Recent `net/rds/` work here is unrelated (zerocopy, MR cleanup,
tcp corruption). This is standalone, not patch 2-of-N that needs earlier
series members.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Allison Henderson is a long-time RDS contributor; this tree
already has several of her RDS fixes. Author is the right subsystem
person.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Series mates (socket ref on MR, send_xmit leak, MR teardown
unpin) are independent bugs. Needed APIs exist here: `in_task()`,
`unpin_user_pages_dirty_lock()`, `rds_wq`, `pin_user_pages_fast()` +
`FOLL_LONGTERM`. No missing helpers.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 mbox` on msgid `20260730041629.3512480-2-achender@kernel.org`:
  8-message thread
- Lore/WebFetch of lore.kernel.org and patch.msgid.link returned 403;
  discussion recovered via b4 + openwall
- Revisions: v1 2026-07-11, v2 2026-07-25, v3 2026-07-26, v4 2026-07-29
  (applied)
- v1 NAK’d conceptually: `set_page_dirty()` from softirq can deadlock on
  fs locks and race truncation
- v3 extra `rds_ib_exit()` flushes dropped in v4 by deferring only unpin
- Applied to netdev/net-next as `d100966325f7` (not this tree)

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: To/Cc included netdev, linux-rdma, Kicinski, Abeni, Dumazet,
Horms. No subsystem Reviewed-by on v4. Kicinski: “I don't have much
confidence in my ability to review this, so let's queue this for -next.”
Author agreed they are old, non-simple bugs.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla in the thread. Motivation is code analysis +
UEK carrying a related (weaker) fix. Oracle RDS/IB users are the
affected population.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: 4-patch “Bug fix ports” series. This patch is 1/4 and does not
depend on 2–4. Patch 4 is a separate pin-vs-put_page leak in
`__rds_ib_teardown_mr()`.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: No useful hit on lore.kernel.org/stable for this subject (search
was noisy/unrelated). Originally aimed at `net` because of Fixes:; moved
to net-next. Absence of stable-list discussion is not a NAK.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `rds_message_unpin_worker` (new), `rds_message_put`,
`rds_rdma_op_unpin_pages` (new), `rds_rdma_free_op`,
`rds_atomic_op_unpin_page` (new), `rds_atomic_free_op`

Step 5.2: TRACE CALLERS
Record:
- `rds_message_put()`: send.c, ib_send.c, ib_cm.c, message.c, loop.c,
  connection.c
- Confirmed atomic path: `rds_ib_tasklet_fn_send()` → `poll_scq()` →
  `rds_ib_send_cqe_handler()` → `rds_message_put()` (`net/rds/ib_cm.c`,
  `ib_send.c`)
- `rds_rdma_free_op()`: `rds_message_purge()` and `rds_cmsg_rdma_args()`
  error path (process context)
- `rds_atomic_free_op()`: only `rds_message_purge()`

Step 5.3: TRACE CALLEES
Record: `unpin_user_pages_dirty_lock()` → `set_page_dirty_lock()` →
`lock_page()` (sleeping). Non-dirty path uses `unpin_user_pages()` only.
Worker uses `queue_work(rds_wq)` / `kfree`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Userspace `sendmsg` with `RDS_CMSG_RDMA_ARGS` / atomic cmsg → IB
RDMA READ or atomic WR → CQ completion in tasklet → final put. Reachable
from sockets if `CONFIG_RDS_RDMA`. Not a theoretical path.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Local `__rds_ib_teardown_mr()` still does `set_page_dirty()` +
`put_page()` (series patch 4). `rds_info.c` unpins from getsockopt
(process context) — OK. Same class of bug is already treated as
backport-worthy in this tree (`88fdf5948f538` Don't sleep inside
`rds_ib_conn_path_shutdown`).

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. This checkout is **5.10.270** (`pending-5.10`, `git
describe` `p-5.10-1-gce56b7a73b64b`).
- `net/rds/rdma.c:500` and `:517` call `unpin_user_pages_dirty_lock()`
- `rds_ib_tasklet_fn_send` still a tasklet
- `rds_pin_pages()` uses `FOLL_LONGTERM`
- Introduced by `0d4597c8c5ab` (v5.7-era), present on this branch

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Semantic apply is straightforward. `rdma.c` / `rds.h` match the
old side of the diff. `message.c` context after `rds_message_put()`
still assigns `hdr->h_exthdr[0]` instead of `memset` of the ext header —
**minor context conflict**, not a rework. `work_struct` / `queue_work` /
`in_task()` are available (`rds.h` → `sock.h` → `netdevice.h` →
`workqueue.h`; `hardirq.h` → `preempt.h`). `rds_wq` is destroyed on
module exit.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: No equivalent deferred-unpin fix. `338a3ba30c5ef` is a different
deadlock.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [net/rds] IMPORTANT for RDS-over-IB (Oracle RAC / HPC). Not core
networking; production users of 5.10 LTS do run this.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature. Core free/put path has been stable for years; this is a
long-standing latent bug, not churn on new code.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Config-specific / driver-specific: `CONFIG_RDS` +
`CONFIG_RDS_RDMA`, IB completions of RDMA READ / atomic ops against
pinned user memory (including MAP_SHARED file pages).

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Common on RDS RDMA READ completion. Timing-dependent on folio
already locked (writeback). Unprivileged user with an RDS socket and
registered memory can hit it. Not every boot.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: Sleep in softirq / `lock_page()` from tasklet → deadlock or
crash. **CRITICAL**. File-backed `set_page_dirty()` alternative would
also be CRITICAL (fs lock deadlock / mapping UAF).

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: high for RDS/IB users (prevents deadlock/oops on a real
  completion path)
- Risk: low–medium (workqueue deferral, ~70 lines, one subsystem; worker
  does not call into the IB module)
- Ratio: benefit outweighs risk. Larger than a 5-line NULL check, but
  the pattern is standard and v4 was specifically reduced to avoid
  unload races.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Sleep in softirq is a real, important bug
- Path exists on this 5.10 tree and is userspace-reachable via RDS RDMA
- Fixes target `0d4597c8c5ab` is in the tree
- Small, RDS-only, no new uAPI
- Needed kernel APIs exist
- v4 design addresses earlier review NAKs
- `destroy_workqueue(rds_wq)` drains deferred work
- RDS maintainer-authored; netdev applied it upstream

AGAINST:
- ~70 lines and a new work item (not a one-liner)
- Queued to net-next; Kicinski was uneasy reviewing it
- No syzbot/Tested-by on the committed message
- Trivial `message.c` context tweak for `rds_message_populate_header()`

UNRESOLVED:
- Could not fetch lore.kernel.org in-browser (403); used b4 mbox instead
- No evidence of a later revert or follow-up for `d100966325f7` (search
  did not turn one up)

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — v4 is the review-fixed
   design; mechanism matches the bug. (Confidence is “good”, not
   “trivial one-liner”.)
2. Fixes a real bug that affects users? **PASS**
3. Important issue? **PASS** — deadlock/crash, CRITICAL
4. Small and contained? **PASS** — 3 files, RDS only
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — code present; at most a minor
   context adjustment

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None (not a device ID/quirk/DT/build/docs exception). Qualifies
as a normal important bugfix.

Step 9.4: MAKE YOUR DECISION
This tree still unpins and dirties RDMA/atomic pages in the IB send
tasklet. That can sleep. Deferring only that unpin onto existing
`rds_wq` is the right fix here and does not need the rest of the v4
series.

What it solves for 5.10 users: RDS-over-InfiniBand RDMA READ/atomic
completion can call `lock_page()` in softirq, which can deadlock or
crash. That is exactly the class of bug stable is for.

Risk vs benefit: contained RDS change, process-context unpin, workqueue
drained on unload. Benefit is preventing a serious completion-path
failure.

Concerns: expect a small `message.c` context edit around
`rds_message_populate_header()`; do not pull series patches 2–4 as
prerequisites.

Verification:
- [Phase 1] Tags: SOB Henderson/Kicinski; Link msgid; lore v4 had Fixes:
  0d4597c8c5ab
- [Phase 2] Diff: defer dirtying unpin via work item; RDMA write still
  unpins in caller
- [Phase 3] `git describe` / Makefile: 5.10.270; blame unpin lines →
  0d4597c8c5ab; ancestor check exit 0
- [Phase 3] `338a3ba30c5ef` is a different recv.c deadlock
- [Phase 4] `b4 mbox`: 8 msgs, v1–v4, applied as d100966325f7; Kicinski
  queued net-next
- [Phase 4] WebFetch lore/msgid.link: 403; discussion from b4 + openwall
- [Phase 5] Call chain verified in ib_cm.c / ib_send.c;
  `set_page_dirty_lock()` uses `lock_page()` in mm/page-writeback.c
- [Phase 5] Other `rds_rdma_free_op()` caller is process-context error
  path in rdma.c:796
- [Phase 6] Local rdma.c still has sleeping unpin; `in_task()` and
  `rds_wq` exist; messages kzalloc’d
- [Phase 6] Header context differs (`h_exthdr[0]` vs memset) — minor
  backport
- [Phase 8] Failure mode: sleep-in-softirq / deadlock, CRITICAL
- UNVERIFIED: live lore HTML; no later revert found

**YES**

 net/rds/message.c | 26 +++++++++++++++++++++++++
 net/rds/rdma.c    | 49 ++++++++++++++++++++++++++++++++++++-----------
 net/rds/rds.h     | 10 ++++++++++
 3 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/net/rds/message.c b/net/rds/message.c
index 19202aa33f6f4..bdd340f4cce65 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -180,6 +180,19 @@ static void rds_message_purge(struct rds_message *rm)
 		kref_put(&rm->atomic.op_rdma_mr->r_kref, __rds_put_mr_final);
 }
 
+static void rds_message_unpin_worker(struct work_struct *work)
+{
+	struct rds_message *rm = container_of(work, struct rds_message,
+					      m_unpin_work);
+
+	if (rm->rdma.op_unpin_deferred)
+		rds_rdma_op_unpin_pages(&rm->rdma);
+	if (rm->atomic.op_unpin_deferred)
+		rds_atomic_op_unpin_page(&rm->atomic);
+
+	kfree(rm);
+}
+
 void rds_message_put(struct rds_message *rm)
 {
 	rdsdebug("put rm %p ref %d\n", rm, refcount_read(&rm->m_refcount));
@@ -187,8 +200,21 @@ void rds_message_put(struct rds_message *rm)
 	if (refcount_dec_and_test(&rm->m_refcount)) {
 		BUG_ON(!list_empty(&rm->m_sock_item));
 		BUG_ON(!list_empty(&rm->m_conn_item));
+
 		rds_message_purge(rm);
 
+		/* A final put in atomic context cannot dirty the ops'
+		 * user pages on unpin, so rds_rdma_free_op() and
+		 * rds_atomic_free_op() deferred it.  Finish the unpin,
+		 * and the free, from process context.
+		 */
+		if (rm->rdma.op_unpin_deferred ||
+		    rm->atomic.op_unpin_deferred) {
+			INIT_WORK(&rm->m_unpin_work, rds_message_unpin_worker);
+			queue_work(rds_wq, &rm->m_unpin_work);
+			return;
+		}
+
 		kfree(rm);
 	}
 }
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 34d9333e4229f..37695056756be 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -483,22 +483,36 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force)
 		kref_put(&mr->r_kref, __rds_put_mr_final);
 }
 
-void rds_rdma_free_op(struct rm_rdma_op *ro)
+void rds_rdma_op_unpin_pages(struct rm_rdma_op *ro)
 {
 	unsigned int i;
 
+	for (i = 0; i < ro->op_nents; i++) {
+		struct page *page = sg_page(&ro->op_sg[i]);
+
+		/* Mark page dirty if it was possibly modified, which
+		 * is the case for a RDMA_READ which copies from remote
+		 * to local memory
+		 */
+		unpin_user_pages_dirty_lock(&page, 1, !ro->op_write);
+	}
+}
+
+void rds_rdma_free_op(struct rm_rdma_op *ro)
+{
 	if (ro->op_odp_mr) {
 		kref_put(&ro->op_odp_mr->r_kref, __rds_put_mr_final);
+	} else if (in_task() || ro->op_write) {
+		/* An RDMA write's pages are only read by the remote
+		 * side; unpinning without dirtying does not sleep.
+		 */
+		rds_rdma_op_unpin_pages(ro);
 	} else {
-		for (i = 0; i < ro->op_nents; i++) {
-			struct page *page = sg_page(&ro->op_sg[i]);
-
-			/* Mark page dirty if it was possibly modified, which
-			 * is the case for a RDMA_READ which copies from remote
-			 * to local memory
-			 */
-			unpin_user_pages_dirty_lock(&page, 1, !ro->op_write);
-		}
+		/* Dirtying the pages on unpin can sleep; leave them
+		 * pinned and have rds_message_put() finish the unpin
+		 * from process context.
+		 */
+		ro->op_unpin_deferred = 1;
 	}
 
 	kfree(ro->op_notifier);
@@ -507,7 +521,7 @@ void rds_rdma_free_op(struct rm_rdma_op *ro)
 	ro->op_odp_mr = NULL;
 }
 
-void rds_atomic_free_op(struct rm_atomic_op *ao)
+void rds_atomic_op_unpin_page(struct rm_atomic_op *ao)
 {
 	struct page *page = sg_page(ao->op_sg);
 
@@ -515,6 +529,19 @@ void rds_atomic_free_op(struct rm_atomic_op *ao)
 	 * is the case for a RDMA_READ which copies from remote
 	 * to local memory */
 	unpin_user_pages_dirty_lock(&page, 1, true);
+}
+
+void rds_atomic_free_op(struct rm_atomic_op *ao)
+{
+	if (in_task()) {
+		rds_atomic_op_unpin_page(ao);
+	} else {
+		/* Dirtying the page on unpin can sleep; leave it
+		 * pinned and have rds_message_put() finish the unpin
+		 * from process context.
+		 */
+		ao->op_unpin_deferred = 1;
+	}
 
 	kfree(ao->op_notifier);
 	ao->op_notifier = NULL;
diff --git a/net/rds/rds.h b/net/rds/rds.h
index a029e5fcdea72..a4816da162930 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -424,6 +424,12 @@ struct rds_message {
 
 	void			*m_final_op;
 
+	/* Unpins the ops' user pages and frees the message from
+	 * process context when the final put happens in atomic
+	 * context: dirtying the pages on unpin can sleep.
+	 */
+	struct work_struct	m_unpin_work;
+
 	struct {
 		struct rm_atomic_op {
 			int			op_type;
@@ -447,6 +453,7 @@ struct rds_message {
 			unsigned int		op_mapped:1;
 			unsigned int		op_silent:1;
 			unsigned int		op_active:1;
+			unsigned int		op_unpin_deferred:1;
 			struct scatterlist	*op_sg;
 			struct rds_notifier	*op_notifier;
 
@@ -462,6 +469,7 @@ struct rds_message {
 			unsigned int		op_mapped:1;
 			unsigned int		op_silent:1;
 			unsigned int		op_active:1;
+			unsigned int		op_unpin_deferred:1;
 			unsigned int		op_bytes;
 			unsigned int		op_nents;
 			unsigned int		op_count;
@@ -938,6 +946,8 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm,
 			  struct cmsghdr *cmsg);
 void rds_rdma_free_op(struct rm_rdma_op *ro);
 void rds_atomic_free_op(struct rm_atomic_op *ao);
+void rds_rdma_op_unpin_pages(struct rm_rdma_op *ro);
+void rds_atomic_op_unpin_page(struct rm_atomic_op *ao);
 void rds_rdma_send_complete(struct rds_message *rm, int wc_status);
 void rds_atomic_send_complete(struct rds_message *rm, int wc_status);
 int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock()
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error Sasha Levin
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 14:32   ` sashiko-bot
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path Sasha Levin
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 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 a507023e6ff1d0b4e7aac49b2f547fed0c21ea4e ]

The pages backing an RDS memory region are pinned in __rds_rdma_map()
with rds_pin_pages(), which uses pin_user_pages_fast(): each page's
refcount is biased by GUP_PIN_COUNTING_BIAS to account the pin.  The
scatterlist is then handed to the IB transport, and the transport
releases the pages in __rds_ib_teardown_mr() with

	set_page_dirty(page);
	put_page(page);

put_page() drops a single reference instead of removing the pin bias,
so every MR teardown permanently strands the remaining references and
the pages are never freed - a userspace-triggerable memory leak of up
to RDS_MAX_MSG_SIZE per RDS_GET_MR/RDS_GET_MR_FOR_DEST call.

The conversion to the pin API updated the unpin sites in rdma.c but
missed this one on the transport side.  Release the pages with
unpin_user_pages_dirty_lock(), which removes the pin bias and also
dirties the page under the folio lock, closing the truncation race
that a bare set_page_dirty() leaves open.

Dirtying under the folio lock can sleep, which is safe in every path
that reaches __rds_ib_teardown_mr(): the registration-reuse path
(rds_ib_map_frmr()) runs in syscall context, and the pool flush
(rds_ib_unreg_frmr()) runs under pool->flush_lock, a mutex, and
already sleeps in rds_ib_post_inv().  The WARN_ON that guarded the
old irq-context set_page_dirty() case is dropped along with it.

Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260730041629.3512480-5-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:

The local tree is **5.10.270** (`pending-5.10`). The buggy RDS IB
teardown path is present here, the pin API mismatch is real, and the fix
applies cleanly.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[net/rds] [unpin] [release MR pages with the pin-API unpin
helper instead of put_page()]**

Subsystem prefix `net/rds`. Action verb is `unpin` (correctness of page
release, not a feature). Claimed intent: MR pages pinned with
`pin_user_pages_fast()` must be released with
`unpin_user_pages_dirty_lock()`, not `put_page()`.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

From the candidate message:
- `Signed-off-by: Allison Henderson <achender@kernel.org>` (author;
  Oracle RDS)
- `Link:
  https://patch.msgid.link/20260730041629.3512480-5-achender@kernel.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev merge)
- No `Reported-by`, `Tested-by`, `Reviewed-by`, `Acked-by`, `Cc: stable`
  in the candidate text

From the original lore submission (msgid
`20260730041629.3512480-5-achender@kernel.org`), these additional tags
were present and stripped by candidate prep:
- `Fixes: 0d4597c8c5ab ("net/rds: Track user mapped pages through
  special API")`
- `Assisted-by: Claude-Code:claude-fable-5`

Record: Author is the RDS contributor who submitted a 4-patch bug-fix
series. Netdev maintainer merged it. Original submission carried a
`Fixes:` tag pointing at the 2020 pin-API conversion. Absence of `Cc:
stable` on the candidate is expected.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `__rds_rdma_map()` pins pages with `rds_pin_pages()` →
  `pin_user_pages_fast()`. Teardown in `__rds_ib_teardown_mr()` does
  `set_page_dirty()` + `put_page()`. `put_page()` drops one ref; a
  FOLL_PIN pin adds `GUP_PIN_COUNTING_BIAS` (1024). Remaining refs are
  stranded.
- **Symptom:** Userspace-triggerable unreclaimable page leak, up to
  `RDS_MAX_MSG_SIZE` (1 MiB) per `RDS_GET_MR` / `RDS_GET_MR_FOR_DEST`.
  Same leak on every MR reuse/flush, not only the ioctl.
- **Root cause:** Pin-API conversion updated `net/rds/rdma.c` unpin
  sites and missed the IB transport teardown path.
- **Secondary fix:** `unpin_user_pages_dirty_lock()` dirties under the
  page/folio lock, closing the truncation race of bare
  `set_page_dirty()`.
- **Sleeping:** Author claims every caller of `__rds_ib_teardown_mr()`
  is process context (syscall reuse path, or pool flush under
  `flush_lock` mutex which already `wait_event`s in
  `rds_ib_post_inv()`).
- **Version info:** Bug introduced by the 2020 pin conversion
  (`0d4597c8c5ab`).

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not hidden. Explicit memory-leak fix with a clear pin vs put
mismatch. Not cleanup/refactor.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `net/rds/ib_rdma.c` only (−3 / +1)
- Function: `__rds_ib_teardown_mr()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record: In the scatterlist-release loop, before: `WARN_ON(!page->mapping
&& irqs_disabled()); set_page_dirty(page); put_page(page);`. After:
`unpin_user_pages_dirty_lock(&page, 1, true);`. DMA unmap,
`kfree(ibmr->sg)`, and pool accounting in `rds_ib_teardown_mr()` are
unchanged. Normal teardown path, not an error-only path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** reference-counting / resource leak (FOLL_PIN bias not
  removed), plus initialization/dirtying correctness
  (`set_page_dirty_lock` vs `set_page_dirty`)
- **Mechanism:** `pin_user_pages_fast()` sets `FOLL_PIN` and bumps
  refcount by `GUP_PIN_COUNTING_BIAS`. `put_page()` subtracts 1, leaving
  1023 refs. Pages never return to the allocator. `unpin_user_page()` /
  `unpin_user_pages_dirty_lock()` call `put_compound_head(...,
  FOLL_PIN)`, which multiplies refs by the bias (or uses
  `hpage_pincount_sub`) and actually releases the pin.

**Step 2.4: ASSESS THE FIX QUALITY**

Record: Obviously correct against the pin-API contract (`mm/gup.c`
documents that FOLL_PIN pages must be released via `unpin_user_page()`).
Same helper is already used in this tree in `net/rds/rdma.c` and
`net/rds/info.c`. Minimal. Regression risk is sleep-in-atomic if
teardown ever runs with IRQs off; verified callers already sleep
(`wait_event` / `mutex_lock`). The dropped `WARN_ON` was a leftover from
a 2015 `BUG_ON(irqs_disabled())` downgrade; current callers take a mutex
or run in syscall context.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- `set_page_dirty` + `put_page` in this function: `08b48a1ed84b19` (Andy
  Grover, 2009) — originally paired with `get_user_pages`.
- `WARN_ON(!page->mapping && irqs_disabled())`: `5c240fa2ab394a` (2015),
  downgraded from `BUG_ON(irqs_disabled())` because that assertion fired
  on “normal execution paths” (FMR-era). FMR support is already removed
  in this tree (`07549ee21ce52`).
- Pin conversion that made `put_page` wrong: `0d4597c8c5abd`
  (2020-02-16), present in this tree.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: `0d4597c8c5abdeeaf50774066c16683f30184dc8` (“net/rds: Track user
mapped pages through special API”) converted `rds_pin_pages()` to
`pin_user_pages_fast()` and updated unpin sites in `rdma.c` only
(`rds_rdma_free_op`, `rds_atomic_free_op`, error paths). It did **not**
touch `ib_rdma.c`. `git merge-base --is-ancestor 0d4597c8c5abd HEAD`
succeeded — the buggy conversion is in this 5.10 tree. Intermediate
related fix already here: `91a44b406bc1f` (“net: rds: fix MR cleanup on
copy error”) — different bug (double-unpin on `put_user` failure), not a
substitute for this leak.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record: Recent `net/rds/ib_rdma.c` history is unrelated (laddr check,
FRMR reject, null deref). This is standalone vs local history. Upstream
it is v4 4/4 of Allison Henderson’s series; patches 1–3 fix different
RDS bugs (sleeping unpin from tasklet in `rdma.c`, socket UAF via MR,
send-path message leak) and are **not** prerequisites for this hunk.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Allison Henderson has many RDS commits in this tree (locking,
shutdown, zerocopy). Oracle RDS maintainer-side contributor.
`MAINTAINERS` lists Santosh Shilimkar; Allison is a long-time RDS
author. Related contemporaneous work is the rest of the v4 series, not a
dependency of this patch.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: Needs `unpin_user_pages_dirty_lock()` and
`pin_user_pages_fast()` — both exist in 5.10 (`mm/gup.c`,
`EXPORT_SYMBOL`). No new helper, no struct change. Can apply standalone.
`git apply --check` succeeded (hunk offset +4 only).

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- Lore/thread via `b4 am` / `b4 mbox`: cover `https://patch.msgid.link/2
  0260730041629.3512480-1-achender@kernel.org`
- Patch: msgid `20260730041629.3512480-5-achender@kernel.org` (`[PATCH
  net v4 4/4]`)
- Openwall mirror: https://lists.openwall.net/netdev/2026/07/30/66
- Revisions: v1–v3 were a 3-patch series; **this leak fix is new in
  v4**. Applied version is v4.
- Merged to `netdev/net-next.git` as `a507023e6ff1` (patchwork-bot,
  2026-08-05)
- Jakub Kicinski: not a NAK — he said he lacked confidence reviewing RDS
  and queued the series for **-next** rather than `net`. Allison agreed
  (Fixes tags, but “not simple bugs” / “really old bugs”).
- No reviewer NAK, no request to drop patch 4, no flag that teardown can
  sleep in IRQ on current code.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record: `b4` recipients: netdev, linux-rdma, Pabeni, Edumazet, Kicinski,
Horms; Cc John Hubbard and Leon Romanovsky (original pin-API authors).
No `Reviewed-by` landed. Kicinski merged without a deep RDS review.
Technical correctness of this hunk does not depend on that: it matches
the pin API the Cc list designed.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No syzbot/bugzilla. Bug is from code inspection / UEK porting.
Trigger is real (`setsockopt(RDS_GET_MR)` / MR reuse), not theoretical.
No user-count from public reports.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Standalone vs 1/4–3/4. Patch 1 is about `rds_rdma_free_op()`
sleeping from the **send tasklet** — a different function already using
`unpin_user_pages_dirty_lock()` in `rdma.c`. Backporting 4/4 does not
require 1/4; it does not widen that tasklet bug.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable search for this subject returned no
discussion that this fix was rejected or already taken. UNVERIFIED that
no private stable thread exists.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**

Record: `__rds_ib_teardown_mr()` (changed); `rds_ib_teardown_mr()`
(wrapper); `rds_ib_map_frmr()`, `rds_ib_unreg_frmr()` (callers).

**Step 5.2: TRACE CALLERS**

Record:
- `rds_ib_map_frmr()` → `rds_ib_teardown_mr()` — reuse/remap. Called
  from `rds_ib_reg_frmr()` → `rds_ib_get_mr()` → `__rds_rdma_map()` /
  cmsg RDMA map. Syscall (`setsockopt` / `sendmsg`). Already
  `wait_event`s in `rds_ib_post_reg_frmr()`.
- `rds_ib_unreg_frmr()` → `__rds_ib_teardown_mr()` — only from
  `rds_ib_flush_mr_pool()`, which takes `pool->flush_lock` (mutex).
  Callers of flush: delayed work `rds_ib_mr_pool_flush_worker`,
  `rds_ib_try_reuse_ibmr` (GFP_KERNEL alloc path), `rds_ib_free_mr` only
  if `!in_interrupt()`, `rds_ib_flush_mrs()` (socket close /
  `RDS_FREE_MR`), `rds_ib_destroy_mr_pool()`,
  `rds_ib_conn_path_shutdown()` (already `wait_event_timeout`).
  Interrupt `free_mr` queues `flush_worker` instead of flushing inline.

**Step 5.3: TRACE CALLEES**

Record: After the change, the loop calls `unpin_user_pages_dirty_lock()`
→ `set_page_dirty_lock()` (can sleep) + `unpin_user_page()`. Previously
`set_page_dirty()` + `put_page()`. DMA unmap stays first.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Reachable from userspace: `rds_setsockopt` → `RDS_GET_MR` /
`RDS_GET_MR_FOR_DEST` → `rds_get_mr()` → `__rds_rdma_map()` →
`rds_pin_pages()` → transport `get_mr`. Also RDMA cmsg on send. Requires
`CONFIG_RDS=y/m`, `CONFIG_RDS_RDMA`, InfiniBand, and `can_do_mlock()`.
Not universal, but a real syscall path. Unprivileged users typically
need `RLIMIT_MEMLOCK`/CAP_IPC_LOCK to pin; RDS/IB cluster users have
that.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Same missed-unpin class was why `rdma.c` was converted in 2020.
Remaining `put_page` in `net/rds/message.c` is for message payload pages
(`__free_page` / zerocopy), not FOLL_PIN MR pages. IB umem/qib/hfi1
already use `unpin_user_pages_dirty_lock()`. This is the leftover RDS IB
MR site.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: Yes. `net/rds/ib_rdma.c` lines 253–260 still have `WARN_ON` +
`set_page_dirty` + `put_page`. `rds_pin_pages()` already uses
`pin_user_pages_fast()` (`net/rds/rdma.c:163`). `GUP_PIN_COUNTING_BIAS`
is `(1U << 10)` in `include/linux/mm.h`. Bug present since this series
branched (v5.10 includes `0d4597c8c5ab` from Feb 2020; v5.10 release is
Dec 2020).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** (`git apply --check`: hunk succeeded at offset
4). Surrounding function matches the mainline hunk. 5.10’s
`unpin_user_pages_dirty_lock()` uses `set_page_dirty_lock()`, not
folios; the public API and sleep/lock properties match what the patch
needs. Commit-message “folio lock” is mainline wording; behavior here is
the page lock, which is correct for 5.10.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No equivalent unpin in `__rds_ib_teardown_mr()`. `91a44b406bc1f`
is a different MR cleanup. `git log --grep='unpin MR pages' -- net/rds`
is empty in this tree.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **net/rds** (Reliable Datagram Sockets), IB RDMA MR pool.
Criticality: **IMPORTANT** for RDS/IB users (Oracle RAC-style clusters);
**PERIPHERAL** for everyone else (`CONFIG_RDS_RDMA` + InfiniBand). Not
core mm/VFS, but pinned-page leaks are mm-visible (unreclaimable pages).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Mature. The teardown loop dates to 2009; the pin mismatch has
been wrong for the entire 5.10 lifetime. Low churn on `ib_rdma.c`
relative to netdev core.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**

Record: Driver/config-specific: `CONFIG_RDS` + `CONFIG_RDS_RDMA` + IB
hardware. TCP RDS (`CONFIG_RDS_TCP`) has no RDMA MRs and is unaffected.

**Step 8.2: TRIGGER CONDITIONS**

Record: Common for RDS RDMA: every MR map/reuse/teardown (`RDS_GET_MR`,
RDMA cmsg, pool flush). Not a rare error path. Needs mlock capability.
Not a timing race.

**Step 8.3: FAILURE MODE SEVERITY**

Record: Unreclaimable page leak (pin bias left behind). Repeated
GET_MR/reuse can pin large amounts of RAM until OOM. **Severity: HIGH**
(not a panic, but a userspace-triggerable leak of pinned pages; same
class as other GUP pin leaks taken into stable). Secondary: dirty-
without-lock truncation race on file-backed MRs (**MEDIUM** on that
subset).

**Step 8.4: RISK-BENEFIT RATIO**

Record:
- **Benefit:** High for RDS/IB; stops a leak that has existed for the
  whole 5.10 life. Zero functional change for other configs.
- **Risk:** Very low — one call-site, existing exported helper, callers
  already sleepable. Does not add APIs or change userspace.
- **Ratio:** Strongly favors backport.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real FOLL_PIN vs `put_page()` leak; verified in 5.10 `mm/gup.c` and
  `net/rds/rdma.c`/`ib_rdma.c`
- Userspace-reachable (`RDS_GET_MR` / RDMA map)
- Fixes commit `0d4597c8c5ab` is in this tree
- 1-file, 4-line change; `unpin_user_pages_dirty_lock()` already used
  elsewhere in RDS here
- Applies cleanly
- Author is RDS; merged by netdev
- Sleeping unpin is safe on verified 5.10 call chains

**AGAINST:**
- RDS/IB is not a universal path
- Kicinski did not deeply review and put the series in net-next
- No public crash/syzbot report
- Series mates 1–3 are separate bugs (not blockers)

**UNRESOLVED:** No stable@ thread found; WebFetch to lore HTML returned
403 (thread recovered via `b4` + openwall + curl).

**Step 9.2: STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — pin-API contract; same
   helper already in-tree RDS; merged to net-next
2. Fixes a real bug that affects users? **PASS** — pinned pages never
   freed on MR teardown
3. Important (crash/security/corruption/deadlock)? **PASS** —
   unreclaimable leak on a hot RDS RDMA path, up to 1 MiB per map plus
   reuse; eventual OOM
4. Small and contained? **PASS** — one function, −3/+1
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — `git apply --check` clean;
   helpers present

**Step 9.3: EXCEPTION CATEGORIES**

Record: None. Ordinary bug fix (not ID/quirk/DT/build/docs).

**Step 9.4: DECISION**

This is a small, obviously correct leak fix for a bug that has been in
this 5.10 tree since day one. It does not need the rest of the v4
series. Benefit for RDS/IB users outweighs the low regression risk.

---

### What the commit solves for this tree

`rds_pin_pages()` already pins with `pin_user_pages_fast()` (`FOLL_PIN`,
+1024 refs). IB teardown still `put_page()`s once, so every MR teardown
permanently leaks those pages. Replacing that with
`unpin_user_pages_dirty_lock()` restores the pin/unpin pairing and
dirties under the page lock. That matters to 5.10 RDS-over-InfiniBand
users (clusters using `RDS_GET_MR` / RDMA ops): memory is not optional
reclaim, it is stuck until reboot.

### Risk vs benefit

Benefit is a real, repeating leak on a syscall-visible path. Risk is a
one-line helper swap on paths that already take a mutex and
`wait_event`. The patch applies without rework.

---

### Verification

- [Phase 1] Parsed candidate tags: Allison Henderson SOB, msgid.link,
  Kicinski SOB; lore copy also has `Fixes: 0d4597c8c5ab`
- [Phase 2] Diff: `__rds_ib_teardown_mr()` in `net/rds/ib_rdma.c`,
  replace WARN/`set_page_dirty`/`put_page` with
  `unpin_user_pages_dirty_lock(&page, 1, true)`
- [Phase 3] `git describe`/Makefile: local tree **5.10.270**, branch
  `pending-5.10`
- [Phase 3] `git blame`: put_page since 2009; WARN_ON from
  `5c240fa2ab394a` (2015)
- [Phase 3] `git show 0d4597c8c5abd`: pin conversion of `rdma.c` only;
  `git merge-base --is-ancestor` → in HEAD
- [Phase 3] `git show dbfe7d74376e1`: only `info.c`, not this leak
- [Phase 3] Read `mm/gup.c`: `pin_user_pages_fast()` sets `FOLL_PIN`;
  `unpin_user_pages_dirty_lock()` / `put_compound_head(..., FOLL_PIN)`
  apply `GUP_PIN_COUNTING_BIAS` (1024)
- [Phase 3] Read local `net/rds/rdma.c` `rds_pin_pages()` and
  `ib_rdma.c` teardown: mismatch confirmed
- [Phase 4] `b4 am`/`b4 mbox`: v4 4/4 series; merged as `a507023e6ff1`;
  Kicinski queued for net-next; no NAK
- [Phase 4] Openwall https://lists.openwall.net/netdev/2026/07/30/66
  matches the diff
- [Phase 4] lore HTML WebFetch: 403; thread recovered via b4
- [Phase 5] Callers: `rds_ib_map_frmr` (syscall), `rds_ib_unreg_frmr`
  via `rds_ib_flush_mr_pool` (mutex + workqueue); `rds_ib_free_mr`
  defers flush when `in_interrupt()`
- [Phase 5] `RDS_MAX_MSG_SIZE` = 1 MiB in `net/rds/rds.h`
- [Phase 6] Buggy code present at `ib_rdma.c:258-260`; `git apply
  --check` succeeded
- [Phase 6] `unpin_user_pages_dirty_lock` already used in
  `net/rds/rdma.c` and `net/rds/info.c`
- [Phase 7] `MAINTAINERS`: RDS supported (Santosh Shilimkar / Oracle)
- [Phase 8] Failure mode: unreclaimable FOLL_PIN leak, HIGH for RDS_RDMA
- UNVERIFIED: no public syzbot/user report; no stable@ thread found

**YES**

 net/rds/ib_rdma.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 751755cd069e0..36fd8dedbce56 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -251,9 +251,7 @@ void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr)
 
 			/* FIXME we need a way to tell a r/w MR
 			 * from a r/o MR */
-			WARN_ON(!page->mapping && irqs_disabled());
-			set_page_dirty(page);
-			put_page(page);
+			unpin_user_pages_dirty_lock(&page, 1, true);
 		}
 		kfree(ibmr->sg);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (2 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock() Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 14:47   ` sashiko-bot
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID Sasha Levin
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Sharath Srinivasan, Gerd Rausch, Allison Henderson,
	Jakub Kicinski, Sasha Levin, davem, edumazet, pabeni, netdev,
	linux-rdma, rds-devel, linux-kernel

From: Sharath Srinivasan <sharath.srinivasan@oracle.com>

[ Upstream commit eb8a59a17f4a8b6f2afb4a8063e99dd96cc3fab0 ]

When rds_send_xmit() picks the next message off cp_send_queue it takes
its own reference with rds_message_addref().  If the message then hits
the never-retransmit check (RDS_MSG_FLUSH, or an RDMA op that was
already retransmitted), it is moved to the local to_be_dropped list and
that reference is dropped after the batch.

However, if RDS_MSG_ON_CONN has already been cleared, the message is
not added to to_be_dropped and the reference taken above is never
dropped: cp_xmit_rm has not been set at this point, so the loop simply
abandons rm and the rds_message (and everything it pins: pages, MRs,
notifiers) leaks after an RDMA error.

The only other places that clear RDS_MSG_ON_CONN are
rds_send_path_drop_acked() and rds_send_drop_to(), and both can run
while rds_send_xmit() has dropped cp_lock between moving the message
to cp_retrans and re-taking the lock in the never-retransmit check:
rds_send_path_drop_acked() can ack away a message that already sat on
cp_retrans - the RDS_MSG_RETRANSMITTED case above - and
rds_send_drop_to() runs on socket close.  Both unlink the message
under cp_lock and put their own reference, leaving the xmit-path
reference stranded.

Drop the reference directly in that case.

This mirrors Oracle UEK commit "net/rds: fix rds_message memleak in
rds_send_xmit".

Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
Signed-off-by: Sharath Srinivasan <sharath.srinivasan@oracle.com>
[achender: port to net-next; update commit message, checkpatch nits]
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260730041629.3512480-4-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:

This is a real, long-standing `rds_message` leak in `rds_send_xmit()`
that exists in this 5.10.270 tree. The fix is small, matches the local
code, and does not need the rest of its series.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[net/rds] [fix] [rds_message leak in rds_send_xmit() drop
path]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

From the candidate message:
- `Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>` (original
  author)
- `Signed-off-by: Sharath Srinivasan <sharath.srinivasan@oracle.com>`
  (UEK/port author)
- `[achender: port to net-next; update commit message, checkpatch nits]`
- `Signed-off-by: Allison Henderson <achender@kernel.org>` (RDS
  maintainer-side porter)
- `Link:
  https://patch.msgid.link/20260730041629.3512480-4-achender@kernel.org`
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` (netdev merge)

No `Reported-by`, `Tested-by`, `Reviewed-by`, or `Acked-by` in the
candidate text. Absence of `Fixes:` / `Cc: stable` is expected here.

Mailing-list v4 (same msgid) **did** carry:
- `Fixes: 2ad8099b58f2 ("RDS: rds_send_xmit() locking/irq fixes")`

Oracle UEK source (`94549e4732d8`) carried:
- `Fixes: fbbe0610d057 ("RDS: add support for atomic messages over the
  wire")` — that SHA is **not** in this tree
- `Reviewed-by: William Kucharski <william.kucharski@oracle.com>`
- `Orabug: 38923495` (internal production bug)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `rds_send_xmit()` takes an extra `rds_message_addref()` when
  dequeuing. On the never-retransmit path (`RDS_MSG_FLUSH` or already-
  retransmitted RDMA), that ref is only dropped if the message is moved
  onto `to_be_dropped`. If `RDS_MSG_ON_CONN` was already cleared, the
  extra ref is abandoned.
- **Symptom:** leak of `rds_message` plus pinned pages, MRs, and
  notifiers after an RDMA error / reconnect / socket close.
- **Root cause:** `rds_send_path_drop_acked()` (ACK of a message already
  on `cp_retrans`) and `rds_send_drop_to()` (socket close) can clear
  `RDS_MSG_ON_CONN` and put **their** refs in the window where xmit has
  dropped `cp_lock`. They do not put the xmit-path extra ref.
  `cp_xmit_rm` is not set yet, so the success-path put never runs.
- **Version info:** bug traces to 2010 locking change; present in this
  5.10 tree.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject and body are an explicit leak/refcount
fix.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `net/rds/send.c` only (~+12/−3 in `rds_send_xmit()`)
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `test_and_clear_bit(RDS_MSG_ON_CONN)` → if set,
  `list_move` to `to_be_dropped`; always unlock; `continue`. If the bit
  was already clear, no put.
- **After:** same if the bit is set; **else** unlock then
  `rds_message_put(rm)` for the extra xmit ref.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Reference-counting / resource leak.** Extra
`rds_message_addref()` at dequeue (local tree `net/rds/send.c:265`) is
not balanced when `RDS_MSG_ON_CONN` is already clear. Verified in this
tree: only `rds_send_path_drop_acked()` (`clear_bit` at line 707) and
`rds_send_drop_to()` (`test_and_clear_bit` at line 774) plus this drop
path itself clear that bit. `rds_send_path_reset()` does **not** (v4
commit message correction vs v1–v3).

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- **Obviously correct.** Queueing takes a conn-list ref
  (`rds_send_queue_rm` addref + `RDS_MSG_ON_CONN`). Xmit takes a second
  ref. Concurrent drop/ack puts the conn-list ref. Xmit must put its
  own.
- `rds_send_remove_from_sock()` documents that it puts the list-position
  ref; drop_acked uses that. Xmit’s extra ref is separate.
- After `continue`, the next loop iteration does `rm = cp->cp_xmit_rm`
  (still NULL), so the local pointer is not used after put.
- Put happens after `spin_unlock_irqrestore`, same as the existing
  success-path put at line 423. The “irqs on here, so we can put()”
  comment is about not putting **under** `cp_lock`.
- **Regression risk: low.** Does not change locking order or APIs.
  Follow-up `reinitialize to_be_dropped on restart` is documented
  hardening with **no known user-visible bug**; this else-path does not
  even enqueue on `to_be_dropped`.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Drop-path structure from `5c11559046c4b3` (“RDS: send.c”, 2009).
- Leak introduced by `2ad8099b58f27` (“RDS: rds_send_xmit() locking/irq
  fixes”, 2010): that commit **removed** an unconditional
  `rds_message_put(rm)` on this path and only put messages that made it
  onto `to_be_dropped`.
- FLUSH clause: `905dd4184e0732` (2016). Multipath `cp_` conversion:
  `1f9ecd7eacfd9e` (2016).
- Buggy pattern has been in-tree for ~16 years; first appeared long
  before 5.10.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record:
- Mailing-list `Fixes: 2ad8099b58f2` — **is an ancestor of this HEAD**
  (`git merge-base --is-ancestor` exit 0).
- `git show 2ad8099b58f27` confirms the put was moved to the batch-end
  `to_be_dropped` walk only.
- UEK `Fixes: fbbe0610d057` is **not** in this tree (exit 128); that tag
  is a red herring for 5.10. The real introducer here is `2ad8099b58f2`.

**Step 3.3: CHECK FILE HISTORY**
Record: Recent `net/rds/send.c` work in this tree is locking/xmit
serialization (`acquire_in_xmit`, shutdown races), not this drop path.
No prior fix for this leak (`rg` for “already off the conn list” is
empty). **Standalone**, not a refactor prerequisite.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Gerd Rausch / Sharath Srinivasan / Allison Henderson are
established RDS contributors. Henderson has many RDS stable backports in
this tree. This is a UEK→upstream port of a production Orabug.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: v4 series is four **independent** bugs (sleep-in-atomic unpin,
MR socket UAF, **this leak**, IB MR pin leak). This hunk only needs
existing `rds_message_put()` / `RDS_MSG_ON_CONN` / `to_be_dropped`, all
present. **Applies standalone.**

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c` on the candidate SHA was not possible (commit is not in
  this checkout). `b4 dig -c 5c11559046c4b3` only found the 2009
  original.
- lore.kernel.org fetches returned **403**. Used openwall mirrors.
- Thread: https://lists.openwall.net/netdev/2026/07/30/65 (v4 3/4),
  cover https://lists.openwall.net/netdev/2026/07/30/62
- Revisions: v1 (2026-07-11) → v3 → v4 (2026-07-30). **Code of this
  patch unchanged after v3**; v4 only corrected the commit message to
  name `drop_acked`/`drop_to` instead of `rds_send_path_reset()`.
- Merged by Jakub Kicinski. No NAK found.
- v1–v3 incorrectly named `rds_send_path_reset()` as a clearer of
  `RDS_MSG_ON_CONN`; verified **false** in this tree
  (`rds_send_path_reset` only sets `RDS_MSG_RETRANSMITTED` and splices
  queues).

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Sent to netdev, linux-rdma, Kicinski, Dumazet, Abeni, Horms. RDS
lists historically include `rds-devel@oss.oracle.com`. No extra
`Reviewed-by` on the upstream version; UEK had William Kucharski.
Maintainer-side porter is Allison Henderson.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: Oracle UEK Orabug 38923495; no public syzbot/bugzilla report
found. Production bug inside Oracle RDS, not theoretical.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Independent of series 1/4, 2/4, 4/4. Later “reinitialize
`to_be_dropped` on restart” is **hardening only** (“no user-visible bug
is known”).

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search **403**; web search found **no**
stable-list discussion of this leak. UNVERIFIED whether anyone already
requested/rejected it for 5.10.y.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

semcode MCP is **not** available; used read/grep.

**Step 5.1: KEY FUNCTIONS**
Record: `rds_send_xmit()` only.

**Step 5.2: TRACE CALLERS**
Record (this tree):
- `rds_sendmsg()` → `rds_send_xmit()` (`send.c:1385`) — syscall
- `rds_send_worker()` (`threads.c:200`) — `rds_wq` work
- `rds_ib_tasklet_fn_send()` (`ib_cm.c:334`) — IB send tasklet

**Step 5.3: TRACE CALLEES**
Record: `rds_message_addref` / `rds_message_put` (`message.c`); last put
runs `rds_message_purge()` (pages, `rds_rdma_free_op`, MR krefs).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: **Userspace-reachable** via RDS `sendmsg`. Also on IB completion
and reconnect. Race: xmit drops `cp_lock` after moving to `cp_retrans`;
recv/ACK path (`rds_send_path_drop_acked`) or
`close`/`RDS_CANCEL_SENT_TO` (`rds_send_drop_to`) can run then.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same file already balances other refs carefully (`drop_to` skips
if `ON_CONN` already clear). This path is the missing counterpart. No
duplicate of this exact leak elsewhere in `net/rds/`.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `pending-5.10`, `make kernelversion` = **5.10.270**,
`git describe` = `p-5.10-1-gce56b7a73b64b`.

```287:294:net/rds/send.c
                        if (test_bit(RDS_MSG_FLUSH, &rm->m_flags) ||
                            (rm->rdma.op_active &&
                            test_bit(RDS_MSG_RETRANSMITTED,
&rm->m_flags))) {
                                spin_lock_irqsave(&cp->cp_lock, flags);
                                if (test_and_clear_bit(RDS_MSG_ON_CONN,
&rm->m_flags))
                                        list_move(&rm->m_conn_item,
&to_be_dropped);
                                spin_unlock_irqrestore(&cp->cp_lock,
flags);
                                continue;
                        }
```

Introduced in 2010 (`2ad8099b58f2`); present for the entire 5.10
lifetime.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply** (trivial fuzz at most). Local drop-path text
matches the hunk exactly. Nearby comment still has the old “We cold
possibly” typo; that line is context only.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: Fix **not** present. No other send.c commit in this tree plugs
this hole.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **net/rds** — Reliable Datagram Sockets (Oracle RAC / InfiniBand
and TCP). MAINTAINERS: Supported (Santosh Shilimkar / Oracle).
**IMPORTANT** (not core mm/VFS; not staging). `CONFIG_RDS` depends on
`INET`; RDMA ops need `CONFIG_RDS_RDMA`.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Actively maintained in this 5.10 tree (recent shutdown/xmit
locking, TCP corruption, NULL-deref fixes). Mature send path; this leak
is old, not a new-feature bug.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Config/driver-specific** — `CONFIG_RDS` users, especially
RDMA/IB reconnect and TCP peer-generation flush (`RDS_MSG_FLUSH` in
`recv.c`). Enterprise RDS/RAC deployments.

**Step 8.2: TRIGGER CONDITIONS**
Record:
1. Xmit dequeues a message (addref, move to `cp_retrans`, drop
   `cp_lock`).
2. Never-retransmit: `RDS_MSG_FLUSH` (peer gen change) or RDMA +
   `RDS_MSG_RETRANSMITTED` (after `rds_send_path_reset`).
3. Concurrent ACK (`drop_acked`) or socket close (`drop_to`) already
   cleared `ON_CONN`.

Not every packet; **error/reconnect/close**. Unprivileged RDS sockets
can drive send/close; RDMA/reconnect is the realistic production case
(Orabug).

**Step 8.3: FAILURE MODE SEVERITY**
Record: **Memory/resource leak** of message, pages, MRs, notifiers. Not
a panic. Repeated reconnects accumulate pinned memory → **HIGH** for RDS
users, not a universal crash.

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for RDS/RDMA users; stops leaking pinned pages/MRs
  after errors that already happen in production.
- **Risk:** very low (~12 lines, one else-put, same pattern as existing
  puts).
- **Ratio:** favor backport.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real refcount leak; objects pin pages/MRs/notifiers
- Present in this 5.10 tree since 2010 (`2ad8099b58f2`)
- Small, obviously correct, one function
- Clean apply; no prerequisites
- RDS maintainer port; netdev merge; Oracle production Orabug
- Userspace-reachable via RDS send + close/reconnect

**AGAINST:**
- RDS is not universal
- Error-path race, not every send
- Not a crash/CVE
- No public syzbot report

**UNRESOLVED:**
- Stable-list history (lore 403)
- Whether last-ref `rds_message_put()` from IB **tasklet** can sleep via
  `unpin_user_pages_dirty_lock()` — **already true** for the success-
  path and `to_be_dropped` puts in this tree; this patch does not create
  that class of bug (series 1/4 is a separate sleep-in-atomic fix)

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — refcount math checks out;
   UEK + netdev merge
2. Real bug affecting users? **PASS** — Orabug 38923495; leak is in this
   tree
3. Important (crash/security/corruption/deadlock)? **PASS** — leak of
   pinned pages/MRs after RDMA error/reconnect; severity HIGH for RDS
4. Small and contained? **PASS** — ~12 lines, one file
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS**

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not an ID/quirk/DT/build/docs exception). Qualifies as a
normal leak/refcount fix.

**Step 9.4: DECISION**
Backport to **this** 5.10.270 tree. The buggy code is here, the fix is
surgical, and there is no missing prerequisite.

What it fixes for 5.10 users: after RDMA QP error / reconnect
(`RDS_MSG_RETRANSMITTED`) or peer generation flush (`RDS_MSG_FLUSH`),
racing ACK or socket close can clear `RDS_MSG_ON_CONN` in the xmit lock
gap. The extra `rds_message_addref()` is then never dropped, leaking the
message and everything it pins. Adding `rds_message_put(rm)` in that
else branch restores the balance `2ad8099b58f2` broke.

---

## Verification

- **[Phase 1]** Tags: SOBs Rausch/Srinivasan/Henderson/Kicinski; Link
  msgid `3512480-4`; ML `Fixes: 2ad8099b58f2`; UEK Orabug 38923495
- **[Phase 2]** Diff: else-branch `rds_message_put(rm)` in
  `rds_send_xmit()` never-retransmit path
- **[Phase 2]** Confirmed `rds_send_remove_from_sock()` puts the conn-
  list ref; xmit extra ref is separate (`send.c:605-674`)
- **[Phase 2]** Confirmed only drop_acked (707) and drop_to (774) plus
  this path clear `RDS_MSG_ON_CONN`
- **[Phase 3]** `git blame`: leak from `2ad8099b58f27` (2010), which
  removed unconditional put
- **[Phase 3]** `git merge-base --is-ancestor 2ad8099b58f2 HEAD` → yes;
  `fbbe0610d057` → no
- **[Phase 3]** `git show 2ad8099b58f27`: put moved to `to_be_dropped`
  only
- **[Phase 4]** openwall v4 0/4 and 3/4; v4 commit-message correction;
  Kicinski merge
- **[Phase 4]** Follow-up `to_be_dropped` reinit is hardening only, not
  required
- **[Phase 4]** UNVERIFIED: lore.kernel.org 403; `b4 dig` could not
  target the 2026 SHA (not in this tree)
- **[Phase 5]** Callers: sendmsg, `rds_send_worker`,
  `rds_ib_tasklet_fn_send`
- **[Phase 5]** No semcode MCP
- **[Phase 6]** `git describe HEAD` = `p-5.10-1-gce56b7a73b64b`; `make
  kernelversion` = 5.10.270
- **[Phase 6]** Buggy hunk present at `send.c:287-294`; fix text absent
- **[Phase 8]** Failure mode: leak of message + pages + MRs; HIGH for
  RDS, not a panic
- **UNVERIFIED:** stable@ discussion of this specific backport

**YES**

 net/rds/send.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/net/rds/send.c b/net/rds/send.c
index 5d09c7654f136..0a541cfc90185 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -288,9 +288,21 @@ int rds_send_xmit(struct rds_conn_path *cp)
 			    (rm->rdma.op_active &&
 			    test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags))) {
 				spin_lock_irqsave(&cp->cp_lock, flags);
-				if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags))
-					list_move(&rm->m_conn_item, &to_be_dropped);
-				spin_unlock_irqrestore(&cp->cp_lock, flags);
+				if (test_and_clear_bit(RDS_MSG_ON_CONN,
+						       &rm->m_flags)) {
+					/* our ref is put after the batch */
+					list_move(&rm->m_conn_item,
+						  &to_be_dropped);
+					spin_unlock_irqrestore(&cp->cp_lock,
+							       flags);
+				} else {
+					/* already off the conn list; drop
+					 * the ref taken above ourselves
+					 */
+					spin_unlock_irqrestore(&cp->cp_lock,
+							       flags);
+					rds_message_put(rm);
+				}
 				continue;
 			}
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (3 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 15:05   ` sashiko-bot
  2026-10-19 15:09   ` Michael Margolin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it Sasha Levin
  6 siblings, 2 replies; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Anas Mousa, Michael Margolin, Leon Romanovsky, Sasha Levin,
	linux-rdma, linux-kernel

From: Anas Mousa <anasmous@amazon.com>

[ Upstream commit 6a57af838b1a56405a9bde9030de16df901ae2ca ]

Add support for 0xefa4 devices.

Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Anas Mousa <anasmous@amazon.com>
Link: https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a two-line PCI ID addition to the existing Amazon EFA RDMA
driver. That matches the stable-tree device-ID exception, and the local
7.3-rc4 tree already has the driver and ID table.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
- Subsystem: `RDMA/efa`
- Action verb: **Add**
- Claimed intent: register PCI device ID `0xefa4` so the in-tree EFA
  driver binds new Amazon Elastic Fabric Adapter hardware.

Record: `[RDMA/efa] [add] [PCI ID 0xefa4 for next-gen EFA VF]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- `Reviewed-by: Michael Margolin <mrgolin@amazon.com>` (Amazon EFA
  contributor; 20 commits in this driver)
- `Signed-off-by: Anas Mousa <anasmous@amazon.com>` (author)
- `Link:
  https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com`
- `Signed-off-by: Leon Romanovsky <leon@kernel.org>` (RDMA maintainer,
  committer)
- No `Fixes:` tag (expected)
- No `Cc: stable@vger.kernel.org` (expected)
- No `Reported-by:`, `Tested-by:`, `Acked-by:`
- Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
  ...]` markers (none in the real commit)

Record: Maintainer-applied PCI ID patch; Amazon internal review; lore
link present; no syzbot/bug report (not applicable).

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Body is one sentence: “Add support for 0xefa4 devices.” Cover letter
(mbox): “Make a minor device interface change needed for new EFA devices
and enable support for 0xefa4 PCI ID.” No crash, no reproducer — this is
hardware enablement.

Record: `[Bug description: none — new PCI ID] [Symptom: 0xefa4 adapters
unbound / unused by in-tree efa] [Version info: none] [Root cause: ID
missing from pci_device_id table]`

**Step 1.4: DETECT HIDDEN BUG FIXES**
Not a disguised leak/race/UAF fix. It is exactly a device-ID addition.

Record: `[Not a hidden bug fix. Explicit PCI ID enablement.]`

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
- File: `drivers/infiniband/hw/efa/efa_main.c` — **+2 / -0**
- `#define PCI_DEV_ID_EFA4_VF 0xefa4`
- `{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA4_VF) }` in `efa_pci_tbl[]`
- Scope: single-file surgical ID addition

Record: `[efa_main.c +2] [pci_device_id table] [surgical single-file]`

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Before: PCI core matches Amazon vendor `0x1d0f` with IDs
`0xefa0`–`0xefa3` only. `0xefa4` is ignored (no probe).
After: `0xefa4` matches `efa_pci_driver`, `efa_probe()` runs the same
path as older generations.

`efa_probe(struct pci_dev *pdev, const struct pci_device_id *ent)` does
not use `ent` for generation-specific branching. `vendor_part_id` is
taken from `pdev->device`. Capabilities come from admin query
(`page_size_cap`, etc.).

Record: `[PCI match table: 4 IDs -> 5 IDs; probe path unchanged]`

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Category **(h) Hardware workarounds / device ID additions**. Without the
ID, new EFA VFs never bind.

Record: `[Device ID addition] [Missing 0xefa4 in efa_pci_tbl prevented
driver bind]`

**Step 2.4: ASSESS THE FIX QUALITY**
Obviously correct. Same pattern as `0xefa2` (`b75927cff13e0`) and
`0xefa3` (`346d2fc606a85`). Does not change locking, APIs, or existing-
ID behavior. Regression risk is confined to `1d0f:efa4` hardware.

Record: `[Minimal, obviously correct] [Regression risk: only 0xefa4
devices]`

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
```
efa0/efa1: d4f9cb5c5b224 (Gal Pressman, 2020)
efa2:     b75927cff13e0 (Michael Margolin, 2022) → v6.1-rc4
efa3:     346d2fc606a85 (Michael Margolin, 2024) → present in v6.11 /
v7.2.7
efa4:     6a57af838b1a5 (Anas Mousa, 2026-07-12)
Driver:   b7f5e880f3774 (2019) → v5.2-rc1
```
The table has been the enablement mechanism since the driver was added.

Record: `[ID table since v5.2; this ID added 2026-07-12 / 7.3 merge
window]`

**Step 3.2: FOLLOW THE FIXES: TAG**
No `Fixes:` tag. Not a regression fix.

Record: `[N/A — device ID, not a regression]`

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Same msgid series `20260712134413`:
1. `4266547bdce74` RDMA/efa: Extend page-shift field in MR registration
   (`19226-2`)
2. `6a57af838b1a5` RDMA/efa: Add EFA 0xefa4 PCI ID (`19226-3`) — this
   commit

Cover letter: 2-patch `for-next` series. Patch 1 widens
`EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT_MASK` from `GENMASK(4,0)` to
`GENMASK(5,0)` for **>4GB page sizes** on 0xefa4. That is extra
capability, not required for PCI bind/probe. `efa_probe` does not depend
on that mask.

Record: `[Series of 2; this patch is standalone for bind] [page-shift is
feature, not probe prerequisite]`

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Anas Mousa: this is the only in-tree EFA commit. Reviewed by Michael
Margolin (regular EFA author). Applied by Leon Romanovsky.

Record: `[First-time author; reviewed by EFA regular; applied by RDMA
maintainer]`

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Local tree already has `PCI_DEV_ID_EFA3_VF`, `PCI_VDEVICE(AMAZON, ...)`,
and `efa_pci_tbl`. No new helpers. Companion page-shift commit is
already in this tree (`git merge-base --is-ancestor 4266547bdce74
HEAD`).

Record: `[Applies standalone] [No missing structs/APIs in this tree]`

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
`b4 dig -c 6a57af838b1a5` →
https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com
`b4 dig -a`: **v1 only** (no v2/v3).
Thread saved to mbox (6 messages).

Key review (on patch 1/2, not this ID patch): Leon asked how non-0xefa4
devices handle the extra page-shift bit. Michael: kernel uses device-
reported `page_size_cap` with `ib_umem_find_best_pgsz()`, so the extra
bit is not set on older devices; device also validates. Leon then
**Applied, thanks!** both patches. No NAK on the PCI ID patch. No `Cc:
stable` request.

Record: `[lore via patch.msgid.link/20260712134413.19226-3] [v1 only]
[no NAK on ID patch] [no stable nomination]`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
`b4 dig -w` recipients: `jgg@nvidia.com`, `leon@kernel.org`, `linux-
rdma@vger.kernel.org`, Amazon EFA engineers (`sleybo`, `matua`,
`gal.pressman`). Right lists and maintainers.

Record: `[RDMA maintainers + linux-rdma CC'd; Leon applied]`

**Step 4.3: SEARCH FOR THE BUG REPORT**
No bugzilla/syzbot. External confirmation that 0xefa4 is real hardware:
- DeviceHunt: PCI `1D0F:EFA4` Amazon Elastic Fabric Adapter
- Amazon out-of-tree `efa_linux_3.3.0`: “Add 0xefa4 device support”
- rdma-core: `efa: Add EFA 0xefa4 PCI ID`

Record: `[Real shipping device; userspace + out-of-tree driver already
list the ID]`

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
2/2 of “Add support for 0xefa4 devices”. Evaluating only the ID patch:
self-contained for enumeration. Full >4GB MR pages needs patch 1/2
(already in this tree).

Record: `[Standalone for bind; series mate is optional extra
capability]`

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
lore.kernel.org WebFetch returned 403. `b4 dig` mbox has no stable-list
traffic. No evidence this ID was rejected for stable.

Record: `[No stable-list discussion found (lore HTTP 403; mbox has
none)]`

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
No function body changed. Data: `PCI_DEV_ID_EFA4_VF`, `efa_pci_tbl[]`.
Consumers: `MODULE_DEVICE_TABLE(pci, efa_pci_tbl)` and
`efa_pci_driver.id_table`.

Record: `[efa_pci_tbl / efa_pci_driver only]`

**Step 5.2: TRACE CALLERS**
PCI core `pci_device_probe` → `efa_probe` → `efa_probe_device` /
`efa_ib_device_add`. Userspace-visible once the VF is assigned (typical
AWS EFA instance).

Record: `[PCI enumeration; bind on matching VF]`

**Step 5.3: TRACE CALLEES**
Unchanged. Probe still does BAR map, MSI-X, admin queues, IB register.

Record: `[Probe callees unchanged]`

**Step 5.4: FOLLOW THE CALL CHAIN**
Reachable when `CONFIG_INFINIBAND_EFA` is set (`PCI_MSI && 64BIT &&
!CPU_BIG_ENDIAN && INFINIBAND_USER_ACCESS`) and `1d0f:efa4` is present.
Common on AWS HPC/ML instances, not a syscall fuzzer path.

Record: `[Reachable from device hotplug/boot on EFA instances]`

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Identical ID adds for efa2/efa3. No `switch (pdev->device)` /
`driver_data` generation quirks in `drivers/infiniband/hw/efa/`.

Record: `[Same pattern as prior EFA IDs; no per-ID code]`

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Local tree: **v7.3-rc4-27-gf0100363d8c37**, `make kernelversion` =
**7.3.0-rc4**.
`INFINIBAND_EFA` and `efa_pci_tbl` exist. `0xefa0`–`0xefa3` exist.
Without this change, `0xefa4` would not match.

`git merge-base --is-ancestor 6a57af838b1a5 HEAD` → yes (landed by
**v7.3-rc1**). Not in **v7.2.7**. Introduced in the 7.3 window, not
after this branch point.

Record: `[Driver and ID table present in this 7.3-rc4 tree] [ID added in
7.3-rc1]`

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Hunk is two lines next to `PCI_DEV_ID_EFA3_VF`. Would apply cleanly to
this file’s table. No refactor of the ID table.

Record: `[Expected apply: clean]`

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
No alternate 0xefa4 enablement. This is the only `0xefa4` PCI table
change.

Record: `[No other 0xefa4 bind fix]`

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
`drivers/infiniband/hw/efa/` — Amazon EFA RDMA NIC.
Criticality: **IMPORTANT** for AWS EFA users; **PERIPHERAL** globally.
Not core mm/net.

Record: `[RDMA/efa] [IMPORTANT for EFA hardware, otherwise peripheral]`

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Actively maintained (completion counters, 128B admin SQ, IRQ lifetime
fixes in 2026). ID adds are a long-standing pattern, not a new
subsystem.

Record: `[Active but mature ID-table pattern]`

MAINTAINERS: “AMAZON RDMA EFA DRIVER”.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Users of Amazon EFA VF `1d0f:efa4` with `CONFIG_INFINIBAND_EFA`. Older
EFA IDs unchanged.

Record: `[driver-specific / config-specific (INFINIBAND_EFA)]`

**Step 8.2: TRIGGER CONDITIONS**
Boot or VF assignment of 0xefa4. Not a race. Unprivileged users cannot
trigger a crash; they just get a working RDMA device after bind.

Record: `[Hotplug/boot of 0xefa4] [Likely on new EFA instances] [Not a
UAF/syscall crash]`

**Step 8.3: FAILURE MODE SEVERITY**
Without the ID: device unused by in-tree driver (lost HPC/RDMA). Not
panic/corruption. For affected hardware this is functional breakage.

Record: `[Device not bound] [Severity: HIGH for 0xefa4 users, LOW for
everyone else]`

**Step 8.4: RISK-BENEFIT RATIO**
Benefit: enables real hardware on an existing driver (stable-kernel-
rules explicitly allow this).
Risk: two lines, ID-table only, no API/lock/hot-path change.

Record: `[Benefit: high for EFA 0xefa4] [Risk: very low] [Favorable]`

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- `Documentation/process/stable-kernel-rules.rst`: “must either fix a
  real bug that bothers people **or just add a device ID**.”
- Canonical PCI ID exception: driver already in tree; only the ID is
  new.
- +2 lines, obviously correct, same as efa2/efa3.
- No per-ID branching; probe is generation-agnostic.
- Real device (`1d0f:efa4`); Amazon out-of-tree and rdma-core already
  list it.
- Reviewed and applied by RDMA maintainer Leon Romanovsky.
- Applies cleanly; no new APIs.

AGAINST:
- Not a crash/security/corruption fix (not required for device IDs).
- Submitted as `for-next`, no `Cc: stable` (absence is expected).
- Series mate extends page-shift for >4GB MRs; not needed for bind.
- Author is a first-time in-tree EFA contributor (offset by Margolin
  review + Leon apply).

UNRESOLVED:
- Direct lore.kernel.org HTTP fetches returned 403; thread recovered via
  `b4 dig -m`.
- Stable mailing list search via WebFetch also 403; no stable discussion
  in the rdma mbox.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — 2-line ID table; maintainer
   applied after review.
2. Fixes a real bug that affects users? **PASS** — device ID exception;
   otherwise 0xefa4 never binds.
3. Important issue? **PASS** under the documented device-ID exception
   (not a panic).
4. Small and contained? **PASS** — +2 lines, one file.
5. No new features or APIs? **PASS** — existing driver, new ID only
   (page-shift is a different commit).
6. Can apply to the local tree? **PASS** — `efa_main.c` ID table
   present; hunk matches.

**Step 9.3: EXCEPTION CATEGORY**
**Device ID addition to existing driver** — automatic stable qualifier.

**Step 9.4: DECISION**
This tree is **7.3.0-rc4**. The EFA driver and PCI table are here.
Adding `0xefa4` is the standard, low-risk hardware-enablement backport.
The companion page-shift change is a separate feature and is not
required for this ID patch to be correct.

### What it solves for users of this tree
Without `0xefa4` in `efa_pci_tbl`, new Amazon EFA adapters are invisible
to the in-tree driver. With it, the existing probe path binds them. That
is exactly what stable trees take PCI IDs for.

### Risk vs benefit
Benefit is hardware enablement for EFA 0xefa4. Risk is two lines that
cannot affect other devices.

---

### Verification
- [Phase 1] Parsed commit `6a57af838b1a56405a9bde9030de16df901ae2ca`:
  Reviewed-by Margolin, SOB Anas Mousa + Leon Romanovsky, Link msgid
  `20260712134413.19226-3`
- [Phase 2] Diff: +2 lines in `efa_pci_tbl` / `PCI_DEV_ID_EFA4_VF` only
- [Phase 2] `efa_probe()` does not branch on `ent`/`pdev->device` for
  quirks (verified in `efa_main.c`)
- [Phase 3] `git blame -L 16,29 efa_main.c`: efa0–efa3 older; efa4 is
  this commit
- [Phase 3] Prior IDs: efa2 `b75927cff13e0`, efa3 `346d2fc606a85` — same
  2-line pattern
- [Phase 3] Series mate `4266547bdce74` is page-shift GENMASK only, not
  a probe dependency
- [Phase 4] `b4 dig -c 6a57af838b1a5`: matched lore thread; v1 only
- [Phase 4] `b4 dig -w`: linux-rdma, jgg, leon CC’d
- [Phase 4] mbox: Leon question on patch 1/2 only; both patches applied
  2026-07-14; no NAK on ID patch
- [Phase 4] WebFetch lore/stable: HTTP 403 — UNVERIFIED via HTTP;
  covered by b4 mbox
- [Phase 5] Call path: PCI `id_table` → `efa_probe`; `page_size_cap`
  used in `efa_verbs.c` for MR pages
- [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`; `make
  kernelversion` = 7.3.0-rc4
- [Phase 6] `git merge-base --is-ancestor 6a57af838b1a5 HEAD` = yes; not
  ancestor of `v7.2.7`
- [Phase 6] Driver added `b7f5e880f3774` (v5.2-rc1); present in this
  tree
- [Phase 7] `Documentation/process/stable-kernel-rules.rst` line 15:
  device ID explicitly allowed
- [Phase 8] Failure mode: device not bound on 0xefa4; no panic path
- UNVERIFIED: stable@vger archive contents (HTTP 403)

The change is a contained PCI ID addition to a driver this tree already
ships, which stable policy explicitly accepts.

**YES**

 drivers/infiniband/hw/efa/efa_main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index fdaf88f0122db..b1f3e7ce2c65e 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -17,12 +17,14 @@
 #define PCI_DEV_ID_EFA1_VF 0xefa1
 #define PCI_DEV_ID_EFA2_VF 0xefa2
 #define PCI_DEV_ID_EFA3_VF 0xefa3
+#define PCI_DEV_ID_EFA4_VF 0xefa4
 
 static const struct pci_device_id efa_pci_tbl[] = {
 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA3_VF) },
+	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA4_VF) },
 	{ }
 };
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (4 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 15:08   ` sashiko-bot
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it Sasha Levin
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Zhiwei Zhang, Zhu Yanjun, Leon Romanovsky, Sasha Levin,
	zyjzyj2000, linux-rdma, linux-kernel

From: Zhiwei Zhang <202275009@qq.com>

[ Upstream commit fbbe1d5cd7d400a98afcf337969cfdb808cb198f ]

The IBTA Software Transport Verbs specification requires the QP,
Memory Window and Memory Region for a Bind Memory Window operation
to belong to the same HCA and protection domain.

rxe only checked the QP and MW protection domain for type 2 MWs.
Move the QP/MW PD check to the common bind path and also reject
binding an MW to an MR from a different PD.

Invalid bind requests continue to fail with IB_WC_MW_BIND_ERR.

Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Zhiwei Zhang <202275009@qq.com>
Link: https://patch.msgid.link/tencent_FD4FB25AA4FFA845E63F5AC36CF4A46CDC0A@qq.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4**. This is a small, spec-required PD
isolation check in Soft-RoCE bind, and the buggy path exists in this
tree.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[RDMA/rxe] [Check] Check PDs for memory window binds.**
Completes IBTA C10-72 by validating that QP, MW, and MR share a
protection domain on bind.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- **Reviewed-by:** Zhu Yanjun `<yanjun.zhu@linux.dev>`
- **Signed-off-by:** Zhiwei Zhang `<202275009@qq.com>` (author)
- **Link:** `https://patch.msgid.link/tencent_FD4FB25AA4FFA845E63F5AC36C
  F4A46CDC0A@qq.com`
- **Signed-off-by:** Leon Romanovsky `<leon@kernel.org>` (RDMA
  maintainer)
- No **Fixes:**, **Reported-by:**, **Tested-by:**, **Acked-by:**, **Cc:
  stable**, or syzbot tags (absence of Fixes/Cc-stable is expected for
  this review)
- Pipeline SOBs ignored per instructions

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** IBTA Software Transport Verbs require QP, MW, and MR of a
  Bind Memory Window to be on the same HCA and PD. rxe only compared QP
  vs MW PD, and only for type 2 MWs. It never compared QP/MW vs MR PD.
- **Symptom:** An invalid bind is accepted instead of completing with
  `IB_WC_MW_BIND_ERR`. After bind, the MW can point at an MR from
  another PD.
- **Version info in message:** none
- **Root cause (author):** type-2-only C10-72 check; missing MR PD check

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not disguised. It is an explicit spec/isolation check. The extra
`rxe_mw_pd()` helper use is equivalent to `to_rpd(mw->ibmw.pd)` and is
not a hidden refactor.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/infiniband/sw/rxe/rxe_mw.c` — **+12 / -8** (net +4)
- Function: `rxe_check_bind_mw()`
- Scope: **single-file surgical fix**

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Hunk 1 (type 2 block):** Before, C10-72 `qp->pd !=
  to_rpd(mw->ibmw.pd)` ran only for `IB_MW_TYPE_2`. After, that check is
  removed from the type-2-only block.
- **Hunk 2 (common path):** After type-1/type-2 state checks, **all**
  binds check `qp->pd != rxe_mw_pd(mw)` and fail with `-EINVAL`.
- **Hunk 3 (when MR present):** Before, a non-NULL MR skipped any PD
  comparison. After, `qp->pd != mr_pd(mr)` rejects a cross-PD MR. Zero-
  length/NULL-MR unbind still returns 0 after the QP/MW PD check.
- Path affected: BIND_MW work-request validation (`rxe_bind_mw` →
  `rxe_check_bind_mw`). Failures still become `IB_WC_MW_BIND_ERR` in
  `rxe_do_local_ops()`.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **Logic / correctness + isolation (memory safety via missing PD
check).**
- Broken: `rxe_bind_mw()` looks up MW/MR by key in **device-global**
  pools (`rxe_pool_get_index`), then `rxe_do_bind_mw()` attaches `mw->mr
  = mr`. Remote access in `rxe_resp.c` uses `mw->mr` after
  `rxe_lookup_mw()`, which checks MW PD vs QP PD but **not** the bound
  MR’s PD. `lookup_mr()` does check `mr_pd(mr) != pd`, so the bind path
  was the hole around that check.
- Fix: enforce QP==MW PD for every MW type, and QP==MR PD whenever an MR
  is bound.

Step 2.4: ASSESS THE FIX QUALITY
Record: **Obviously correct and minimal.** Same `-EINVAL` /
`IB_WC_MW_BIND_ERR` policy as existing bind failures. Regression risk is
**low**: only previously illegal cross-PD binds start failing.
`rxe_mw_pd()` / `mr_pd()` already existed on the parent.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: Incomplete C10-72 check came from **`32a577b4c3a9d` (2021-06-07)
“RDMA/rxe: Add support for bind MW work requests”**. Ancestor of
**v5.14** (`git merge-base --is-ancestor` vs v5.13 failed, vs v5.14
succeeded). Bug is long-standing.

Step 3.2: FOLLOW THE FIXES: TAG
Record: **No Fixes: tag.** Buggy commit identified by history as
`32a577b4c3a9d`. That commit **is** an ancestor of this HEAD.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Recent `rxe_mw.c` work includes access-flag and error-path bind
fixes (`425e1c9018fdf`, `5c719d7aef298`). Those do not replace this PD
check. **Standalone**, not `patch X/Y`. No later commits on `rxe_mw.c`
after this one on HEAD.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Zhiwei Zhang has **only this** rxe commit in this history.
Reviewer Zhu Yanjun and applier Leon Romanovsky are established RDMA
reviewers/maintainers.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Parent already has `rxe_mw_pd()` and `mr_pd()` in `rxe_verbs.h`
(`cdd0b85675aec` 2021, `1858d98b83940` 2020). **Applies standalone**
against this tree’s rxe MW code.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- **v1:** https://patch.msgid.link/tencent_88CB6CA0A60CDD53B24EA5E3A865E
  6FF5A0A@qq.com (2026-06-25)
- **v2 (applied):** https://patch.msgid.link/tencent_FD4FB25AA4FFA845E63
  F5AC36CF4A46CDC0A@qq.com (2026-06-26)
- v1→v2: Zhu asked only that the MR-mismatch dbg string say `"attempt to
  bind MW/QP to MR with different PD"` because QP/MW PD is already
  checked. No NAK. v2 applied as-is.
- Leon: “Applied, thanks!” → rdma git `f58ea84a3584d1`

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: Recipients included **Leon Romanovsky**, **Jason Gunthorpe**,
**Zhu Yanjun**, `linux-rdma@vger.kernel.org`. Maintainer-reviewed.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No bugzilla/syzbot/user **Reported-by**. Issue is spec analysis
(C10-72), not a crash report.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Single-patch series. v2 is the committed version.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: **UNVERIFIED.** lore.kernel.org/stable returned Anubis bot-check
(403/challenge). No evidence in the linux-rdma mbox of a stable
nomination or of a reason to withhold it.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `rxe_check_bind_mw()` only. Callers/callees: `rxe_bind_mw()`,
`rxe_do_bind_mw()`, `rxe_do_local_ops()`, `rxe_lookup_mw()`.

Step 5.2: TRACE CALLERS
Record:
- `rxe_bind_mw()` ← `rxe_do_local_ops()` on `IB_WR_BIND_MW`
  (`rxe_req.c`)
- Userspace QPs: `rxe_post_send()` only schedules `send_task`; WQEs
  (including `mw_rkey`/`mr_lkey` in `include/uapi/rdma/rdma_user_rxe.h`)
  are written by userspace into the SQ. **Unprivileged RDMA userspace
  can post BIND_MW with arbitrary keys.**

Step 5.3: TRACE CALLEES
Record: Debug prints and PD helpers only. No alloc/lock changes. Bind
still runs under `spin_lock_bh(&mw->lock)`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: userspace BIND_MW → requester local op → `rxe_bind_mw` (global
pool lookup by key) → `rxe_do_bind_mw` (`mw->mr = mr`) → later RDMA to
MW rkey in `rxe_resp.c` uses `mw->mr` **without** `lookup_mr()`’s PD
check. **Userspace-reachable isolation hole.**

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: `lookup_mr()` already requires `mr_pd(mr) == pd`.
`rxe_lookup_mw()` already requires `rxe_mw_pd(mw) == pd`. Bind was the
inconsistent path. No sibling rxe function needs the same change.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes, in this 7.3 line.** `git describe HEAD` =
`v7.3-rc4-27-gf0100363d8c37`; `make kernelversion` = `7.3.0-rc4`. MW
bind exists since v5.14. Pre-fix `rxe_check_bind_mw` (parent of
`fbbe1d5cd7d40`) had type-2-only QP/MW PD check and no MR PD check. This
commit is an ancestor of HEAD (landed by v7.3-rc1; not in v7.2).
Evaluating **this** checkout, the rxe MW bind code is present and the
fix matches the local file (no later `rxe_mw.c` deltas).

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Clean apply** on this tree. Helpers and function layout match.
`git diff fbbe1d5 HEAD -- drivers/infiniband/sw/rxe/rxe_mw.c` is empty.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: Access-check and error-path bind fixes are already here; they do
**not** implement C10-72 for type 1 or MR PD. No alternate PD-bind fix.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **RDMA software RoCE (`drivers/infiniband/sw/rxe`)**,
`CONFIG_RDMA_RXE`. **IMPORTANT** (not core mm/VFS): Soft-RoCE is a real
verbs provider; PD is the IB isolation primitive. Not staging.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature. MW bind from 2021; ongoing small correctness fixes. Not
a brand-new subsystem on this branch.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Config/driver-specific:** users of Soft-RoCE
(`CONFIG_RDMA_RXE`) who use memory windows. Multi-PD or multi-process
sharing one rxe device is the interesting case.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Post `IB_WR_BIND_MW` with MW/MR keys from another PD. Userspace
can do that; keys are `index << 8 | u8` (`rxe_get_next_key()`). Trigger
is **intentional/malicious or buggy app**, not every bind. Unprivileged
verbs users **can** trigger it.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: **Not a crash.** Invalid bind **succeeds**, then RDMA through
the MW rkey can touch another PD’s registered memory. **Severity: HIGH**
(isolation/security), not panic/deadlock.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit: high** for rxe MW users — closes a PD bypass around
  `lookup_mr()`.
- **Risk: very low** — ~12 lines, validation-only, same error code, no
  API/lock/structure change.
- **Ratio:** favor applying.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
**FOR:**
- Real IBTA C10-72 hole, not style
- Userspace-reachable via mapped SQ BIND_MW + global key lookup
- After bind, `mw->mr` is used without MR PD check → isolation bypass
- Tiny, obviously correct; maintainer applied; one-line v2 log tweak
  only
- Helpers already in this tree; applies cleanly
- Bug since v5.14 MW bind support

**AGAINST:**
- No crash/syzbot/CVE/user report
- rxe is not mlx5-class hardware; fewer production hosts
- Could be framed as spec hardening

**UNRESOLVED:**
- Whether stable@ already discussed this (lore/stable blocked)
- No public reproducer beyond code-path analysis (verified in-tree)

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — reviewed, v2 applied by
   Leon; logic matches existing checks
2. Fixes a real bug that affects users? **PASS** — invalid binds
   succeed; PD isolation not enforced on bind
3. Important (crash/security/corruption/deadlock)? **PASS** — PD bypass
   / unauthorized MR attach; HIGH isolation, not a panic
4. Small and contained? **PASS** — one function, +12/-8
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — file and helpers match; no
   rewrite needed

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None (not a device ID, quirk, DT, build, or docs-only change).
Qualifies as a normal bugfix.

Step 9.4: MAKE YOUR DECISION
This should be in this tree: it closes a long-standing Soft-RoCE bind
isolation gap with a few lines of PD checks, no API change, and
negligible regression risk. Missing crash reports does not make a
skipped PD check “theoretical” when userspace supplies the keys and the
data path then uses `mw->mr`.

Verification:
- [Phase 1] Tags: Reviewed-by Zhu Yanjun; SOB Zhiwei Zhang; Link msgid;
  SOB Leon; no Fixes/Reported-by/syzbot
- [Phase 1] Body: C10-72 QP/MW/MR same PD; type-2-only check;
  `IB_WC_MW_BIND_ERR`
- [Phase 2] Diff: `rxe_check_bind_mw` +12/-8; common QP/MW PD check; new
  QP vs `mr_pd(mr)`
- [Phase 2] Parent code: C10-72 only under `IB_MW_TYPE_2`; no MR PD
  check
- [Phase 2] `rxe_do_local_ops`: bind failure → `IB_WC_MW_BIND_ERR`
  (verified `rxe_req.c`)
- [Phase 3] `git describe HEAD` / `make kernelversion`: v7.3-rc4 /
  7.3.0-rc4
- [Phase 3] `git merge-base --is-ancestor fbbe1d5 HEAD` → yes; vs v7.2 →
  no; vs v7.3-rc1 → yes
- [Phase 3] Buggy intro `32a577b4c3a9d` is ancestor of v5.14, not v5.13
- [Phase 3] Parent has `rxe_mw_pd` / `mr_pd` in `rxe_verbs.h`
- [Phase 3] Author: only this rxe commit; not a series
- [Phase 4] `b4 dig -c fbbe1d5`: v2 msgid tencent_FD4FB25…; v1
  tencent_88CB6CA0…
- [Phase 4] v1 review: Zhu requested dbg string only; Reviewed-by; no
  NAK
- [Phase 4] Leon applied to rdma tree; no stable nomination in that mbox
- [Phase 4] lore.kernel.org WebFetch 403; stable/? search hit Anubis —
  UNVERIFIED on stable@
- [Phase 5] Call chain: user SQ BIND_MW → `rxe_bind_mw` global pool
  lookup → `mw->mr` → `rxe_resp.c` uses `mw->mr` without `lookup_mr()`
  PD check
- [Phase 5] `lookup_mr()` already has `mr_pd(mr) != pd` (verified
  `rxe_mr.c:713-716`)
- [Phase 5] Userspace WQE fields `mr_lkey`/`mw_rkey` in
  `rdma_user_rxe.h`; `rxe_post_send` does not copy/validate them for
  user QPs
- [Phase 6] `git diff fbbe1d5 HEAD -- rxe_mw.c` empty; clean on this
  tree
- [Phase 8] Keys: `index << 8 | rxe_get_next_key()` (8-bit key);
  isolation severity HIGH
- UNVERIFIED: stable@ history; no in-tree test/reproducer for cross-PD
  bind

**YES**

 drivers/infiniband/sw/rxe/rxe_mw.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
index 379e65bfcd49a..bddb7a2578313 100644
--- a/drivers/infiniband/sw/rxe/rxe_mw.c
+++ b/drivers/infiniband/sw/rxe/rxe_mw.c
@@ -72,13 +72,6 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
 			return -EINVAL;
 		}
 
-		/* C10-72 */
-		if (unlikely(qp->pd != to_rpd(mw->ibmw.pd))) {
-			rxe_dbg_mw(mw,
-				"attempt to bind type 2 MW with qp with different PD\n");
-			return -EINVAL;
-		}
-
 		/* o10-37.2.40 */
 		if (unlikely(!mr || wqe->wr.wr.mw.length == 0)) {
 			rxe_dbg_mw(mw,
@@ -87,10 +80,21 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
 		}
 	}
 
-	/* remaining checks only apply to a nonzero MR */
+	/* C10-72 */
+	if (unlikely(qp->pd != rxe_mw_pd(mw))) {
+		rxe_dbg_mw(mw, "attempt to bind MW with qp with different PD\n");
+		return -EINVAL;
+	}
+
 	if (!mr)
 		return 0;
 
+	/* remaining checks only apply to a nonzero MR */
+	if (unlikely(qp->pd != mr_pd(mr))) {
+		rxe_dbg_mw(mw, "attempt to bind MW/QP to MR with different PD\n");
+		return -EINVAL;
+	}
+
 	if (unlikely(mr->access & IB_ZERO_BASED)) {
 		rxe_dbg_mw(mw, "attempt to bind MW to zero based MR\n");
 		return -EINVAL;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (5 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 15:15   ` sashiko-bot
  6 siblings, 1 reply; 15+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Håkon Bugge, Allison Henderson, Jakub Kicinski, Sasha Levin,
	davem, edumazet, pabeni, netdev, linux-rdma, rds-devel,
	linux-kernel

From: Håkon Bugge <haakon.bugge@oracle.com>

[ Upstream commit 9079adef042c1e7a6141dcdfd3041acd30607297 ]

Each rds_mr stores a bare back pointer to the socket that created it
(mr->r_sock) but takes no reference on it.  When the mr is destroyed it
references the rs. Hence, provisions must be made to avoid the rs
being destroyed before all mrs referencing it have been destroyed.

The MR itself is refcounted, and in-flight messages legitimately hold
MR krefs that can outlive the socket: rds_release() drops the rb-tree
references via rds_rdma_drop_keys(), but a send completion arriving
afterwards drops the final message reference from the CQ handler and
ends up in

  rds_message_purge()
    __rds_put_mr_final()
      rds_destroy_mr()   -> takes rs->rs_rdma_lock

dereferencing a socket that may already have been freed.

Oracle UEK fixed the same use-after-free ("rds: Add proper refcnt when
an RDS MR references an RDS Socket") after seeing crashes of the form:

  PF: supervisor write access in kernel mode
  _raw_spin_lock_irqsave+0x4a/0x6a
  __rds_put_mr_final+0x2c/0xe0 [rds]
  rds_message_purge+0x13c/0x150 [rds]
  rds_message_put+0x39/0x54 [rds]
  rds_ib_send_cqe_handler+0x147/0x3dd [rds_rdma]

To fix this, take a socket reference when an MR is created and drop it
when the final MR kref goes away.  The reference cycle is broken by
rds_release(), which always runs rds_rdma_drop_keys() on close.  So the
socket reference held by an MR never prevents release, it only delays
sk_free() until the last MR user is done.

The hold sits next to kref_init() at both allocation sites -
__rds_rdma_map() and the on-demand-paging path in
rds_cmsg_rdma_args() - so every MR owns exactly one socket reference
from the moment it becomes kref-managed.  For that to work on the ODP
path, its get_mr() error handling is converted from a bare kfree() to
kref_put(..., __rds_put_mr_final), with r_trans_private cleared first
since it holds an ERR_PTR there; both sites then tear down through
the same path and a future error-path change cannot silently leak or
double-drop the reference.

Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
[achender: port to net-next (sock_hold/sock_put in place of the UEK
 rds_sock_addref/rds_sock_put helpers); also balance the reference on
 the rds_cmsg_rdma_args() ODP path and unify its error path with
 __rds_put_mr_final(); update commit message]
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260730041629.3512480-3-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:

This is a use-after-free in RDS MR teardown. The buggy path is in this
5.10 tree, the fix is small, and it should be backported.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[net/rds] [hold] hold the socket while an rds_mr references
it**
- Subsystem: `net/rds`
- Action verb: “hold” (keep a missing reference so the socket outlives
  the MR)
- Claimed intent: an `rds_mr` keeps a counted socket reference for its
  lifetime

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record (from the candidate / merged `9079adef042c`):
- **Fixes:** absent in the git commit. The v4 mailing-list post had
  `Fixes: eff5f53bef75 ("RDS: RDMA support")`. Absence in git is
  expected here and is not a negative.
- **Reported-by:** none. The body cites an Oracle UEK production crash.
- **Tested-by:** none
- **Reviewed-by / Acked-by:** none on the commit
- **Link:** `https://patch.msgid.link/20260730041629.3512480-3-
  achender@kernel.org`
- **Cc: stable:** absent (expected)
- **Signed-off-by:** Håkon Bugge (Oracle, original); Allison Henderson
  (RDS, port); Jakub Kicinski (net maintainer, merge)
- Notable: Allison’s trailer says this is a UEK port
  (`sock_hold`/`sock_put` instead of UEK
  `rds_sock_addref`/`rds_sock_put`). This tree already has those helpers
  as thin wrappers around `sock_hold`/`sock_put`.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** `mr->r_sock` is a bare back-pointer. `rds_destroy_mr()` takes
  `rs->rs_rdma_lock` after the socket may already be freed.
- **Symptom:** kernel oops: `PF: supervisor write access` in
  `_raw_spin_lock_irqsave` from `__rds_put_mr_final` ←
  `rds_message_purge` ← `rds_message_put` ← `rds_ib_send_cqe_handler`.
- **Root cause:** `rds_release()` drops rb-tree MR refs via
  `rds_rdma_drop_keys()`, but in-flight send completions still hold MR
  krefs. The CQ/tasklet path then destroys the MR against a freed
  socket.
- **Version info:** none beyond “Oracle UEK saw this.” The mechanism is
  as old as RDS RDMA (2009).
- **Fix:** `sock_hold()` at both MR alloc sites next to `kref_init()`;
  `sock_put()` in `__rds_put_mr_final()`. Cycle is broken because
  `rds_release()` always runs `rds_rdma_drop_keys()`, so the MR ref only
  delays `sk_free()`, it does not block `release`.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not disguised. Explicit UAF fix with a crash stack. The ODP
`kfree` → `kref_put` change is part of making the hold/put pairing
correct on the error path.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- `net/rds/rdma.c`: +13 / −1 (functional)
- `net/rds/rds.h`: +4 / −1 (comment on `r_sock`)
- **Functions:** `__rds_put_mr_final()`, `__rds_rdma_map()`,
  `rds_cmsg_rdma_args()`
- **Scope:** single-subsystem, surgical (~17 lines)

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **`__rds_put_mr_final`:** after `rds_destroy_mr(mr)`, add
  `sock_put(rds_rs_to_sk(mr->r_sock))` before `kfree(mr)`.
- **`__rds_rdma_map`:** after `mr->r_sock = rs`, add `sock_hold()`. This
  tree already `kref_put`s `mr` on every `out:` path (success and
  error), so the hold is paired.
- **ODP path in `rds_cmsg_rdma_args`:** `sock_hold()` next to
  `kref_init()`. On `get_mr()` failure, clear `r_trans_private` (it is
  an `ERR_PTR`) and `kref_put(..., __rds_put_mr_final)` instead of a
  bare `kfree`, so `free_mr()` is not called with an error pointer and
  the socket ref is dropped.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- **Category:** use-after-free / missing reference count
- **Mechanism:** MR outlives socket; destructor uses `rs->rs_rdma_lock`.
  Fix is one `sock_hold` per kref-managed MR, one `sock_put` on final
  kref.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: classic missing get/put; both alloc sites covered
  (only two `kref_init` of `rds_mr` in `net/rds/`).
- `__rds_rdma_map` already uses `kref_put` on `out:`; ODP error path is
  converted to the same destructor.
- Regression risk is low. `sock_put` from the send tasklet is already
  done in `rds_message_purge()` for `rm->m_rs`. `rds_sock_destruct()` is
  only a `WARN_ON` on an empty list.
- No API or data-structure layout change beyond a comment.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- `mr->r_sock = rs` and `rds_destroy_mr()` using that pointer:
  `eff5f53bef75` (“RDS: RDMA support”), 2009-02-26. Present in 5.10.
- `__rds_put_mr_final` / `kref_init`: `e228a5d05e9ee` (2020-04-09), in
  this tree.
- ODP alloc in `rds_cmsg_rdma_args`: `2eafa1746f178` (2020-01-18), in
  this tree.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` on the git commit. Mailing-list tag `eff5f53bef75`
**is** an ancestor of HEAD (`git merge-base --is-ancestor` exit 0).
Merged mainline SHA `9079adef042c` is **not** an ancestor of this tree
(exit 1). No later sock-hold-on-MR commit exists in this tree.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- `91a44b406bc1f` (“net: rds: fix MR cleanup on copy error”) is already
  here; it only stops double-free of pages/sg on `put_user` failure. It
  does not hold the socket.
- `2fabef4f65b46` (“Fix MR reference counting problem”) is about
  `rds_free_mr()` bypassing kref, not socket lifetime.
- This patch is standalone vs those.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Håkon Bugge has multiple RDS commits in this history. Allison
Henderson is the RDS maintainer and ported the UEK fix. The original
crash was seen in Oracle production.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Submitted as **v4 2/4**. Siblings:
1. `d100966325f7` — don’t `unpin_user_pages_dirty_lock()` from atomic
   context
3. message leak in `rds_send_xmit()` drop path
4. unpin MR pages with `unpin_user_pages_dirty_lock()`
Those are separate bugs. This diff only needs `sock_hold`/`sock_put`,
`kref_put`, and `__rds_put_mr_final`, all present here. **Can apply
standalone.**

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c 9079adef042c`: v4 2/4,
  https://patch.msgid.link/20260730041629.3512480-3-achender@kernel.org
- Revisions: v1 (2026-07-10), v2, v3 (ODP hold after successful
  `get_mr`), v4 (hold next to `kref_init`, error path via
  `__rds_put_mr_final`) — applied version is v4.
- Cover letter: explicit UAF of the RDS socket through long-lived MR
  refs; UEK port https://github.com/oracle/linux-uek/commit/94549e4732d8
- No NAK found on this patch. Jakub applied the series to net-next on
  2026-08-04 (`9079adef042c`).
- v4 changelog: ODP ref moved next to `kref_init` so both alloc sites
  share one ownership rule.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): netdev, linux-rdma, Paolo Abeni, Eric Dumazet,
Jakub Kicinski, Simon Horman, John Hubbard, Leon Romanovsky. Applied by
the net maintainer. No NAK located.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla link. Evidence is the UEK oops in the commit
message, matching this tree’s call chain (`rds_ib_tasklet_fn_send` →
`rds_ib_send_cqe_handler` → `rds_message_put` → `rds_message_purge` →
`__rds_put_mr_final`).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: 4 independent RDS bug-fix ports. This one does not need 1/3/4.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: **UNVERIFIED** — `lore.kernel.org/stable` fetch returned 403. No
local evidence this was rejected for 5.10.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `__rds_put_mr_final`, `__rds_rdma_map`, `rds_cmsg_rdma_args`
(plus `rds_destroy_mr` as callee).

Step 5.2: TRACE CALLERS
Record:
- `__rds_put_mr_final`: `kref_put` from `rds_rdma_drop_keys`,
  `rds_free_mr`, `rds_rdma_unuse`, `rds_rdma_free_op` (ODP),
  `rds_message_purge` (`op_rdma_mr` / atomic MR), and `__rds_rdma_map`
  `out:`.
- `__rds_rdma_map`: `rds_get_mr`, `rds_get_mr_for_dest`,
  `rds_cmsg_rdma_map` (sendmsg cmsg). Userspace RDMA registration.
- `rds_cmsg_rdma_args`: `rds_sendmsg` path for `RDS_CMSG_RDMA_ARGS`.

Step 5.3: TRACE CALLEES
Record: `rds_destroy_mr` → `spin_lock_irqsave(&rs->rs_rdma_lock)` (the
UAF); `free_mr()`; `sock_hold`/`sock_put`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Userspace maps an MR or sends RDMA, then closes the socket while
a send is in flight. Completions run in `rds_ib_tasklet_fn_send`
(softirq). Reachable from AF_RDS sockets with `CONFIG_RDS` +
`CONFIG_RDS_RDMA` (InfiniBand). Typical Oracle RAC / IB RDS workload.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Only two `kref_init` sites for `struct rds_mr`. Both patched.
`rds_cmsg_rdma_dest` only `kref_get`s an existing tree MR.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.**
- Tree: `pending-5.10`, `5.10.270` (`p-5.10-1-gce56b7a73b64b`)
- `net/rds/rdma.c`: `mr->r_sock = rs` with no `sock_hold` (lines 243–246
  and 735–738)
- `__rds_put_mr_final` has no `sock_put` (115–121)
- `rds_release()` still does `rds_rdma_drop_keys()` then `sock_put(sk)`
  (`af_rds.c`)
- Introduced 2009; ODP path 2020. Both in 5.10.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Minor context only.** Mainline uses `kzalloc_obj` /
`kzalloc_objs`; this tree uses `kzalloc` / `kcalloc`. The hold/put lines
sit on identical `kref_init` / `mr->r_sock` / ODP `get_mr` error code.
Local ODP error uses `ret = IS_ERR(...)` then overwrites with
`-EOPNOTSUPP`; the patch uses `PTR_ERR` then the same overwrite.
Semantic apply is straightforward.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: No socket-hold-on-MR fix. `91a44b406bc1f` is a different MR
cleanup bug.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **net/rds** — IMPORTANT, not core. RDS over IB is production for
Oracle RAC and similar clusters. UAF is still a kernel oops for those
users.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature (2009). Occasional stable fixes in this tree
(`91a44b406bc1f` in 2026). Not a new subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **config/driver-specific:** `CONFIG_RDS` + RDMA
(`CONFIG_RDS_RDMA`). Not all 5.10 boxes, but all RDS/IB RDMA users who
close a socket with in-flight MRs.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Map MR or send RDMA, close socket before CQ completion. Timing-
dependent but realistic (UEK crash). Needs an RDS socket; typical RDS
users are cluster services.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: **Use-after-free → oops on spinlock of freed `rds_sock`.**
Severity **CRITICAL/HIGH**. Same class as KASAN UAF; crash stack is
real.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for RDS/IB — prevents a known UAF oops.
- **Risk:** low — ~17 lines, standard `sock_hold`/`sock_put`, both alloc
  sites, error path unified.
- **Ratio:** strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
**FOR:**
- Real UAF with production oops (Oracle UEK).
- Same call path exists in this 5.10 tree.
- Bug dates to 2009 RDMA support; ODP path also here.
- Small, obviously correct refcount fix; v4 review then net-maintainer
  merge.
- Standalone vs the rest of the series.
- `__rds_rdma_map` already drops the MR via `kref_put` on all exits, so
  the new hold is balanced.

**AGAINST:**
- RDS/IB is not universal.
- Patch was 2/4 of a series (siblings are independent).
- Minor `kzalloc_obj` vs `kzalloc` context when applying.

**UNRESOLVED:**
- Stable-list discussion (lore 403).
- No public syzbot repro (crash is still documented).

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — hold at `kref_init`, put in
   finalizer; merged to net-next; UEK precedent.
2. Fixes a real bug that affects users? **PASS** — production oops.
3. Important issue? **PASS** — UAF / kernel oops, HIGH/CRITICAL.
4. Small and contained? **PASS** — 2 files, ~17 lines.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — buggy code present; minor
   context only.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary memory-
safety fix.

Step 9.4: MAKE YOUR DECISION
This 5.10 tree has the bare `r_sock` pointer, the CQ/tasklet free path,
and no socket hold on MRs. The fix is the missing refcount. It should be
backported.

===============================================================
What this solves for stable users
===============================================================
Closing an RDS socket while an RDMA MR is still referenced by an in-
flight send can free `rds_sock` before `__rds_put_mr_final` →
`rds_destroy_mr` takes `rs->rs_rdma_lock`. That is an oops. Holding the
socket until the last MR kref drops keeps the lock valid;
`rds_rdma_drop_keys()` in `rds_release()` still breaks the tree↔socket
cycle.

Risk vs benefit: high benefit for RDS/IB, low regression risk.
`sock_put` from this tasklet is already used for `rm->m_rs`. Backport
may need trivial context adjustment (`kzalloc` vs `kzalloc_obj`); no
missing helpers or types.

Verification:
- [Phase 1] Tags: Link msgid `20260730041629.3512480-3`; SOB Bugge /
  Henderson / Kicinski; no Fixes in git; ML had `Fixes: eff5f53bef75`
- [Phase 2] Diff: `sock_put` in `__rds_put_mr_final`; `sock_hold` in
  `__rds_rdma_map` and ODP alloc; ODP error `kfree` → `kref_put` after
  NULL-out of `ERR_PTR`
- [Phase 2] Local `__rds_rdma_map` `out:` already `kref_put`s if `mr`
  non-NULL (`rdma.c` 348–351)
- [Phase 3] `git blame`: `r_sock` / `rds_destroy_mr` from `eff5f53bef75`
  (2009); kref from `e228a5d05e9ee` (2020)
- [Phase 3] `git merge-base --is-ancestor eff5f53bef75c0 HEAD` → 0;
  `2eafa1746f178` → 0; `9079adef042c` → 1 (not in this tree)
- [Phase 3] `git describe HEAD` / `make kernelversion`: pending-5.10,
  5.10.270
- [Phase 3] Only two `kref_init(&...r_kref)` sites in `net/rds/`
- [Phase 4] `b4 dig -c 9079adef042c`: v4 2/4; recipients
  netdev/rdma/Kicinski/Dumazet/Abeni/Horman
- [Phase 4] `b4 dig -a`: v1→v4; v4 unifies ODP error path
- [Phase 4] Cover letter: UEK UAF port; applied as `9079adef042c`
- [Phase 4] UNVERIFIED: stable@ thread (403)
- [Phase 5] Call chain confirmed: `rds_ib_tasklet_fn_send` →
  `rds_ib_send_cqe_handler` → `rds_message_put` → `rds_message_purge` →
  `__rds_put_mr_final`
- [Phase 5] `rds_release` calls `rds_rdma_drop_keys` then `sock_put`
  (`af_rds.c` 78, 89)
- [Phase 6] Local `rdma.c` has no `sock_hold`/`sock_put`; comment still
  says “back pointer”
- [Phase 8] Failure mode: UAF oops on `rs_rdma_lock`, HIGH/CRITICAL
- UNVERIFIED: whether an unprivileged process can open AF_RDS on a given
  distro; crash still confirmed for RDS/IB users

**YES**

 net/rds/rdma.c | 14 +++++++++++++-
 net/rds/rds.h  |  5 ++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 37695056756be..062c12d9318e9 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -117,6 +117,7 @@ void __rds_put_mr_final(struct kref *kref)
 	struct rds_mr *mr = container_of(kref, struct rds_mr, r_kref);
 
 	rds_destroy_mr(mr);
+	sock_put(rds_rs_to_sk(mr->r_sock));
 	kfree(mr);
 }
 
@@ -243,7 +244,11 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 	kref_init(&mr->r_kref);
 	RB_CLEAR_NODE(&mr->r_rb_node);
 	mr->r_trans = rs->rs_transport;
+	/* The MR can outlive its socket: a socket reference is held
+	 * until the final kref is dropped in __rds_put_mr_final().
+	 */
 	mr->r_sock = rs;
+	sock_hold(rds_rs_to_sk(rs));
 
 	if (args->flags & RDS_RDMA_USE_ONCE)
 		mr->r_use_once = 1;
@@ -762,7 +767,12 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
 			RB_CLEAR_NODE(&local_odp_mr->r_rb_node);
 			kref_init(&local_odp_mr->r_kref);
 			local_odp_mr->r_trans = rs->rs_transport;
+			/* The MR can outlive its socket: a socket
+			 * reference is held until the final kref is
+			 * dropped in __rds_put_mr_final().
+			 */
 			local_odp_mr->r_sock = rs;
+			sock_hold(rds_rs_to_sk(rs));
 			local_odp_mr->r_trans_private =
 				rs->rs_transport->get_mr(
 					NULL, 0, rs, &local_odp_mr->r_key, NULL,
@@ -771,7 +781,9 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
 				ret = PTR_ERR(local_odp_mr->r_trans_private);
 				rdsdebug("get_mr ret %d %p\"", ret,
 					 local_odp_mr->r_trans_private);
-				kfree(local_odp_mr);
+				local_odp_mr->r_trans_private = NULL;
+				kref_put(&local_odp_mr->r_kref,
+					 __rds_put_mr_final);
 				ret = -EOPNOTSUPP;
 				goto out_pages;
 			}
diff --git a/net/rds/rds.h b/net/rds/rds.h
index a4816da162930..dcbc4610735d5 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -299,7 +299,10 @@ struct rds_mr {
 	unsigned int		r_invalidate:1;
 	unsigned int		r_write:1;
 
-	struct rds_sock		*r_sock; /* back pointer to the socket that owns us */
+	struct rds_sock		*r_sock; /* socket that owns us; counted
+					  * reference, dropped by
+					  * __rds_put_mr_final()
+					  */
 	struct rds_transport	*r_trans;
 	void			*r_trans_private;
 };
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error Sasha Levin
@ 2026-10-19 14:00   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 14:00 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Seyeong Kim <seyeong.kim@canonical.com>
> 
> [ Upstream commit 4dc9c884c0aafac1e8d37536d88d485135e26883 ]
> 
> The irdma driver currently issues an unconditional PF reset whenever the
> HMC Error interrupt (PFINT_OICR bit 26) fires:
> 
> 	if (event->reg & IRDMAPFINT_OICR_HMC_ERR_M) {
> 		ibdev_err(&iwdev->ibdev, "HMC Error\n");
> 		iwdev->rf->reset = true;
> 	}
> 
> request_reset() issues an IIDC_PFR to ice. In practice a single HMC_ERR
> can trigger cascading PF resets, IOMMU faults during teardown, and
> teardown of every RDMA connection on the device.
> 
> i40e handles the identically-named interrupt by reading
> PFHMC_ERRORINFO and PFHMC_ERRORDATA and logging them without touching
> device state; see commit 9c010ee0ea5f ("i40e: Suppress HMC error to
> Interrupt message level") which removed the reset as "not necessary".
> This patch mirrors that handling on irdma.
> 
> With this change, repeated HMC_ERR no longer produces a reset storm and
> RDMA traffic on the device continues uninterrupted.
> 
> Signed-off-by: Seyeong Kim <seyeong.kim@canonical.com>
> Link: https://patch.msgid.link/20260619050044.1807044-1-seyeong.kim@canonical.com
> Signed-off-by: Leon Romanovsky <leon@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-6-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context
  2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context Sasha Levin
@ 2026-10-19 14:07   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 14:07 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Allison Henderson <achender@kernel.org>
> 
> [ Upstream commit d100966325f782aa7775e5f0e8fb04f66f56308e ]
> 
> rds_rdma_free_op() and rds_atomic_free_op() are reached from the IB
> send completion path via
> 
>   rds_ib_tasklet_fn_send()
>     rds_ib_send_cqe_handler()
>       rds_message_put()
>         rds_message_purge()
>           rds_rdma_free_op() / rds_atomic_free_op()
> 
> which runs in tasklet (softirq) context.  Both functions unpin the
> user pages of the op with unpin_user_pages_dirty_lock(), which uses
> [ ... ]
> 
> Signed-off-by: Allison Henderson <achender@kernel.org>
> Link: https://patch.msgid.link/20260730041629.3512480-2-achender@kernel.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-8-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock()
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock() Sasha Levin
@ 2026-10-19 14:32   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 14:32 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Allison Henderson <achender@kernel.org>
> 
> [ Upstream commit a507023e6ff1d0b4e7aac49b2f547fed0c21ea4e ]
> 
> The pages backing an RDS memory region are pinned in __rds_rdma_map()
> with rds_pin_pages(), which uses pin_user_pages_fast(): each page's
> refcount is biased by GUP_PIN_COUNTING_BIAS to account the pin.  The
> scatterlist is then handed to the IB transport, and the transport
> releases the pages in __rds_ib_teardown_mr() with
> 
> 	set_page_dirty(page);
> 	put_page(page);
> 
> put_page() drops a single reference instead of removing the pin bias,
> so every MR teardown permanently strands the remaining references and
> [ ... ]
> 
> Signed-off-by: Allison Henderson <achender@kernel.org>
> Link: https://patch.msgid.link/20260730041629.3512480-5-achender@kernel.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-172-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path Sasha Levin
@ 2026-10-19 14:47   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 14:47 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Sharath Srinivasan <sharath.srinivasan@oracle.com>
> 
> [ Upstream commit eb8a59a17f4a8b6f2afb4a8063e99dd96cc3fab0 ]
> 
> When rds_send_xmit() picks the next message off cp_send_queue it takes
> its own reference with rds_message_addref().  If the message then hits
> the never-retransmit check (RDS_MSG_FLUSH, or an RDMA op that was
> already retransmitted), it is moved to the local to_be_dropped list and
> that reference is dropped after the batch.
> 
> However, if RDS_MSG_ON_CONN has already been cleared, the message is
> not added to to_be_dropped and the reference taken above is never
> dropped: cp_xmit_rm has not been set at this point, so the loop simply
> abandons rm and the rds_message (and everything it pins: pages, MRs,
> notifiers) leaks after an RDMA error.
> [ ... ]
> [achender: port to net-next; update commit message, checkpatch nits]
> Signed-off-by: Allison Henderson <achender@kernel.org>
> Link: https://patch.msgid.link/20260730041629.3512480-4-achender@kernel.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-258-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID Sasha Levin
@ 2026-10-19 15:05   ` sashiko-bot
  2026-10-19 15:09   ` Michael Margolin
  1 sibling, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 15:05 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] RDMA/efa: broken >=4GB MR registration on 0xefa4 in efa_register_mr()
- [High] RDMA/efa: missing AH cache in efa_com_create_ah() for 0xefa4 devices
--

commit b286b983be1758d745ca136c6fbfaf1703d09edf
Author: Anas Mousa <anasmous@amazon.com>

RDMA/efa: Add EFA 0xefa4 PCI ID

This commit adds the PCI device ID 0xefa4 (PCI_DEV_ID_EFA4_VF) to
efa_pci_tbl so the EFA driver can bind to 0xefa4 devices.

Link: https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com

> diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
> index 6c415b9adb5fe..460d77d965057 100644
> --- a/drivers/infiniband/hw/efa/efa_main.c
> +++ b/drivers/infiniband/hw/efa/efa_main.c
> @@ -17,12 +17,14 @@
>  #define PCI_DEV_ID_EFA1_VF 0xefa1
>  #define PCI_DEV_ID_EFA2_VF 0xefa2
>  #define PCI_DEV_ID_EFA3_VF 0xefa3
> +#define PCI_DEV_ID_EFA4_VF 0xefa4
>  
>  static const struct pci_device_id efa_pci_tbl[] = {
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA3_VF) },
> +	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA4_VF) },

[Severity: High]
Does enabling PCI_DEV_ID_EFA4_VF in efa_pci_tbl break memory region
registration when a page size of 4GB or larger (page_shift >= 32) is
selected on 0xefa4 devices?

When 0xefa4 devices advertise >= 4GB page sizes in dev_attr.page_size_cap
and a consumer registers a large memory region via efa_register_mr(), the
64-bit unsigned long return value of ib_umem_find_best_pgsz() is stored in
a 32-bit unsigned int pg_sz:

drivers/infiniband/hw/efa/efa_verbs.c:efa_register_mr() {
	unsigned int pg_sz;
	...
	pg_sz = ib_umem_find_best_pgsz(mr->umem,
				       dev->dev_attr.page_size_cap,
				       virt_addr);
	if (!pg_sz) {
		ibdev_dbg(&dev->ibdev, "Failed to find a suitable page size in page_size_cap %#llx\n",
			  dev->dev_attr.page_size_cap);
		return -EOPNOTSUPP;
	}

	params.page_shift = order_base_2(pg_sz);
}

When ib_umem_find_best_pgsz() selects a power-of-two page size >= 4GB,
assigning it to unsigned int pg_sz truncates the value to 0 and causes
efa_register_mr() to fail with -EOPNOTSUPP.

In addition, upstream commit 6a57af838b1a5 ("RDMA/efa: Add EFA 0xefa4 PCI
ID") was submitted as patch 2/2 alongside commit 4266547bdce74 ("RDMA/efa:
Extend page-shift field in MR registration"), which widens
EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT_MASK from GENMASK(4, 0) to
GENMASK(5, 0) for >4GB page sizes. Without that companion commit,
drivers/infiniband/hw/efa/efa_admin_cmds_defs.h still defines:

#define EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT_MASK      GENMASK(4, 0)

So in efa_com_register_mr() in drivers/infiniband/hw/efa/efa_com_cmd.c:

	EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
		params->page_shift);

bit 5 of params->page_shift is masked off for any page_shift >= 32. Should
pg_sz be an unsigned long and commit 4266547bdce74 be included as well?

[Severity: High]
Will creating multiple address handles to the same remote GID on the same
PD fail on 0xefa4 hardware without the address handle cache commits?

Upstream commits 97ba15272e8e ("RDMA/efa: Add initialization of AH cache
rhashtable") and 234895fa8be0 ("RDMA/efa: Add AH cache handling on create
and destroy AH") were merged right before commit 6a57af838b1a5 because new
EFA devices do not support creating multiple address handles to the same
remote on the same PD.

Without those commits backported, calling efa_create_ah() ->
efa_com_create_ah() for the same (pdn, dest_addr) pair unconditionally
sends a new EFA_ADMIN_CREATE_AH command to the device instead of
deduplicating and refcounting via efa_ah_cache_get():

drivers/infiniband/hw/efa/efa_com_cmd.c:efa_com_create_ah() {
	...
	ah_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_AH;

	memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
	ah_cmd.pd = params->pdn;

	err = efa_com_cmd_exec(aq,
			       (struct efa_admin_aq_entry *)&ah_cmd,
			       sizeof(ah_cmd),
			       (struct efa_admin_acq_entry *)&cmd_completion,
			       sizeof(cmd_completion));
}

Should commits 97ba15272e8e and 234895fa8be0 also be backported before
enabling PCI_DEV_ID_EFA4_VF?

>  	{ }
>  };
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-330-sashal@kernel.org?part=1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds Sasha Levin
@ 2026-10-19 15:08   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 15:08 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Zhiwei Zhang <202275009@qq.com>
> 
> [ Upstream commit fbbe1d5cd7d400a98afcf337969cfdb808cb198f ]
> 
> The IBTA Software Transport Verbs specification requires the QP,
> Memory Window and Memory Region for a Bind Memory Window operation
> to belong to the same HCA and protection domain.
> 
> rxe only checked the QP and MW protection domain for type 2 MWs.
> Move the QP/MW PD check to the common bind path and also reject
> binding an MW to an MR from a different PD.
> 
> Invalid bind requests continue to fail with IB_WC_MW_BIND_ERR.
> 
> Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
> Signed-off-by: Zhiwei Zhang <202275009@qq.com>
> Link: https://patch.msgid.link/tencent_FD4FB25AA4FFA845E63F5AC36CF4A46CDC0A@qq.com
> Signed-off-by: Leon Romanovsky <leon@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-403-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID Sasha Levin
  2026-10-19 15:05   ` sashiko-bot
@ 2026-10-19 15:09   ` Michael Margolin
  1 sibling, 0 replies; 15+ messages in thread
From: Michael Margolin @ 2026-10-19 15:09 UTC (permalink / raw)
  To: Sasha Levin
  Cc: patches, stable, Anas Mousa, Leon Romanovsky, linux-rdma,
	linux-kernel

On Mon, Oct 19, 2026 at 09:50:21AM -0400, Sasha Levin wrote:
> From: Anas Mousa <anasmous@amazon.com>
> 
> [ Upstream commit 6a57af838b1a56405a9bde9030de16df901ae2ca ]
> 
> Add support for 0xefa4 devices.
> 
> Reviewed-by: Michael Margolin <mrgolin@amazon.com>
> Signed-off-by: Anas Mousa <anasmous@amazon.com>
> Link: https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com
> Signed-off-by: Leon Romanovsky <leon@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> 
> LLM Generated explanations, may be completely bogus:
> 
> This is a two-line PCI ID addition to the existing Amazon EFA RDMA
> driver. That matches the stable-tree device-ID exception, and the local
> 7.3-rc4 tree already has the driver and ID table.
>

The 0xefa4 device support requires previous changes introduced in 7.3.
Please do not apply this patch on stable kernels.

> ---
> 
> ## PHASE 1: COMMIT MESSAGE FORENSICS
> 
> **Step 1.1: PARSE THE SUBJECT LINE**
> - Subsystem: `RDMA/efa`
> - Action verb: **Add**
> - Claimed intent: register PCI device ID `0xefa4` so the in-tree EFA
>   driver binds new Amazon Elastic Fabric Adapter hardware.
> 
> Record: `[RDMA/efa] [add] [PCI ID 0xefa4 for next-gen EFA VF]`
> 
> **Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
> - `Reviewed-by: Michael Margolin <mrgolin@amazon.com>` (Amazon EFA
>   contributor; 20 commits in this driver)
> - `Signed-off-by: Anas Mousa <anasmous@amazon.com>` (author)
> - `Link:
>   https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com`
> - `Signed-off-by: Leon Romanovsky <leon@kernel.org>` (RDMA maintainer,
>   committer)
> - No `Fixes:` tag (expected)
> - No `Cc: stable@vger.kernel.org` (expected)
> - No `Reported-by:`, `Tested-by:`, `Acked-by:`
> - Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
>   ...]` markers (none in the real commit)
> 
> Record: Maintainer-applied PCI ID patch; Amazon internal review; lore
> link present; no syzbot/bug report (not applicable).
> 
> **Step 1.3: ANALYZE THE COMMIT BODY TEXT**
> Body is one sentence: “Add support for 0xefa4 devices.” Cover letter
> (mbox): “Make a minor device interface change needed for new EFA devices
> and enable support for 0xefa4 PCI ID.” No crash, no reproducer — this is
> hardware enablement.
> 
> Record: `[Bug description: none — new PCI ID] [Symptom: 0xefa4 adapters
> unbound / unused by in-tree efa] [Version info: none] [Root cause: ID
> missing from pci_device_id table]`
> 
> **Step 1.4: DETECT HIDDEN BUG FIXES**
> Not a disguised leak/race/UAF fix. It is exactly a device-ID addition.
> 
> Record: `[Not a hidden bug fix. Explicit PCI ID enablement.]`
> 
> ---
> 
> ## PHASE 2: DIFF ANALYSIS
> 
> **Step 2.1: INVENTORY THE CHANGES**
> - File: `drivers/infiniband/hw/efa/efa_main.c` — **+2 / -0**
> - `#define PCI_DEV_ID_EFA4_VF 0xefa4`
> - `{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA4_VF) }` in `efa_pci_tbl[]`
> - Scope: single-file surgical ID addition
> 
> Record: `[efa_main.c +2] [pci_device_id table] [surgical single-file]`
> 
> **Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
> Before: PCI core matches Amazon vendor `0x1d0f` with IDs
> `0xefa0`–`0xefa3` only. `0xefa4` is ignored (no probe).
> After: `0xefa4` matches `efa_pci_driver`, `efa_probe()` runs the same
> path as older generations.
> 
> `efa_probe(struct pci_dev *pdev, const struct pci_device_id *ent)` does
> not use `ent` for generation-specific branching. `vendor_part_id` is
> taken from `pdev->device`. Capabilities come from admin query
> (`page_size_cap`, etc.).
> 
> Record: `[PCI match table: 4 IDs -> 5 IDs; probe path unchanged]`
> 
> **Step 2.3: IDENTIFY THE BUG MECHANISM**
> Category **(h) Hardware workarounds / device ID additions**. Without the
> ID, new EFA VFs never bind.
> 
> Record: `[Device ID addition] [Missing 0xefa4 in efa_pci_tbl prevented
> driver bind]`
> 
> **Step 2.4: ASSESS THE FIX QUALITY**
> Obviously correct. Same pattern as `0xefa2` (`b75927cff13e0`) and
> `0xefa3` (`346d2fc606a85`). Does not change locking, APIs, or existing-
> ID behavior. Regression risk is confined to `1d0f:efa4` hardware.
> 
> Record: `[Minimal, obviously correct] [Regression risk: only 0xefa4
> devices]`
> 
> ---
> 
> ## PHASE 3: GIT HISTORY INVESTIGATION
> 
> **Step 3.1: BLAME THE CHANGED LINES**
> ```
> efa0/efa1: d4f9cb5c5b224 (Gal Pressman, 2020)
> efa2:     b75927cff13e0 (Michael Margolin, 2022) → v6.1-rc4
> efa3:     346d2fc606a85 (Michael Margolin, 2024) → present in v6.11 /
> v7.2.7
> efa4:     6a57af838b1a5 (Anas Mousa, 2026-07-12)
> Driver:   b7f5e880f3774 (2019) → v5.2-rc1
> ```
> The table has been the enablement mechanism since the driver was added.
> 
> Record: `[ID table since v5.2; this ID added 2026-07-12 / 7.3 merge
> window]`
> 
> **Step 3.2: FOLLOW THE FIXES: TAG**
> No `Fixes:` tag. Not a regression fix.
> 
> Record: `[N/A — device ID, not a regression]`
> 
> **Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
> Same msgid series `20260712134413`:
> 1. `4266547bdce74` RDMA/efa: Extend page-shift field in MR registration
>    (`19226-2`)
> 2. `6a57af838b1a5` RDMA/efa: Add EFA 0xefa4 PCI ID (`19226-3`) — this
>    commit
> 
> Cover letter: 2-patch `for-next` series. Patch 1 widens
> `EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT_MASK` from `GENMASK(4,0)` to
> `GENMASK(5,0)` for **>4GB page sizes** on 0xefa4. That is extra
> capability, not required for PCI bind/probe. `efa_probe` does not depend
> on that mask.
> 
> Record: `[Series of 2; this patch is standalone for bind] [page-shift is
> feature, not probe prerequisite]`
> 
> **Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
> Anas Mousa: this is the only in-tree EFA commit. Reviewed by Michael
> Margolin (regular EFA author). Applied by Leon Romanovsky.
> 
> Record: `[First-time author; reviewed by EFA regular; applied by RDMA
> maintainer]`
> 
> **Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
> Local tree already has `PCI_DEV_ID_EFA3_VF`, `PCI_VDEVICE(AMAZON, ...)`,
> and `efa_pci_tbl`. No new helpers. Companion page-shift commit is
> already in this tree (`git merge-base --is-ancestor 4266547bdce74
> HEAD`).
> 
> Record: `[Applies standalone] [No missing structs/APIs in this tree]`
> 
> ---
> 
> ## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
> 
> **Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
> `b4 dig -c 6a57af838b1a5` →
> https://patch.msgid.link/20260712134413.19226-3-mrgolin@amazon.com
> `b4 dig -a`: **v1 only** (no v2/v3).
> Thread saved to mbox (6 messages).
> 
> Key review (on patch 1/2, not this ID patch): Leon asked how non-0xefa4
> devices handle the extra page-shift bit. Michael: kernel uses device-
> reported `page_size_cap` with `ib_umem_find_best_pgsz()`, so the extra
> bit is not set on older devices; device also validates. Leon then
> **Applied, thanks!** both patches. No NAK on the PCI ID patch. No `Cc:
> stable` request.
> 
> Record: `[lore via patch.msgid.link/20260712134413.19226-3] [v1 only]
> [no NAK on ID patch] [no stable nomination]`
> 
> **Step 4.2: CHECK WHO REVIEWED THE PATCH**
> `b4 dig -w` recipients: `jgg@nvidia.com`, `leon@kernel.org`, `linux-
> rdma@vger.kernel.org`, Amazon EFA engineers (`sleybo`, `matua`,
> `gal.pressman`). Right lists and maintainers.
> 
> Record: `[RDMA maintainers + linux-rdma CC'd; Leon applied]`
> 
> **Step 4.3: SEARCH FOR THE BUG REPORT**
> No bugzilla/syzbot. External confirmation that 0xefa4 is real hardware:
> - DeviceHunt: PCI `1D0F:EFA4` Amazon Elastic Fabric Adapter
> - Amazon out-of-tree `efa_linux_3.3.0`: “Add 0xefa4 device support”
> - rdma-core: `efa: Add EFA 0xefa4 PCI ID`
> 
> Record: `[Real shipping device; userspace + out-of-tree driver already
> list the ID]`
> 
> **Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
> 2/2 of “Add support for 0xefa4 devices”. Evaluating only the ID patch:
> self-contained for enumeration. Full >4GB MR pages needs patch 1/2
> (already in this tree).
> 
> Record: `[Standalone for bind; series mate is optional extra
> capability]`
> 
> **Step 4.5: CHECK STABLE MAILING LIST HISTORY**
> lore.kernel.org WebFetch returned 403. `b4 dig` mbox has no stable-list
> traffic. No evidence this ID was rejected for stable.
> 
> Record: `[No stable-list discussion found (lore HTTP 403; mbox has
> none)]`
> 
> ---
> 
> ## PHASE 5: CODE SEMANTIC ANALYSIS
> 
> **Step 5.1: KEY FUNCTIONS**
> No function body changed. Data: `PCI_DEV_ID_EFA4_VF`, `efa_pci_tbl[]`.
> Consumers: `MODULE_DEVICE_TABLE(pci, efa_pci_tbl)` and
> `efa_pci_driver.id_table`.
> 
> Record: `[efa_pci_tbl / efa_pci_driver only]`
> 
> **Step 5.2: TRACE CALLERS**
> PCI core `pci_device_probe` → `efa_probe` → `efa_probe_device` /
> `efa_ib_device_add`. Userspace-visible once the VF is assigned (typical
> AWS EFA instance).
> 
> Record: `[PCI enumeration; bind on matching VF]`
> 
> **Step 5.3: TRACE CALLEES**
> Unchanged. Probe still does BAR map, MSI-X, admin queues, IB register.
> 
> Record: `[Probe callees unchanged]`
> 
> **Step 5.4: FOLLOW THE CALL CHAIN**
> Reachable when `CONFIG_INFINIBAND_EFA` is set (`PCI_MSI && 64BIT &&
> !CPU_BIG_ENDIAN && INFINIBAND_USER_ACCESS`) and `1d0f:efa4` is present.
> Common on AWS HPC/ML instances, not a syscall fuzzer path.
> 
> Record: `[Reachable from device hotplug/boot on EFA instances]`
> 
> **Step 5.5: SEARCH FOR SIMILAR PATTERNS**
> Identical ID adds for efa2/efa3. No `switch (pdev->device)` /
> `driver_data` generation quirks in `drivers/infiniband/hw/efa/`.
> 
> Record: `[Same pattern as prior EFA IDs; no per-ID code]`
> 
> ---
> 
> ## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
> 
> **Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
> Local tree: **v7.3-rc4-27-gf0100363d8c37**, `make kernelversion` =
> **7.3.0-rc4**.
> `INFINIBAND_EFA` and `efa_pci_tbl` exist. `0xefa0`–`0xefa3` exist.
> Without this change, `0xefa4` would not match.
> 
> `git merge-base --is-ancestor 6a57af838b1a5 HEAD` → yes (landed by
> **v7.3-rc1**). Not in **v7.2.7**. Introduced in the 7.3 window, not
> after this branch point.
> 
> Record: `[Driver and ID table present in this 7.3-rc4 tree] [ID added in
> 7.3-rc1]`
> 
> **Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
> Hunk is two lines next to `PCI_DEV_ID_EFA3_VF`. Would apply cleanly to
> this file’s table. No refactor of the ID table.
> 
> Record: `[Expected apply: clean]`
> 
> **Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
> No alternate 0xefa4 enablement. This is the only `0xefa4` PCI table
> change.
> 
> Record: `[No other 0xefa4 bind fix]`
> 
> ---
> 
> ## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
> 
> **Step 7.1: SUBSYSTEM AND CRITICALITY**
> `drivers/infiniband/hw/efa/` — Amazon EFA RDMA NIC.
> Criticality: **IMPORTANT** for AWS EFA users; **PERIPHERAL** globally.
> Not core mm/net.
> 
> Record: `[RDMA/efa] [IMPORTANT for EFA hardware, otherwise peripheral]`
> 
> **Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
> Actively maintained (completion counters, 128B admin SQ, IRQ lifetime
> fixes in 2026). ID adds are a long-standing pattern, not a new
> subsystem.
> 
> Record: `[Active but mature ID-table pattern]`
> 
> MAINTAINERS: “AMAZON RDMA EFA DRIVER”.
> 
> ---
> 
> ## PHASE 8: IMPACT AND RISK ASSESSMENT
> 
> **Step 8.1: WHO IS AFFECTED**
> Users of Amazon EFA VF `1d0f:efa4` with `CONFIG_INFINIBAND_EFA`. Older
> EFA IDs unchanged.
> 
> Record: `[driver-specific / config-specific (INFINIBAND_EFA)]`
> 
> **Step 8.2: TRIGGER CONDITIONS**
> Boot or VF assignment of 0xefa4. Not a race. Unprivileged users cannot
> trigger a crash; they just get a working RDMA device after bind.
> 
> Record: `[Hotplug/boot of 0xefa4] [Likely on new EFA instances] [Not a
> UAF/syscall crash]`
> 
> **Step 8.3: FAILURE MODE SEVERITY**
> Without the ID: device unused by in-tree driver (lost HPC/RDMA). Not
> panic/corruption. For affected hardware this is functional breakage.
> 
> Record: `[Device not bound] [Severity: HIGH for 0xefa4 users, LOW for
> everyone else]`
> 
> **Step 8.4: RISK-BENEFIT RATIO**
> Benefit: enables real hardware on an existing driver (stable-kernel-
> rules explicitly allow this).
> Risk: two lines, ID-table only, no API/lock/hot-path change.
> 
> Record: `[Benefit: high for EFA 0xefa4] [Risk: very low] [Favorable]`
> 
> ---
> 
> ## PHASE 9: FINAL SYNTHESIS
> 
> **Step 9.1: COMPILE THE EVIDENCE**
> 
> FOR:
> - `Documentation/process/stable-kernel-rules.rst`: “must either fix a
>   real bug that bothers people **or just add a device ID**.”
> - Canonical PCI ID exception: driver already in tree; only the ID is
>   new.
> - +2 lines, obviously correct, same as efa2/efa3.
> - No per-ID branching; probe is generation-agnostic.
> - Real device (`1d0f:efa4`); Amazon out-of-tree and rdma-core already
>   list it.
> - Reviewed and applied by RDMA maintainer Leon Romanovsky.
> - Applies cleanly; no new APIs.
> 
> AGAINST:
> - Not a crash/security/corruption fix (not required for device IDs).
> - Submitted as `for-next`, no `Cc: stable` (absence is expected).
> - Series mate extends page-shift for >4GB MRs; not needed for bind.
> - Author is a first-time in-tree EFA contributor (offset by Margolin
>   review + Leon apply).
> 
> UNRESOLVED:
> - Direct lore.kernel.org HTTP fetches returned 403; thread recovered via
>   `b4 dig -m`.
> - Stable mailing list search via WebFetch also 403; no stable discussion
>   in the rdma mbox.
> 
> **Step 9.2: STABLE RULES CHECKLIST**
> 1. Obviously correct and tested? **PASS** — 2-line ID table; maintainer
>    applied after review.
> 2. Fixes a real bug that affects users? **PASS** — device ID exception;
>    otherwise 0xefa4 never binds.
> 3. Important issue? **PASS** under the documented device-ID exception
>    (not a panic).
> 4. Small and contained? **PASS** — +2 lines, one file.
> 5. No new features or APIs? **PASS** — existing driver, new ID only
>    (page-shift is a different commit).
> 6. Can apply to the local tree? **PASS** — `efa_main.c` ID table
>    present; hunk matches.
> 
> **Step 9.3: EXCEPTION CATEGORY**
> **Device ID addition to existing driver** — automatic stable qualifier.
> 
> **Step 9.4: DECISION**
> This tree is **7.3.0-rc4**. The EFA driver and PCI table are here.
> Adding `0xefa4` is the standard, low-risk hardware-enablement backport.
> The companion page-shift change is a separate feature and is not
> required for this ID patch to be correct.
> 
> ### What it solves for users of this tree
> Without `0xefa4` in `efa_pci_tbl`, new Amazon EFA adapters are invisible
> to the in-tree driver. With it, the existing probe path binds them. That
> is exactly what stable trees take PCI IDs for.
> 
> ### Risk vs benefit
> Benefit is hardware enablement for EFA 0xefa4. Risk is two lines that
> cannot affect other devices.
> 
> ---
> 
> ### Verification
> - [Phase 1] Parsed commit `6a57af838b1a56405a9bde9030de16df901ae2ca`:
>   Reviewed-by Margolin, SOB Anas Mousa + Leon Romanovsky, Link msgid
>   `20260712134413.19226-3`
> - [Phase 2] Diff: +2 lines in `efa_pci_tbl` / `PCI_DEV_ID_EFA4_VF` only
> - [Phase 2] `efa_probe()` does not branch on `ent`/`pdev->device` for
>   quirks (verified in `efa_main.c`)
> - [Phase 3] `git blame -L 16,29 efa_main.c`: efa0–efa3 older; efa4 is
>   this commit
> - [Phase 3] Prior IDs: efa2 `b75927cff13e0`, efa3 `346d2fc606a85` — same
>   2-line pattern
> - [Phase 3] Series mate `4266547bdce74` is page-shift GENMASK only, not
>   a probe dependency
> - [Phase 4] `b4 dig -c 6a57af838b1a5`: matched lore thread; v1 only
> - [Phase 4] `b4 dig -w`: linux-rdma, jgg, leon CC’d
> - [Phase 4] mbox: Leon question on patch 1/2 only; both patches applied
>   2026-07-14; no NAK on ID patch
> - [Phase 4] WebFetch lore/stable: HTTP 403 — UNVERIFIED via HTTP;
>   covered by b4 mbox
> - [Phase 5] Call path: PCI `id_table` → `efa_probe`; `page_size_cap`
>   used in `efa_verbs.c` for MR pages
> - [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`; `make
>   kernelversion` = 7.3.0-rc4
> - [Phase 6] `git merge-base --is-ancestor 6a57af838b1a5 HEAD` = yes; not
>   ancestor of `v7.2.7`
> - [Phase 6] Driver added `b7f5e880f3774` (v5.2-rc1); present in this
>   tree
> - [Phase 7] `Documentation/process/stable-kernel-rules.rst` line 15:
>   device ID explicitly allowed
> - [Phase 8] Failure mode: device not bound on 0xefa4; no panic path
> - UNVERIFIED: stable@vger archive contents (HTTP 403)
> 
> The change is a contained PCI ID addition to a driver this tree already
> ships, which stable policy explicitly accepts.
> 
> **YES**
> 
>  drivers/infiniband/hw/efa/efa_main.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
> index fdaf88f0122db..b1f3e7ce2c65e 100644
> --- a/drivers/infiniband/hw/efa/efa_main.c
> +++ b/drivers/infiniband/hw/efa/efa_main.c
> @@ -17,12 +17,14 @@
>  #define PCI_DEV_ID_EFA1_VF 0xefa1
>  #define PCI_DEV_ID_EFA2_VF 0xefa2
>  #define PCI_DEV_ID_EFA3_VF 0xefa3
> +#define PCI_DEV_ID_EFA4_VF 0xefa4
>  
>  static const struct pci_device_id efa_pci_tbl[] = {
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
>  	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA3_VF) },
> +	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA4_VF) },
>  	{ }
>  };
>  
> -- 
> 2.53.0
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it Sasha Levin
@ 2026-10-19 15:15   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-10-19 15:15 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-rdma

> From: Håkon Bugge <haakon.bugge@oracle.com>
> 
> [ Upstream commit 9079adef042c1e7a6141dcdfd3041acd30607297 ]
> 
> Each rds_mr stores a bare back pointer to the socket that created it
> (mr->r_sock) but takes no reference on it.  When the mr is destroyed it
> references the rs. Hence, provisions must be made to avoid the rs
> being destroyed before all mrs referencing it have been destroyed.
> 
> The MR itself is refcounted, and in-flight messages legitimately hold
> MR krefs that can outlive the socket: rds_release() drops the rb-tree
> references via rds_rdma_drop_keys(), but a send completion arriving
> afterwards drops the final message reference from the CQ handler and
> ends up in
> 
> [ ... ]
>  __rds_put_mr_final(); update commit message]
> Signed-off-by: Allison Henderson <achender@kernel.org>
> Link: https://patch.msgid.link/20260730041629.3512480-3-achender@kernel.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-432-sashal@kernel.org?part=1


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-10-19 15:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:44 ` [PATCH AUTOSEL 6.18] RDMA/irdma: Suppress PF reset on HMC error Sasha Levin
2026-10-19 14:00   ` sashiko-bot
2026-10-19 13:44 ` [PATCH AUTOSEL 6.18-5.10] net/rds: don't use unpin_user_pages_dirty_lock() from atomic context Sasha Levin
2026-10-19 14:07   ` sashiko-bot
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] net/rds: unpin MR pages with unpin_user_pages_dirty_lock() Sasha Levin
2026-10-19 14:32   ` sashiko-bot
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] net/rds: fix rds_message leak in the rds_send_xmit() drop path Sasha Levin
2026-10-19 14:47   ` sashiko-bot
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] RDMA/efa: Add EFA 0xefa4 PCI ID Sasha Levin
2026-10-19 15:05   ` sashiko-bot
2026-10-19 15:09   ` Michael Margolin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.1] RDMA/rxe: Check PDs for memory window binds Sasha Levin
2026-10-19 15:08   ` sashiko-bot
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] net/rds: hold the socket while an rds_mr references it Sasha Levin
2026-10-19 15:15   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox