]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
rasdaemon: Add page offline support for cxl memory
authorSrinivasulu Thanneeru <sthanneeru.opensrc@micron.com>
Wed, 20 Nov 2024 06:25:28 +0000 (22:25 -0800)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 10 Mar 2025 10:20:41 +0000 (11:20 +0100)
CXL Type 3 device implements a threshold for corrected errors as described in
CXL 3.1 specification section 8.2.9.2.1.2 and 8.2.9.9.11.3.
Device can set the threshold field in the DRAM event descriptor when
it detects corrected errors that meet or exceed the threshold value.

This patch is intended to offline pages for corrected memory errors when the
device sets the threshold in the DRAM event descriptor.
This helps prevent corrected errors from becoming uncorrected.

Record the hpa for given dpa, then do pageoffline for hpa when corrected
errors threshold is set.

Signed-off-by: Srinivasulu Thanneeru <sthanneeru.opensrc@micron.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
ras-cxl-handler.c
ras-page-isolation.c
ras-page-isolation.h

index 67ce32e201b280562c0f7649cf990269faa6912c..bd6b4fa7f09fceeed6a4074b4ea75718b00a6b44 100644 (file)
@@ -12,6 +12,7 @@
 #include <unistd.h>
 
 #include "ras-cxl-handler.h"
+#include "ras-page-isolation.h"
 #include "ras-logger.h"
 #include "ras-record.h"
 #include "ras-report.h"
@@ -917,6 +918,12 @@ int ras_cxl_dram_event_handler(struct trace_seq *s,
        if (trace_seq_printf(s, "dpa:0x%llx ", (unsigned long long)ev.dpa) <= 0)
                return -1;
 
+       if (tep_get_field_val(s, event, "hpa", record, &val, 1) < 0)
+               return -1;
+       ev.hpa = val;
+       if (trace_seq_printf(s, "hpa:0x%llx ", (unsigned long long)ev.hpa) <= 0)
+               return -1;
+
        if (tep_get_field_val(s,  event, "dpa_flags", record, &val, 1) < 0)
                return -1;
        ev.dpa_flags = val;
@@ -1045,6 +1052,13 @@ int ras_cxl_dram_event_handler(struct trace_seq *s,
                }
        }
 
+#ifdef HAVE_MEMORY_CE_PFA
+       /* Page offline for CE when threeshold is set */
+       if (!(ev.descriptor & CXL_GMER_EVT_DESC_UNCORRECTABLE_EVENT) &&
+           (ev.descriptor & CXL_GMER_EVT_DESC_THRESHOLD_EVENT))
+               ras_hw_threshold_pageoffline(ev.hpa);
+#endif
+
        /* Insert data into the SGBD */
 #ifdef HAVE_SQLITE3
        ras_store_cxl_dram_event(ras, &ev);
index 30572e4bfa47dc28a79ea2cddd00df5fa023e589..2166f5cd0023214cfc5e50346370847abd7ca266 100644 (file)
@@ -429,6 +429,13 @@ void ras_record_page_error(unsigned long long addr, unsigned int count, time_t t
        }
 }
 
+void ras_hw_threshold_pageoffline(unsigned long long addr)
+{
+       time_t now = time(NULL);
+
+       ras_record_page_error(addr, threshold.val, now);
+}
+
 /* memory page CE threshold policy ends */
 
 /* memory row CE threshold policy starts */
index a9bae13bf428e2f337fbc74bc33a588abe1b7a62..215f26dfabe036d6bbedba95cff7aa469787ad1b 100644 (file)
@@ -117,6 +117,7 @@ struct isolation {
 void ras_page_account_init(void);
 void ras_record_page_error(unsigned long long addr,
                           unsigned int count, time_t time);
+void ras_hw_threshold_pageoffline(unsigned long long addr);
 void ras_row_account_init(void);
 void ras_record_row_error(const char *detail, unsigned int count, time_t time,
                          unsigned long long addr);