mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v5 0/3] cxl/edac: Fix event record lookups for memory repair
@ 2026-11-08  2:20 Jongwon Lee
  2026-11-08  2:20 ` [PATCH v5 1/3] cxl/edac: Read cached DRAM event records under the xarray lock Jongwon Lee
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jongwon Lee @ 2026-11-08  2:20 UTC (permalink / raw)
  To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield,
	Vishal Verma, Dan Williams
  Cc: Ira Weiny, Li Ming, Richard Cheng, linux-cxl, linux-kernel

This series fixes how the memory repair path looks up cached event
records.

Patch 1 fixes a use-after-free between the repair path and the event
path. Sashiko's review of v2 found that the repair path reads cached
DRAM event records without any lock that stops the event path from
freeing them [1]. This race was already there in cxl_find_rec_dram()
and cxl_mem_perform_sparing(). Patch 1 does the DRAM lookup under the
xarray lock, and copies the record out for the sparing path.

Patch 2 makes both lookups skip records that the device marked
NOT_REPAIRABLE. Since the General Media lookup now reads the record, it
also takes the xarray lock.

Patch 3 is the DPA flag masking fix from the earlier versions. It has to
come after patch 2. With the masked key, the DPA from the trace event
matches a NOT_REPAIRABLE record, so masking alone would let such a
record be repaired.

I used xa_lock() for the race. kfree_rcu() would need a wrapper struct
with an rcu_head, since the cached records are copies of the event
structures from the spec. The lookups only compare a few fields, so the
lock is held for a short time. Taking device_lock() in the repair path,
like the event path does, looked like it could deadlock with unbind.
Unbind removes the EDAC sysfs files while holding device_lock().

Changes in v5:
- New patch 2: the NOT_REPAIRABLE check, split out of v4 patch 2 and
  placed before the masking patch (Li Ming)
- Patch 3: rename cxl_rec_key() to cxl_rec_dpa() (Li Ming)
- Patch 1: drop the found variable in cxl_find_rec_dram() (Li Ming).
  It now returns rec. I said rec != NULL in my reply, but checkpatch
  --strict warns about that.
- No message is printed when a NOT_REPAIRABLE record is skipped. The
  trace events already show dpa_flags='NOT_REPAIRABLE' for it. I can
  add a dev_dbg() there if that is preferred.
- Richard's Reviewed-by on v4 2/2 is not carried over to patches 2 and
  3, since that patch was split.
- Rebased on cxl/next (e44dc3a303), no conflicts.

Changes in v4:
- Patch 1: copy the whole struct cxl_event_dram out instead of only
  validity_flags (Richard Cheng)
- Patch 2: make cxl_rec_key() and cxl_rec_not_repairable() static
  inline (Richard Cheng)
- Cover letter: describe patch 1 first (Richard Cheng)

Changes in v3:
- New patch 1 for the record lifetime race (Sashiko)
- Patch 2: General Media lookup under the xarray lock, returns bool

Changes in v2:
- Moved the Claude Code note below the --- (Dave Jiang)

v4: https://lore.kernel.org/r/20261102123233.74598-1-ai@linux.com
v3: https://lore.kernel.org/r/20261101013418.87326-1-ai@linux.com
v2: https://lore.kernel.org/r/20261031161121.15948-1-ai@linux.com
v1: https://lore.kernel.org/r/20261030072721.31970-1-ai@linux.com

Testing was done in QEMU master (b574eaf) with a CXL type 3 device and
a committed region, on top of d89e1d186e. Debug options: KASAN,
PROVE_LOCKING, PROVE_RAW_LOCK_NESTING, PROVE_RCU, DEBUG_ATOMIC_SLEEP,
DEBUG_LIST, UBSAN_BOUNDS, KMEMLEAK, hung task and soft lockup detection,
booted with preempt=full. The unpatched results are from the v4 runs on
the same base. Not tested on real CXL hardware.

- Repair table: DRAM events at 0x1001, 0x2000 and 0x3002 and General
  Media events at 0x5001 and 0x6002, then a repair request on all five
  mem_repair devices for eight DPAs. With the series, 0x1000 and 0x2000
  succeed for all five repair types, and 0x5000 succeeds for PPR only.
  0x3000 and 0x6000 (NOT_REPAIRABLE set), 0x7000 (no record), 0x1001
  and 0x3002 fail with -EINVAL, same as v4. With only patches 1 and 2,
  0x3002 is rejected, 0x1001 is accepted, and 0x1000 and the PPR
  request at 0x5000 still fail. Unpatched, 0x1000 and the PPR request
  at 0x5000 fail, and 0x1001 and 0x3002 are accepted.
- Race test with a test-only mdelay(20): the host injects DRAM and
  General Media events back to back. Some DPAs repeat, so xa_store()
  replaces and frees records, and there are enough distinct DPAs to hit
  the overflow path. Four guest loops request repairs on all five
  devices at the same time. Unpatched, with the delay after xa_load()
  and after the lookup in the sparing path, KASAN reported a
  slab-use-after-free in cxl_do_mem_sparing() after 120 s. With v5 and
  the delay after both xa_load() calls inside the locked section and
  after the lookup in the sparing path: 600 s, 10650 repair requests,
  241298 events, no report.
- The same race test without the delay: v5 ran for 1800 s, 67830
  repair requests and 988817 events, no report.
- Unbind test: two repair loops and the same event injection for 600 s,
  while another loop unbinds cxl_mem, waits 2 s, binds it again and
  waits 3 s. v5: 82 unbind/bind cycles, 8838 repair requests, no
  report, and mem0 was still bound at the end.
- kmemleak scan at the end of each run: no unreferenced objects.
- Builds: the x86_64 test kernel with gcc. For drivers/cxl/core/edac.o:
  W=1 after each patch, sparse, clang W=1 for x86_64 and arm64, and
  CONFIG_CXL_EDAC_MEM_REPAIR=n, with no new warnings. The series
  applies to cxl/next (e44dc3a303) and edac.o builds there after each
  patch with W=1 and no new warnings.

This series was developed with Claude Code.

[1] https://lore.kernel.org/r/sashiko-outbox-192042@kernel.org

Jongwon Lee (3):
  cxl/edac: Read cached DRAM event records under the xarray lock
  cxl/edac: Skip event records marked NOT_REPAIRABLE
  cxl/edac: Mask DPA flags in the event record cache key

 drivers/cxl/core/edac.c | 113 ++++++++++++++++++++++++++--------------
 1 file changed, 74 insertions(+), 39 deletions(-)


base-commit: e44dc3a3037346354ac0dcd70415a7e049fab059
-- 
2.55.0


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

end of thread, other threads:[~2026-11-08  2:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-08  2:20 [PATCH v5 0/3] cxl/edac: Fix event record lookups for memory repair Jongwon Lee
2026-11-08  2:20 ` [PATCH v5 1/3] cxl/edac: Read cached DRAM event records under the xarray lock Jongwon Lee
2026-11-08  2:20 ` [PATCH v5 2/3] cxl/edac: Skip event records marked NOT_REPAIRABLE Jongwon Lee
2026-11-08  2:20 ` [PATCH v5 3/3] cxl/edac: Mask DPA flags in the event record cache key Jongwon Lee

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

all inboxes | Powered by JetHome®