On Tue, Jun 03, 2025 at 12:22:27PM -0500, Terry Bowman wrote: > +static struct pci_dev *sbdf_to_pci(struct cxl_prot_error_info *err_info) > +{ > + unsigned int devfn = PCI_DEVFN(err_info->device, > + err_info->function); > + struct pci_dev *pdev __free(pci_dev_put) = What? Why is it freeing the returned pointer? That should happen in the caller, surely? > + pci_get_domain_bus_and_slot(err_info->segment, > + err_info->bus, > + devfn); > + return pdev; > +} > + > +static void cxl_handle_prot_error(struct cxl_prot_error_info *err_info) > +{ > + struct pci_dev *pdev __free(pci_dev_put) = pci_dev_get(sbdf_to_pci(err_info)); Ok, it does happen in the caller, but dropping and then incrementing the reference count like this is racy. regards, dan carpenter > + > + if (!pdev) { > + pr_err("Failed to find the CXL device\n"); > + return; > + } > + > + /* > + * Internal errors of an RCEC indicate an AER error in an > + * RCH's downstream port. Check and handle them in the CXL.mem > + * device driver. > + */ > + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_EC) > + return pcie_walk_rcec(pdev, cxl_rch_handle_error_iter, err_info); > + > + if (err_info->severity == AER_CORRECTABLE) { > + int aer = pdev->aer_cap; > + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); > + struct device *dev __free(put_device) = get_device(&cxlds->cxlmd->dev); > + > + if (aer) > + pci_clear_and_set_config_dword(pdev, > + aer + PCI_ERR_COR_STATUS, > + 0, PCI_ERR_COR_INTERNAL); > + > + cxl_cor_error_detected(pdev); > + > + pcie_clear_device_status(pdev); > + } else { > + cxl_do_recovery(pdev); > + } > +} > +