Re: [PATCHv2 0/5] aer handling fixups

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 11, 2021 at 09:02:39PM +0100, Hinko Kocevar wrote:
> Attached are the messages.
> 
> Thanks!

Thank you. It kind of looks like the frequent ext capabilty lookup might
just be really slow for some reason. Could you try the following patch
and let me know if this improves the CPU lockup?

---
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 5c59365092fa..8a61a9365c28 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -106,6 +106,7 @@ void pci_pm_init(struct pci_dev *dev);
 void pci_ea_init(struct pci_dev *dev);
 void pci_msi_init(struct pci_dev *dev);
 void pci_msix_init(struct pci_dev *dev);
+void pci_vc_init(struct pci_dev *dev);
 void pci_allocate_cap_save_buffers(struct pci_dev *dev);
 void pci_free_cap_save_buffers(struct pci_dev *dev);
 bool pci_bridge_d3_possible(struct pci_dev *dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 953f15abc850..56992a42bac6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2401,6 +2401,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
 	pci_aer_init(dev);		/* Advanced Error Reporting */
 	pci_dpc_init(dev);		/* Downstream Port Containment */
 	pci_rcec_init(dev);		/* Root Complex Event Collector */
+	pci_vc_init(dev);		/* Virtual Channel */
 
 	pcie_report_downtraining(dev);
 
diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
index 5fc59ac31145..76ac118b9b5d 100644
--- a/drivers/pci/vc.c
+++ b/drivers/pci/vc.c
@@ -357,7 +357,7 @@ int pci_save_vc_state(struct pci_dev *dev)
 		int pos, ret;
 		struct pci_cap_saved_state *save_state;
 
-		pos = pci_find_ext_capability(dev, vc_caps[i].id);
+		pos = dev->vc_caps[i];
 		if (!pos)
 			continue;
 
@@ -394,9 +394,12 @@ void pci_restore_vc_state(struct pci_dev *dev)
 		int pos;
 		struct pci_cap_saved_state *save_state;
 
-		pos = pci_find_ext_capability(dev, vc_caps[i].id);
+		pos = dev->vc_caps[i];
+		if (!pos)
+			continue;
+
 		save_state = pci_find_saved_ext_cap(dev, vc_caps[i].id);
-		if (!save_state || !pos)
+		if (!save_state)
 			continue;
 
 		pci_vc_do_save_buffer(dev, pos, save_state, false);
@@ -415,7 +418,7 @@ void pci_allocate_vc_save_buffers(struct pci_dev *dev)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(vc_caps); i++) {
-		int len, pos = pci_find_ext_capability(dev, vc_caps[i].id);
+		int len, pos = dev->vc_caps[i];
 
 		if (!pos)
 			continue;
@@ -426,3 +429,11 @@ void pci_allocate_vc_save_buffers(struct pci_dev *dev)
 				vc_caps[i].name);
 	}
 }
+
+void pci_vc_init(struct pci_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vc_caps); i++)
+		dev->vc_caps[i] = pci_find_ext_capability(dev, vc_caps[i].id);
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b32126d26997..7a3aa7e4d6f8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -501,6 +501,7 @@ struct pci_dev {
 	struct pci_p2pdma *p2pdma;
 #endif
 	u16		acs_cap;	/* ACS Capability offset */
+	u16		vc_caps[3];	/* Virtual Channel capability offsets */
 	phys_addr_t	rom;		/* Physical address if not from BAR */
 	size_t		romlen;		/* Length if not from BAR */
 	char		*driver_override; /* Driver name to force a match */
--



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux