Hi Bjorn, > On Dec 5, 2020, at 1:30 PM, Bjorn Helgaas <helgaas@xxxxxxxxxx> wrote: > > On Fri, Dec 04, 2020 at 05:17:58PM +0000, Kelley, Sean V wrote: >>> On Dec 3, 2020, at 4:01 PM, Bjorn Helgaas <helgaas@xxxxxxxxxx> wrote: >>> On Thu, Dec 03, 2020 at 12:51:40AM +0000, Kelley, Sean V wrote: >>>>> On Dec 2, 2020, at 3:44 PM, Bjorn Helgaas <helgaas@xxxxxxxxxx> wrote: >>>>> On Fri, Nov 20, 2020 at 04:10:33PM -0800, Sean V Kelley wrote: >>>>>> From: Qiuxu Zhuo <qiuxu.zhuo@xxxxxxxxx> >>>>>> >>>>>> When attempting error recovery for an RCiEP associated with an RCEC device, >>>>>> there needs to be a way to update the Root Error Status, the Uncorrectable >>>>>> Error Status and the Uncorrectable Error Severity of the parent RCEC. In >>>>>> some non-native cases in which there is no OS-visible device associated >>>>>> with the RCiEP, there is nothing to act upon as the firmware is acting >>>>>> before the OS. >>>>>> >>>>>> Add handling for the linked RCEC in AER/ERR while taking into account >>>>>> non-native cases. >>>>>> >>>>>> Co-developed-by: Sean V Kelley <sean.v.kelley@xxxxxxxxx> >>>>>> Link: https://lore.kernel.org/r/20201002184735.1229220-12-seanvk.dev@xxxxxxxxxxxxxxxx >>>>>> Signed-off-by: Sean V Kelley <sean.v.kelley@xxxxxxxxx> >>>>>> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@xxxxxxxxx> >>>>>> Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> >>>>>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> >>>>>> --- >>>>>> drivers/pci/pcie/aer.c | 46 +++++++++++++++++++++++++++++++----------- >>>>>> drivers/pci/pcie/err.c | 20 +++++++++--------- >>>>>> 2 files changed, 44 insertions(+), 22 deletions(-) >>>>>> >>>>>> diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c >>>>>> index 0ba0b47ae751..51389a6ee4ca 100644 >>>>>> --- a/drivers/pci/pcie/aer.c >>>>>> +++ b/drivers/pci/pcie/aer.c >>>>>> @@ -1358,29 +1358,51 @@ static int aer_probe(struct pcie_device *dev) >>>>>> */ >>>>>> static pci_ers_result_t aer_root_reset(struct pci_dev *dev) >>>>>> { >>>>>> - int aer = dev->aer_cap; >>>>>> + int type = pci_pcie_type(dev); >>>>>> + struct pci_dev *root; >>>>>> + int aer = 0; >>>>>> + int rc = 0; >>>>>> u32 reg32; >>>>>> - int rc; >>>>>> >>>>>> - if (pcie_aer_is_native(dev)) { >>>>>> + if (type == PCI_EXP_TYPE_RC_END) >>>>>> + /* >>>>>> + * The reset should only clear the Root Error Status >>>>>> + * of the RCEC. Only perform this for the >>>>>> + * native case, i.e., an RCEC is present. >>>>>> + */ >>>>>> + root = dev->rcec; >>>>>> + else >>>>>> + root = dev; >>>>>> + >>>>>> + if (root) >>>>>> + aer = dev->aer_cap; >>>>>> + >>>>>> + if ((aer) && pcie_aer_is_native(dev)) { >>>>>> /* Disable Root's interrupt in response to error messages */ >>>>>> - pci_read_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, ®32); >>>>>> + pci_read_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, ®32); >>>>>> reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; >>>>>> - pci_write_config_dword(dev, aer + PCI_ERR_ROOT_COMMAND, reg32); >>>>>> + pci_write_config_dword(root, aer + PCI_ERR_ROOT_COMMAND, reg32); >>>>>> } >>>>>> >>>>>> - rc = pci_bus_error_reset(dev); >>>>>> - pci_info(dev, "Root Port link has been reset (%d)\n", rc); >>>>>> + if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) { >>>>>> + if (pcie_has_flr(dev)) { >>>>>> + rc = pcie_flr(dev); >>>>>> + pci_info(dev, "has been reset (%d)\n", rc); >>>>> >>>>> Maybe: >>>>> >>>>> + } else { >>>>> + rc = -ENOTTY; >>>>> + pci_info(dev, "not reset (no FLR support)\n"); >>>>> >>>>> Or do we want to pretend the device was reset and return >>>>> PCI_ERS_RESULT_RECOVERED? >>>> >>>> We are currently doing the latter now with the default of rc = 0 >>>> above and so I’m not sure the extra detail here on the absence of >>>> FLR support is of value. >>> >>> So to make sure I understand the proposal here, for RCECs and RCiEPs >>> that don't support FLR, you're saying you want to continue silently >>> and return PCI_ERS_RESULT_RECOVERED and let the drivers assume their >>> device was reset when it was not? >> >> The setting of the ‘rc’ on the FLR support is fine to add to the >> else condition. I had simply recalled in earlier discussion that >> pcie_has_flr() was needed due to quirky behavior in some hardware >> and so was not sure that detail of having or not having flr was in >> fact consitent/accurate. > > I think we should do the following, unless you object: > > if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) { > if (pcie_has_flr(dev)) { > rc = pcie_flr(dev); > pci_info(dev, "has been reset (%d)\n", rc); > } else { > pci_info(dev, "not reset (no FLR support)\n"); > rc = -ENOTTY; > } > } else { > rc = pci_bus_error_reset(dev); > pci_info(dev, "Root Port link has been reset (%d)\n", rc); > } > ... > return rc ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; > > Sorry, I should have done that in the proposed patch earlier; it's > what I was *thinking* but didn't get it transcribed into the code. Looks good to me. Thanks, Sean > > Bjorn