From: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
To: <linux-pci@vger.kernel.org>
Cc: Bjorn Helgaas <helgaas@kernel.org>,
Rajat Jain <rajatja@google.com>, <linux@yadro.com>,
Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
Subject: [PATCH RFC v3 16/21] PCI: Calculate fixed areas of bridge windows based on fixed BARs
Date: Mon, 4 Feb 2019 18:35:56 +0300 [thread overview]
Message-ID: <20190204153601.7576-17-s.miroshnichenko@yadro.com> (raw)
In-Reply-To: <20190204153601.7576-1-s.miroshnichenko@yadro.com>
For every (IO, MEM, MEM64) bridge window, count the fixed resources of
its children endpoints and children bridge windows:
| <- BAR -> | | <- child bus fixed_range_hard -> | | <- fixed BAR -> |
| <- bus's fixed_range_hard -> |
| <- bus's bridge window -> |
These ranges will be later used to arrange bridge windows in a way which
covers every immovable BAR as well as the movable ones during hotplug.
Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
---
drivers/pci/pci.h | 14 +++++++
drivers/pci/probe.c | 82 +++++++++++++++++++++++++++++++++++++++++
drivers/pci/setup-bus.c | 17 +++++++++
include/linux/pci.h | 6 +++
4 files changed, 119 insertions(+)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 56b905068ac5..14e3ebe68010 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -364,6 +364,20 @@ static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
return dev->error_state == pci_channel_io_perm_failure;
}
+static inline int pci_get_bridge_resource_idx(struct resource *r)
+{
+ int idx = 1;
+
+ if (r->flags & IORESOURCE_IO)
+ idx = 0;
+ else if (!(r->flags & IORESOURCE_PREFETCH))
+ idx = 1;
+ else if (r->flags & IORESOURCE_MEM_64)
+ idx = 2;
+
+ return idx;
+}
+
/* pci_dev priv_flags */
#define PCI_DEV_ADDED 0
#define PCI_DEV_IGNORE 1
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c1d88721697e..cc302a5798bf 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -500,6 +500,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
{
struct pci_bus *b;
+ int idx;
b = kzalloc(sizeof(*b), GFP_KERNEL);
if (!b)
@@ -516,6 +517,11 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
if (parent)
b->domain_nr = parent->domain_nr;
#endif
+ for (idx = 0; idx < PCI_BRIDGE_RESOURCE_NUM; ++idx) {
+ b->fixed_range_hard[idx].start = (resource_size_t)-1;
+ b->fixed_range_hard[idx].end = 0;
+ }
+
return b;
}
@@ -3261,6 +3267,81 @@ static void pci_setup_bridges(struct pci_bus *bus)
pci_setup_bridge(bus);
}
+static void pci_bus_update_fixed_range_hard(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+ int idx;
+ resource_size_t start, end;
+
+ for (idx = 0; idx < PCI_BRIDGE_RESOURCE_NUM; ++idx) {
+ bus->fixed_range_hard[idx].start = (resource_size_t)-1;
+ bus->fixed_range_hard[idx].end = 0;
+ }
+
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->subordinate)
+ pci_bus_update_fixed_range_hard(dev->subordinate);
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ int i;
+
+ for (i = 0; i < PCI_BRIDGE_RESOURCES; ++i) {
+ struct resource *r = &dev->resource[i];
+
+ if (!r->flags || (r->flags & IORESOURCE_UNSET) || !r->parent)
+ continue;
+
+ if (r->flags & IORESOURCE_PCI_FIXED) {
+ idx = pci_get_bridge_resource_idx(r);
+ start = bus->fixed_range_hard[idx].start;
+ end = bus->fixed_range_hard[idx].end;
+
+ if (start > r->start)
+ start = r->start;
+ if (end < r->end)
+ end = r->end;
+
+ if (bus->fixed_range_hard[idx].start != start ||
+ bus->fixed_range_hard[idx].end != end) {
+ dev_dbg(&bus->dev, "%s: Found fixed 0x%llx-0x%llx in %s, expand the fixed bridge window %d to 0x%llx-0x%llx\n",
+ __func__,
+ (unsigned long long)r->start,
+ (unsigned long long)r->end,
+ dev_name(&dev->dev), idx,
+ (unsigned long long)start,
+ (unsigned long long)end);
+ bus->fixed_range_hard[idx].start = start;
+ bus->fixed_range_hard[idx].end = end;
+ }
+ }
+ }
+
+ if (dev->subordinate) {
+ struct pci_bus *child = dev->subordinate;
+
+ for (idx = 0; idx < PCI_BRIDGE_RESOURCE_NUM; ++idx) {
+ start = bus->fixed_range_hard[idx].start;
+ end = bus->fixed_range_hard[idx].end;
+
+ if (start > child->fixed_range_hard[idx].start)
+ start = child->fixed_range_hard[idx].start;
+ if (end < child->fixed_range_hard[idx].end)
+ end = child->fixed_range_hard[idx].end;
+
+ if (start < bus->fixed_range_hard[idx].start ||
+ end > bus->fixed_range_hard[idx].end) {
+ dev_dbg(&bus->dev, "%s: Expand the fixed bridge window %d from %s to 0x%llx-0x%llx\n",
+ __func__, idx, dev_name(&child->dev),
+ (unsigned long long)start,
+ (unsigned long long)end);
+ bus->fixed_range_hard[idx].start = start;
+ bus->fixed_range_hard[idx].end = end;
+ }
+ }
+ }
+ }
+}
+
static struct pci_dev *pci_find_next_new_device(struct pci_bus *bus)
{
struct pci_dev *dev;
@@ -3361,6 +3442,7 @@ unsigned int pci_rescan_bus(struct pci_bus *bus)
pci_bus_rescan_prepare(root);
max = pci_scan_child_bus(root);
+ pci_bus_update_fixed_range_hard(root);
pci_reassign_root_bus_resources(root);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a1b1b1cda3e8..59af85029869 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -916,9 +916,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
resource_size_t children_add_size = 0;
resource_size_t min_align, align;
+ resource_size_t fixed_start = bus->fixed_range_hard[0].start;
+ resource_size_t fixed_end = bus->fixed_range_hard[0].end;
+ resource_size_t fixed_size = (fixed_start < fixed_end) ?
+ (fixed_end - fixed_start + 1) : 0;
+
if (!b_res)
return;
+ if (min_size < fixed_size)
+ min_size = fixed_size;
+
min_align = window_alignment(bus, IORESOURCE_IO);
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
@@ -1027,6 +1035,15 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
resource_size_t children_add_size = 0;
resource_size_t children_add_align = 0;
resource_size_t add_align = 0;
+ bool is_mem64 = (mask & IORESOURCE_MEM_64);
+
+ resource_size_t fixed_start = bus->fixed_range_hard[is_mem64 ? 2 : 1].start;
+ resource_size_t fixed_end = bus->fixed_range_hard[is_mem64 ? 2 : 1].end;
+ resource_size_t fixed_size = (fixed_start < fixed_end) ?
+ (fixed_end - fixed_start + 1) : 0;
+
+ if (min_size < fixed_size)
+ min_size = fixed_size;
if (!b_res)
return -ENOSPC;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5c739bf0c94f..e2b4742c477a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -569,6 +569,12 @@ struct pci_bus {
struct list_head resources; /* Address space routed to this bus */
struct resource busn_res; /* Bus numbers routed to this bus */
+ /*
+ * If there are fixed resources in the bridge window, the hard range
+ * contains the lowest and the highest addresses of them.
+ */
+ struct resource fixed_range_hard[PCI_BRIDGE_RESOURCE_NUM];
+
struct pci_ops *ops; /* Configuration access functions */
struct msi_controller *msi; /* MSI controller */
void *sysdata; /* Hook for sys-specific extension */
--
2.20.1
next prev parent reply other threads:[~2019-02-04 15:36 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-04 15:35 [PATCH RFC v3 00/21] PCI: Allow BAR movement during hotplug Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 01/21] PCI: Fix writing invalid BARs during pci_restore_state() Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 02/21] PCI: Fix race condition in pci_enable/disable_device() Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 03/21] PCI: Enable bridge's I/O and MEM access for hotplugged devices Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 04/21] PCI: Define PCI-specific version of the release_child_resources() Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 05/21] PCI: hotplug: Add a flag for the movable BARs feature Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 06/21] PCI: Pause the devices with movable BARs during rescan Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 07/21] PCI: Wake up bridges during rescan when movable BARs enabled Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 08/21] nvme-pci: Handle movable BARs Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 09/21] PCI: Mark immovable BARs with PCI_FIXED Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 10/21] PCI: Fix assigning of fixed prefetchable resources Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 11/21] PCI: Release and reassign the root bridge resources during rescan Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 12/21] PCI: Don't allow hotplugged devices to steal resources Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 13/21] PCI: Include fixed BARs into the bus size calculating Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 14/21] PCI: Don't reserve memory for hotplug when enabled movable BARs Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 15/21] PCI: Allow the failed resources to be reassigned later Sergey Miroshnichenko
2019-02-04 15:35 ` Sergey Miroshnichenko [this message]
2019-02-04 15:35 ` [PATCH RFC v3 17/21] PCI: Calculate boundaries for bridge windows Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 18/21] PCI: Make sure bridge windows include their fixed BARs Sergey Miroshnichenko
2019-02-04 15:35 ` [PATCH RFC v3 19/21] PCI: Prioritize fixed BAR assigning over the movable ones Sergey Miroshnichenko
2019-02-04 15:36 ` [PATCH RFC v3 20/21] PCI: pciehp: Add support for the movable BARs feature Sergey Miroshnichenko
2019-02-04 15:36 ` [PATCH RFC v3 21/21] powerpc/pci: Fix crash with enabled movable BARs Sergey Miroshnichenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190204153601.7576-17-s.miroshnichenko@yadro.com \
--to=s.miroshnichenko@yadro.com \
--cc=helgaas@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@yadro.com \
--cc=rajatja@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).