RE: [PATCH v1 1/2] cxl/edac: Fix the min_scrub_cycle of a region miscalculation

From: Shiju Jose
Date: Tue Jun 03 2025 - 13:07:08 EST


>-----Original Message-----
>From: Li Ming <ming.li@xxxxxxxxxxxx>
>Sent: 03 June 2025 11:43
>To: dave@xxxxxxxxxxxx; Jonathan Cameron <jonathan.cameron@xxxxxxxxxx>;
>dave.jiang@xxxxxxxxx; alison.schofield@xxxxxxxxx; vishal.l.verma@xxxxxxxxx;
>ira.weiny@xxxxxxxxx; dan.j.williams@xxxxxxxxx; Shiju Jose
><shiju.jose@xxxxxxxxxx>
>Cc: linux-cxl@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Li Ming
><ming.li@xxxxxxxxxxxx>
>Subject: [PATCH v1 1/2] cxl/edac: Fix the min_scrub_cycle of a region
>miscalculation
>
>When trying to update the scrub_cycle value of a cxl region, which means
>updating the scrub_cycle value of each memdev under a cxl region. cxl driver
>needs to guarantee the new scrub_cycle value is greater than the
>min_scrub_cycle value of a memdev, otherwise the updating operation will
>fail(Per Table 8-223 in CXL r3.2 section 8.2.10.9.11.1).
>
>Current implementation logic of getting the min_scrub_cycle value of a cxl
>region is that getting the min_scrub_cycle value of each memdevs under the cxl
>region, then using the minimum min_scrub_cycle value as the region's
>min_scrub_cycle. Checking if the new scrub_cycle value is greater than this
>value. If yes, updating the new scrub_cycle value to each memdevs. The issue is
>that the new scrub_cycle value is possibly greater than the minimum
>min_scrub_cycle value of all memdevs but less than the maximum
>min_scrub_cycle value of all memdevs if memdevs have a different
>min_scrub_cycle value. The updating operation will always fail on these
>memdevs which have a greater min_scrub_cycle than the new scrub_cycle.
>
>The correct implementation logic is to get the maximum value of these
>memdevs' min_scrub_cycle, check if the new scrub_cycle value is greater than
>the value. If yes, the new scrub_cycle value is fit for the region.
>
>The change also impacts the result of
>cxl_patrol_scrub_get_min_scrub_cycle(), the interface returned the minimum
>min_scrub_cycle value among all memdevs under the region before the change.
>The interface will return the maximum min_scrub_cycle value among all
>memdevs under the region with the change.
>

Reviewed-by: Shiju Jose <shiju.jose@xxxxxxxxxx>

>Signed-off-by: Li Ming <ming.li@xxxxxxxxxxxx>
>---
>Changes from RFC:
>1. Add more description about the max scrub cycle. (Alison) 2. Add more
>description about the min scrub cycle of a region. (Alison) 3. Drop RFC tag.
>
>base-commit: 9f153b7fb5ae45c7d426851f896487927f40e501 cxl/next
>---
> drivers/cxl/core/edac.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/cxl/core/edac.c b/drivers/cxl/core/edac.c index
>2cbc664e5d62..0ef245d0bd9f 100644
>--- a/drivers/cxl/core/edac.c
>+++ b/drivers/cxl/core/edac.c
>@@ -103,10 +103,10 @@ static int cxl_scrub_get_attrbs(struct
>cxl_patrol_scrub_context *cxl_ps_ctx,
> u8 *cap, u16 *cycle, u8 *flags, u8 *min_cycle)
>{
> struct cxl_mailbox *cxl_mbox;
>- u8 min_scrub_cycle = U8_MAX;
> struct cxl_region_params *p;
> struct cxl_memdev *cxlmd;
> struct cxl_region *cxlr;
>+ u8 min_scrub_cycle = 0;
> int i, ret;
>
> if (!cxl_ps_ctx->cxlr) {
>@@ -133,8 +133,12 @@ static int cxl_scrub_get_attrbs(struct
>cxl_patrol_scrub_context *cxl_ps_ctx,
> if (ret)
> return ret;
>
>+ /*
>+ * The min_scrub_cycle of a region is the max of minimum
>scrub
>+ * cycles supported by memdevs that back the region.
>+ */
> if (min_cycle)
>- min_scrub_cycle = min(*min_cycle, min_scrub_cycle);
>+ min_scrub_cycle = max(*min_cycle, min_scrub_cycle);
> }
>
> if (min_cycle)
>--
>2.34.1