]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
EDAC/skx_common: Add SubChannel support to ADXL decode
authorQiuxu Zhuo <qiuxu.zhuo@intel.com>
Thu, 21 May 2026 07:31:10 +0000 (15:31 +0800)
committerTony Luck <tony.luck@intel.com>
Fri, 29 May 2026 15:34:12 +0000 (08:34 -0700)
Diamond Rapids server RRL (Retry Read error Log) operates at sub-channel
granularity. Add SubChannel support to ADXL decoding in preparation for
enabling this feature.

Also introduce adxl_component_required() to validate mandatory ADXL
components to improve code readability.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Link: https://patch.msgid.link/20260521073112.3881223-7-qiuxu.zhuo@intel.com
drivers/edac/skx_common.c
drivers/edac/skx_common.h

index f769a354ea45a8527987921d353cbe3ad9722131..4d832f02fb596c73045dc9b8de458caf60e21662 100644 (file)
@@ -31,10 +31,12 @@ static const char * const component_names[] = {
        [INDEX_CHANNEL]         = "ChannelId",
        [INDEX_DIMM]            = "DimmSlotId",
        [INDEX_CS]              = "ChipSelect",
+       [INDEX_SUBCH]           = "SubChId",
        [INDEX_NM_MEMCTRL]      = "NmMemoryControllerId",
        [INDEX_NM_CHANNEL]      = "NmChannelId",
        [INDEX_NM_DIMM]         = "NmDimmSlotId",
        [INDEX_NM_CS]           = "NmChipSelect",
+       [INDEX_NM_SUBCH]        = "NmSubChId",
 };
 
 static int component_indices[ARRAY_SIZE(component_names)];
@@ -43,6 +45,7 @@ static const char * const *adxl_component_names;
 static u64 *adxl_values;
 static char *adxl_msg;
 static unsigned long adxl_nm_bitmap;
+static unsigned long adxl_bitmap;
 
 static char skx_msg[MSG_SIZE];
 static skx_decode_f driver_decode;
@@ -288,6 +291,15 @@ void skx_show_rrl(struct decoded_addr *res, char *msg, int len, bool scrub_err)
 }
 EXPORT_SYMBOL_GPL(skx_show_rrl);
 
+static bool adxl_component_required(int idx)
+{
+       return idx == INDEX_SOCKET ||
+              idx == INDEX_MEMCTRL ||
+              idx == INDEX_CHANNEL ||
+              idx == INDEX_DIMM ||
+              idx == INDEX_CS;
+}
+
 int skx_adxl_get(void)
 {
        const char * const *names;
@@ -306,12 +318,14 @@ int skx_adxl_get(void)
 
                                if (i >= INDEX_NM_FIRST)
                                        adxl_nm_bitmap |= 1 << i;
+                               else
+                                       adxl_bitmap |= 1 << i;
 
                                break;
                        }
                }
 
-               if (!names[j] && i < INDEX_NM_FIRST)
+               if (!names[j] && adxl_component_required(i))
                        goto err;
        }
 
@@ -438,11 +452,15 @@ static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src)
                               (int)adxl_values[component_indices[INDEX_NM_DIMM]] : -1;
                res->cs      = (adxl_nm_bitmap & BIT_NM_CS) ?
                               (int)adxl_values[component_indices[INDEX_NM_CS]] : -1;
+               res->subch   = (adxl_nm_bitmap & BIT_NM_SUBCH) ?
+                              (int)adxl_values[component_indices[INDEX_NM_SUBCH]] : -1;
        } else {
                res->imc     = (int)adxl_values[component_indices[INDEX_MEMCTRL]];
                res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]];
                res->dimm    = (int)adxl_values[component_indices[INDEX_DIMM]];
                res->cs      = (int)adxl_values[component_indices[INDEX_CS]];
+               res->subch   = (adxl_bitmap & BIT_SUBCH) ?
+                              (int)adxl_values[component_indices[INDEX_SUBCH]] : -1;
        }
 
        if (res->imc < 0) {
index eea2d95cc0ac615953e9dfa40a38fdc8a1d64ee6..38d96bf71fd94159481096e38fafc915fd554572 100644 (file)
@@ -210,11 +210,13 @@ enum {
        INDEX_CHANNEL,
        INDEX_DIMM,
        INDEX_CS,
+       INDEX_SUBCH,
        INDEX_NM_FIRST,
        INDEX_NM_MEMCTRL = INDEX_NM_FIRST,
        INDEX_NM_CHANNEL,
        INDEX_NM_DIMM,
        INDEX_NM_CS,
+       INDEX_NM_SUBCH,
        INDEX_MAX
 };
 
@@ -225,10 +227,12 @@ enum error_source {
        ERR_SRC_NOT_MEMORY,
 };
 
+#define BIT_SUBCH      BIT_ULL(INDEX_SUBCH)
 #define BIT_NM_MEMCTRL BIT_ULL(INDEX_NM_MEMCTRL)
 #define BIT_NM_CHANNEL BIT_ULL(INDEX_NM_CHANNEL)
 #define BIT_NM_DIMM    BIT_ULL(INDEX_NM_DIMM)
 #define BIT_NM_CS      BIT_ULL(INDEX_NM_CS)
+#define BIT_NM_SUBCH   BIT_ULL(INDEX_NM_SUBCH)
 
 struct decoded_addr {
        struct mce *mce;
@@ -242,6 +246,7 @@ struct decoded_addr {
        int     chanways;
        int     dimm;
        int     cs;
+       int     subch;
        int     rank;
        int     channel_rank;
        u64     rank_address;