[Skiboot] [PATCH 1/8] pci: Add bitmap to know if a pci device has cfg reg filters

Benjamin Herrenschmidt benh at kernel.crashing.org
Tue Jun 6 08:59:17 AEST 2017


This avoids doing a search through the list of all devices on
every config space access to every device under a PHB.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 core/pci-iov.c |  1 +
 core/pci.c     | 10 ++++++++++
 hw/phb3.c      |  9 ++-------
 include/pci.h  |  4 ++++
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/core/pci-iov.c b/core/pci-iov.c
index 14c810b..6abb85a 100644
--- a/core/pci-iov.c
+++ b/core/pci-iov.c
@@ -184,6 +184,7 @@ static void pci_iov_init_VF(struct pci_device *pd, struct pci_device *vf)
 	vf->dn			= NULL;
 	vf->slot		= NULL;
 	vf->parent		= pd;
+	vf->phb			= pd->phb;
 	list_head_init(&vf->pcrf);
 	list_head_init(&vf->children);
 }
diff --git a/core/pci.c b/core/pci.c
index 0adc6d2..5671b69 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -247,6 +247,7 @@ static struct pci_device *pci_scan_one(struct phb *phb, struct pci_device *paren
 		PCIERR(phb, bdfn,"Failed to allocate structure pci_device !\n");
 		goto fail;
 	}
+	pd->phb = phb;
 	pd->bdfn = bdfn;
 	pd->vdid = vdid;
 	pci_cfg_read32(phb, bdfn, PCI_CFG_SUBSYS_VENDOR_ID, &pd->sub_vdid);
@@ -951,6 +952,9 @@ int64_t pci_register_phb(struct phb *phb, int opal_id)
 	init_lock(&phb->lock);
 	list_head_init(&phb->devices);
 
+	phb->filter_map = zalloc(BITMAP_BYTES(0x10000));
+	assert(phb->filter_map);
+
 	return OPAL_SUCCESS;
 }
 
@@ -1764,6 +1768,11 @@ struct pci_cfg_reg_filter *pci_find_cfg_reg_filter(struct pci_device *pd,
 	return NULL;
 }
 
+bool pci_device_has_cfg_reg_filters(struct phb *phb, uint16_t bdfn)
+{
+       return bitmap_tst_bit(*phb->filter_map, bdfn);
+}
+
 struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd,
 						  uint32_t start, uint32_t len,
 						  uint32_t flags,
@@ -1793,6 +1802,7 @@ struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd,
 	if (pd->pcrf_end < (start + len))
 		pd->pcrf_end = start + len;
 	list_add_tail(&pd->pcrf, &pcrf->link);
+	bitmap_set_bit(*pd->phb->filter_map, pd->bdfn);
 
 	return pcrf;
 }
diff --git a/hw/phb3.c b/hw/phb3.c
index b33ed7b..c99f1de 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -236,13 +236,8 @@ static void phb3_pcicfg_filter(struct phb *phb, uint32_t bdfn,
 		return;
 	}
 
-	/* FIXME: It harms the performance to search the PCI
-	 * device which doesn't have any filters at all. So
-	 * it's worthy to maintain a table in PHB to indicate
-	 * the PCI devices who have filters. However, bitmap
-	 * seems not supported by skiboot yet. To implement
-	 * it after bitmap is supported.
-	 */
+	if (!pci_device_has_cfg_reg_filters(phb, bdfn))
+		return;
 	pd = pci_find_dev(phb, bdfn);
 	pcrf = pd ? pci_find_cfg_reg_filter(pd, offset, len) : NULL;
 	if (!pcrf || !pcrf->func)
diff --git a/include/pci.h b/include/pci.h
index dc418a9..1e84b51 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -20,6 +20,7 @@
 #include <opal.h>
 #include <device.h>
 #include <lock.h>
+#include <bitmap.h>
 #include <ccan/list/list.h>
 
 struct pci_device;
@@ -87,6 +88,7 @@ struct pci_device {
 	struct dt_node		*dn;
 	struct pci_slot		*slot;
 	struct pci_device	*parent;
+	struct phb		*phb;
 	struct list_head	children;
 	struct list_node	link;
 };
@@ -343,6 +345,7 @@ struct phb {
 	const struct phb_ops	*ops;
 	struct pci_lsi_state	lstate;
 	uint32_t		mps;
+	bitmap_t		*filter_map;
 
 	/* PCI-X only slot info, for PCI-E this is in the RC bridge */
 	struct pci_slot		*slot;
@@ -424,6 +427,7 @@ extern struct pci_device *pci_walk_dev(struct phb *phb,
 				       void *userdata);
 extern struct pci_device *pci_find_dev(struct phb *phb, uint16_t bdfn);
 extern void pci_restore_bridge_buses(struct phb *phb, struct pci_device *pd);
+extern bool pci_device_has_cfg_reg_filters(struct phb *phb, uint16_t bdfn);
 extern struct pci_cfg_reg_filter *pci_find_cfg_reg_filter(struct pci_device *pd,
 					uint32_t start, uint32_t len);
 extern struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd,
-- 
2.9.4



More information about the Skiboot mailing list