From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11AFD322A1A; Fri, 29 Aug 2025 15:34:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756481644; cv=none; b=MmdlCbAwwhWq0rJNOCiKy9iw9rqiMvmErzmZhZhlryaBA2VhcbSSdaaqy3Uox1YC0NPfPaR/9w2s9vnYfTHla+ZLkTBLaPK97jrTzWc82CQWsJ7HDWb6xvmMitHuqbOU5o0JHL/TlUzQUx9lZbC3IieumTWoJAfHaj6k67dSZWQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756481644; c=relaxed/simple; bh=Wkarqdkf6ZyEUqPeiXDncAJYJ0ETWgarIDKcNGEi7CM=; h=Date:From:To:CC:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Nmknh0TSmUAf92wJM2icnrt997icxooVDTNSMccREg9Mud6algKM170DJ1DWfMKNTOiB/a4tfeYX8KiFfQApn1lWFZTXErwzuld3j2Vm+POrJwrzfzZ8K7kSilGx6jqb9pvqPdEnYjIqXyj4KE/oHIerEizT1cJ+U1TLUOA6Aoc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.31]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4cD2Jx4sgLz67ZRh; Fri, 29 Aug 2025 23:30:25 +0800 (CST) Received: from frapeml500008.china.huawei.com (unknown [7.182.85.71]) by mail.maildlp.com (Postfix) with ESMTPS id A1C7114027A; Fri, 29 Aug 2025 23:33:57 +0800 (CST) Received: from localhost (10.203.177.15) by frapeml500008.china.huawei.com (7.182.85.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Fri, 29 Aug 2025 17:33:56 +0200 Date: Fri, 29 Aug 2025 16:33:55 +0100 From: Jonathan Cameron To: Terry Bowman CC: , , , , , , , , , , , , , , , , , , Subject: Re: [PATCH v11 05/23] cxl: Move CXL driver RCH error handling into CONFIG_CXL_RCH_RAS conditional block Message-ID: <20250829163355.00004fda@huawei.com> In-Reply-To: <20250827013539.903682-6-terry.bowman@amd.com> References: <20250827013539.903682-1-terry.bowman@amd.com> <20250827013539.903682-6-terry.bowman@amd.com> X-Mailer: Claws Mail 4.3.0 (GTK 3.24.42; x86_64-w64-mingw32) Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To frapeml500008.china.huawei.com (7.182.85.71) On Tue, 26 Aug 2025 20:35:20 -0500 Terry Bowman wrote: > Restricted CXL Host (RCH) protocol error handling uses a procedure distinct > from the CXL Virtual Hierarchy (VH) handling. This is because of the > differences in the RCH and VH topologies. Improve the maintainability and > add ability to enable/disable RCH handling. > > Move and combine the RCH handling code into a single block conditionally > compiled with the CONFIG_CXL_RCH_RAS kernel config. > > Signed-off-by: Terry Bowman > How painful to move this to a ras_rch.c file and conditionally compile that? Would want to do that is some merged thing with patch 1 though, rather than moving at least some of the code twice. > --- > v10->v11: > - New patch > --- > drivers/cxl/core/ras.c | 175 +++++++++++++++++++++-------------------- > 1 file changed, 90 insertions(+), 85 deletions(-) > > diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c > index 0875ce8116ff..f42f9a255ef8 100644 > --- a/drivers/cxl/core/ras.c > +++ b/drivers/cxl/core/ras.c > @@ -126,6 +126,7 @@ void cxl_ras_exit(void) > cancel_work_sync(&cxl_cper_prot_err_work); > } > > +#ifdef CONFIG_CXL_RCH_RAS > static void cxl_dport_map_rch_aer(struct cxl_dport *dport) > { > resource_size_t aer_phys; > @@ -141,18 +142,6 @@ static void cxl_dport_map_rch_aer(struct cxl_dport *dport) > } > } > > -static void cxl_dport_map_ras(struct cxl_dport *dport) > -{ > - struct cxl_register_map *map = &dport->reg_map; > - struct device *dev = dport->dport_dev; > - > - if (!map->component_map.ras.valid) > - dev_dbg(dev, "RAS registers not found\n"); > - else if (cxl_map_component_regs(map, &dport->regs.component, > - BIT(CXL_CM_CAP_CAP_ID_RAS))) > - dev_dbg(dev, "Failed to map RAS capability.\n"); > -} > - > static void cxl_disable_rch_root_ints(struct cxl_dport *dport) > { > void __iomem *aer_base = dport->regs.dport_aer; > @@ -177,6 +166,95 @@ static void cxl_disable_rch_root_ints(struct cxl_dport *dport) > writel(aer_cmd, aer_base + PCI_ERR_ROOT_COMMAND); > } > > +/* > + * Copy the AER capability registers using 32 bit read accesses. > + * This is necessary because RCRB AER capability is MMIO mapped. Clear the > + * status after copying. > + * > + * @aer_base: base address of AER capability block in RCRB > + * @aer_regs: destination for copying AER capability > + */ > +static bool cxl_rch_get_aer_info(void __iomem *aer_base, > + struct aer_capability_regs *aer_regs) > +{ > + int read_cnt = sizeof(struct aer_capability_regs) / sizeof(u32); > + u32 *aer_regs_buf = (u32 *)aer_regs; > + int n; > + > + if (!aer_base) > + return false; > + > + /* Use readl() to guarantee 32-bit accesses */ > + for (n = 0; n < read_cnt; n++) > + aer_regs_buf[n] = readl(aer_base + n * sizeof(u32)); > + > + writel(aer_regs->uncor_status, aer_base + PCI_ERR_UNCOR_STATUS); > + writel(aer_regs->cor_status, aer_base + PCI_ERR_COR_STATUS); > + > + return true; > +} > + > +/* Get AER severity. Return false if there is no error. */ > +static bool cxl_rch_get_aer_severity(struct aer_capability_regs *aer_regs, > + int *severity) > +{ > + if (aer_regs->uncor_status & ~aer_regs->uncor_mask) { > + if (aer_regs->uncor_status & PCI_ERR_ROOT_FATAL_RCV) > + *severity = AER_FATAL; > + else > + *severity = AER_NONFATAL; > + return true; > + } > + > + if (aer_regs->cor_status & ~aer_regs->cor_mask) { > + *severity = AER_CORRECTABLE; > + return true; > + } > + > + return false; > +} > + > +static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) > +{ > + struct pci_dev *pdev = to_pci_dev(cxlds->dev); > + struct aer_capability_regs aer_regs; > + struct cxl_dport *dport; > + int severity; > + > + struct cxl_port *port __free(put_cxl_port) = > + cxl_pci_find_port(pdev, &dport); > + if (!port) > + return; > + > + if (!cxl_rch_get_aer_info(dport->regs.dport_aer, &aer_regs)) > + return; > + > + if (!cxl_rch_get_aer_severity(&aer_regs, &severity)) > + return; > + > + pci_print_aer(pdev, severity, &aer_regs); > + if (severity == AER_CORRECTABLE) > + cxl_handle_cor_ras(cxlds, dport->regs.ras); > + else > + cxl_handle_ras(cxlds, dport->regs.ras); > +} > +#else > +static inline void cxl_dport_map_rch_aer(struct cxl_dport *dport) { } > +static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { } > +static inline void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) { } > +#endif > + > +static void cxl_dport_map_ras(struct cxl_dport *dport) > +{ > + struct cxl_register_map *map = &dport->reg_map; > + struct device *dev = dport->dport_dev; > + > + if (!map->component_map.ras.valid) > + dev_dbg(dev, "RAS registers not found\n"); > + else if (cxl_map_component_regs(map, &dport->regs.component, > + BIT(CXL_CM_CAP_CAP_ID_RAS))) > + dev_dbg(dev, "Failed to map RAS capability.\n"); > +} > > /** > * cxl_dport_init_ras_reporting - Setup CXL RAS report on this dport > @@ -270,79 +348,6 @@ static bool cxl_handle_ras(struct cxl_dev_state *cxlds, void __iomem *ras_base) > return true; > } > > -/* > - * Copy the AER capability registers using 32 bit read accesses. > - * This is necessary because RCRB AER capability is MMIO mapped. Clear the > - * status after copying. > - * > - * @aer_base: base address of AER capability block in RCRB > - * @aer_regs: destination for copying AER capability > - */ > -static bool cxl_rch_get_aer_info(void __iomem *aer_base, > - struct aer_capability_regs *aer_regs) > -{ > - int read_cnt = sizeof(struct aer_capability_regs) / sizeof(u32); > - u32 *aer_regs_buf = (u32 *)aer_regs; > - int n; > - > - if (!aer_base) > - return false; > - > - /* Use readl() to guarantee 32-bit accesses */ > - for (n = 0; n < read_cnt; n++) > - aer_regs_buf[n] = readl(aer_base + n * sizeof(u32)); > - > - writel(aer_regs->uncor_status, aer_base + PCI_ERR_UNCOR_STATUS); > - writel(aer_regs->cor_status, aer_base + PCI_ERR_COR_STATUS); > - > - return true; > -} > - > -/* Get AER severity. Return false if there is no error. */ > -static bool cxl_rch_get_aer_severity(struct aer_capability_regs *aer_regs, > - int *severity) > -{ > - if (aer_regs->uncor_status & ~aer_regs->uncor_mask) { > - if (aer_regs->uncor_status & PCI_ERR_ROOT_FATAL_RCV) > - *severity = AER_FATAL; > - else > - *severity = AER_NONFATAL; > - return true; > - } > - > - if (aer_regs->cor_status & ~aer_regs->cor_mask) { > - *severity = AER_CORRECTABLE; > - return true; > - } > - > - return false; > -} > - > -static void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) > -{ > - struct pci_dev *pdev = to_pci_dev(cxlds->dev); > - struct aer_capability_regs aer_regs; > - struct cxl_dport *dport; > - int severity; > - > - struct cxl_port *port __free(put_cxl_port) = > - cxl_pci_find_port(pdev, &dport); > - if (!port) > - return; > - > - if (!cxl_rch_get_aer_info(dport->regs.dport_aer, &aer_regs)) > - return; > - > - if (!cxl_rch_get_aer_severity(&aer_regs, &severity)) > - return; > - > - pci_print_aer(pdev, severity, &aer_regs); > - if (severity == AER_CORRECTABLE) > - cxl_handle_cor_ras(cxlds, dport->regs.ras); > - else > - cxl_handle_ras(cxlds, dport->regs.ras); > -} > - > void cxl_cor_error_detected(struct pci_dev *pdev) > { > struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);