Linux CXL
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Dave Jiang <dave.jiang@intel.com>
Cc: linux-cxl@vger.kernel.org, dave@stgolabs.net,
	alison.schofield@intel.com, ming.li@zohomail.com,
	icheng@nvidia.com
Subject: Re: [PATCH] cxl/mbox: Store event records for EDAC repair regardless of tracing
Date: Fri, 25 Sep 2026 23:44:25 +0100	[thread overview]
Message-ID: <20260925234425.67be0e2e@jic23-hlaptop> (raw)
In-Reply-To: <20260924212320.56573-1-dave.jiang@intel.com>

On Thu, 24 Sep 2026 14:23:20 -0700
Dave Jiang <dave.jiang@intel.com> wrote:

> The driver throws away media error records unless a tracepoint is enabled.
> 
> cxl_event_trace_record() stores general media and DRAM records for EDAC
> repair, but both calls sit inside a block gated on the cxl_general_media
> and cxl_dram tracepoints. That gate only exists to skip the DPA-to-HPA
> lookup used to annotate those tracepoints. Storing a record does not need
> the lookup.
> 
> With both tracepoints off, two things break. The kernel clears the device
> event log either way, so the records are destroyed in hardware and kept
> nowhere else. And live repair stops working altogether: sPPR and memory
> sparing require the target DPA to have reported an error, no DPA ever has
> a record, so every request fails with -EINVAL.

Hi Dave,

Given userspace is always in that path (I think), without the
tracepoints being enabled it will be one impressive guess to
successfully make repair happen - you'll have to magically know
what address will see a hit in the stored error records.

Maybe that happens in some test case, but it doesn't feel real
to me.

> 
> Move the two stores ahead of the tracepoint check. Keep them under the
> memdev lock, which is what stops err_rec_free() from freeing
> cxlmd->err_rec_array while the CPER callback runs. Leave the region and
> DPA rwsems with the lookup.
> 
> Fixes: 0b5ccb0de1e2 ("cxl/edac: Support for finding memory operation attributes from the current boot")

Why the fixes tag?   Maybe this is enabling something new that is
useful but I'm not immediately understanding what was 'broken' before.


> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> Assisted-by: LLM
> ---
> Found by reviewing the gate, not from a failure report.
> 
> The documented flow is unaffected, which is why this has gone unnoticed:
> rasdaemon watches the tracepoints, so they are on and the records exist
> (Documentation/edac/memory_repair.rst:94-97). Offline repair is unaffected
> too, since both checks sit under cxl_is_memdev_memory_online():
> 
>   edac.c:1807  sPPR     -EINVAL when neither cxl_find_rec_dram() nor
>                         cxl_find_rec_gen_media() finds a record
>   edac.c:1357  sparing  -EINVAL when cxl_mem_get_rec_dram() finds none
> 
> The unconditional log clear is at mbox.c:1115, after the record loop.
> 
> The memdev lock has to cover the store. err_rec_free() is a devm action on
> &cxlmd->dev (edac.c:2021) that NULLs err_rec_array and frees it, and the
> CPER path (cxl/pci.c:1053) can run while cxl_mem unbinds. Hoisting the
> stores out from under guard(device) would trade the gating bug for a
> use-after-free.
> 
> The casts on cxlmd go away because the parameter has not been const since
> dc372e5f429c ("cxl/pci: Hold memdev lock in cxl_event_trace_record()").
> 
> Tested in QEMU with cxl_test. kprobe entry counts over the same 220 mock
> event records, using cxl_event_trace_record() as the control:
> 
>   tracepoints off      control   store_gen_media   store_dram
>     before                 220                 0            0
>     after                  220                22           33
> 
>   tracepoints on       control   store_gen_media   store_dram
>     before                 220                22           33
>     after                  220                22           33
> 
> Records are kept with tracing off, and the tracing-on path is unchanged -
> the hoist neither drops nor duplicates a store. The guest log shows
> cxl_clear_event_record() draining the device log in both cases, so the
> records really are gone from hardware whether or not the kernel kept them.
> Builds warning-free with CONFIG_CXL_EDAC_MEM_FEATURES=y and disabled.
> 
> Not covered: the -EINVAL itself. cxl_test mocks no sPPR or sparing feature,
> so the repair path cannot be driven end to end.
> 
> Left alone to keep this minimal: the WARN_ON_ONCE checks on the AP/CME
> counter-expire descriptor (mbox.c:952-964) stay inside the gate, and are
> arguably mis-gated for the same reason.
> ---
>  drivers/cxl/core/mbox.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index 55828a836c01..89fb2f569e4b 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -913,6 +913,22 @@ void cxl_event_trace_record(struct cxl_memdev *cxlmd,
>  		return;
>  	}
>  
> +	/*
> +	 * EDAC memory repair looks these records up from the current boot, so
> +	 * store them whether or not tracing is enabled. Hold the memdev lock
> +	 * across the store to keep cxlmd->err_rec_array alive against a
> +	 * concurrent cxl_mem unbind.
> +	 */
> +	guard(device)(&cxlmd->dev);
> +
> +	if (event_type == CXL_CPER_EVENT_GEN_MEDIA) {
> +		if (cxl_store_rec_gen_media(cxlmd, evt))
> +			dev_dbg(&cxlmd->dev, "CXL store rec_gen_media failed\n");
> +	} else if (event_type == CXL_CPER_EVENT_DRAM) {
> +		if (cxl_store_rec_dram(cxlmd, evt))
> +			dev_dbg(&cxlmd->dev, "CXL store rec_dram failed\n");
> +	}
> +
>  	if (trace_cxl_general_media_enabled() || trace_cxl_dram_enabled()) {
>  		u64 dpa, hpa = ULLONG_MAX, hpa_alias = ULLONG_MAX;
>  		struct cxl_region *cxlr;
> @@ -922,7 +938,6 @@ void cxl_event_trace_record(struct cxl_memdev *cxlmd,
>  		 * translations. Take topology mutation locks and lookup
>  		 * { HPA, REGION } from { DPA, MEMDEV } in the event record.
>  		 */
> -		guard(device)(&cxlmd->dev);
>  		guard(rwsem_read)(&cxl_rwsem.region);
>  		guard(rwsem_read)(&cxl_rwsem.dpa);
>  
> @@ -937,9 +952,6 @@ void cxl_event_trace_record(struct cxl_memdev *cxlmd,
>  		}
>  
>  		if (event_type == CXL_CPER_EVENT_GEN_MEDIA) {
> -			if (cxl_store_rec_gen_media((struct cxl_memdev *)cxlmd, evt))
> -				dev_dbg(&cxlmd->dev, "CXL store rec_gen_media failed\n");
> -
>  			if (evt->gen_media.media_hdr.descriptor &
>  			    CXL_GMER_EVT_DESC_THRESHOLD_EVENT)
>  				WARN_ON_ONCE((evt->gen_media.media_hdr.type &
> @@ -952,9 +964,6 @@ void cxl_event_trace_record(struct cxl_memdev *cxlmd,
>  			trace_cxl_general_media(cxlmd, type, cxlr, hpa,
>  						hpa_alias, &evt->gen_media);
>  		} else if (event_type == CXL_CPER_EVENT_DRAM) {
> -			if (cxl_store_rec_dram((struct cxl_memdev *)cxlmd, evt))
> -				dev_dbg(&cxlmd->dev, "CXL store rec_dram failed\n");
> -
>  			if (evt->dram.media_hdr.descriptor &
>  			    CXL_GMER_EVT_DESC_THRESHOLD_EVENT)
>  				WARN_ON_ONCE((evt->dram.media_hdr.type &
> 
> base-commit: fd73f4a6659897191fa0d40695fe370925dd3780


  reply	other threads:[~2026-09-25 22:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 21:23 [PATCH] cxl/mbox: Store event records for EDAC repair regardless of tracing Dave Jiang
2026-09-25 22:44 ` Jonathan Cameron [this message]
2026-09-25 22:53   ` Dave Jiang
2026-09-25 23:50     ` Jonathan Cameron
2026-09-25 23:52       ` Dave Jiang

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20260925234425.67be0e2e@jic23-hlaptop \
    --to=jic23@kernel.org \
    --cc=alison.schofield@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=icheng@nvidia.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=ming.li@zohomail.com \
    /path/to/YOUR_REPLY

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

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