From patchwork Mon Jun 5 22:59:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 771498 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3whVdz0y8dz9s5L for ; Tue, 6 Jun 2017 09:00:23 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3whVdz08vDzDqLl for ; Tue, 6 Jun 2017 09:00:23 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3whVdc3vRJzDqFR for ; Tue, 6 Jun 2017 09:00:04 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v55MxVn1025839; Mon, 5 Jun 2017 17:59:32 -0500 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Tue, 6 Jun 2017 08:59:17 +1000 Message-Id: <20170605225924.11416-1-benh@kernel.crashing.org> X-Mailer: git-send-email 2.9.4 Subject: [Skiboot] [PATCH 1/8] pci: Add bitmap to know if a pci device has cfg reg filters X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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 --- 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 #include #include +#include #include 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,