From: Shawn Lin <shawn.lin@rock-chips.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org, Shawn Lin <shawn.lin@rock-chips.com>
Subject: [PATCH v5] PCI: use IDA to manage domain number if not getting it from DT
Date: Tue, 27 Jun 2017 08:31:13 +0800 [thread overview]
Message-ID: <1498523473-157373-1-git-send-email-shawn.lin@rock-chips.com> (raw)
If not getting domain number from DT, the domain number will
keep increasing once doing unbind/bind RC drivers. This could
introduce pointless tree view of lspci as shows below:
-+-[0001:00]---00.0-[01]----00.0
\-[0000:00]-
The more test we do, the lengthier it would be. The more serious
issue is that if attaching two hierarchies for two different domains
belonging to two root bridges, so when doing unbind/bind test for one
of them and keep the other, then the domain number would finally
overflow and make the two hierarchies of devices share the some domain
number but actually they shouldn't. So it looks like we need to invent
a new indexing ID mechanism to manage domain number. This patch
introduces idr to achieve our purpose.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v5:
- fix Bjorn's comments for v3 as actually I didn't address his comments
for v3 when posted my v4.
v3: https://patchwork.kernel.org/patch/9742003/
For ACPI case, we never use DT or IDA to get domain numbers and
acpi_pci_bus_find_domain_nr would return the proper value we need
whether _SEG exist or not. For DT or IDA, we hope bridges use one of
them consistently, and this is actually what the pre-existing code
did. So I remove ida_domain now since it complicated the logic of the
code and we could just make use_dt_domains global instead to slightly
achieve our purpose.
Changes in v4:
- make domain_nr depends on CONFIG_PCI_DOMAINS instead of
CONFIG_PCI_DOMAINS_GENERIC.
Changes in v3:
- make ida_domain a system-wide property and check it in the code to
combine with use_dt_domains. Also update the comment there.
Changes in v2:
- add a remove wrapper
- rename use_dt_domains to ida_domain and set this bit
in pci_get_new_domain_nr and test it in the remove wrapper.
drivers/pci/pci.c | 13 ++++++++++---
drivers/pci/remove.c | 2 ++
include/linux/pci.h | 7 +++++--
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b58a6b3..9953eaf 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/dmi.h>
+#include <linux/idr.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_pci.h>
@@ -5305,17 +5306,23 @@ static void pci_no_domains(void)
}
#ifdef CONFIG_PCI_DOMAINS
-static atomic_t __domain_nr = ATOMIC_INIT(-1);
+static DEFINE_IDA(__domain_nr);
int pci_get_new_domain_nr(void)
{
- return atomic_inc_return(&__domain_nr);
+ return ida_simple_get(&__domain_nr, 0, sizeof(u64), GFP_KERNEL);
+}
+
+static int use_dt_domains = -1;
+void pci_put_domain_nr(struct pci_bus *bus)
+{
+ if (acpi_disabled && use_dt_domains != 1)
+ ida_simple_remove(&__domain_nr, bus->domain_nr);
}
#ifdef CONFIG_PCI_DOMAINS_GENERIC
static int of_pci_bus_find_domain_nr(struct device *parent)
{
- static int use_dt_domains = -1;
int domain = -1;
if (parent)
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 73a03d3..01dd1b4 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -157,6 +157,8 @@ void pci_remove_root_bus(struct pci_bus *bus)
list_for_each_entry_safe(child, tmp,
&bus->devices, bus_list)
pci_remove_bus_device(child);
+
+ pci_put_domain_nr(bus);
pci_remove_bus(bus);
host_bridge->bus = NULL;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 18cc70a..d6be9596 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -523,7 +523,7 @@ struct pci_bus {
unsigned char primary; /* number of primary bridge */
unsigned char max_bus_speed; /* enum pci_bus_speed */
unsigned char cur_bus_speed; /* enum pci_bus_speed */
-#ifdef CONFIG_PCI_DOMAINS_GENERIC
+#ifdef CONFIG_PCI_DOMAINS
int domain_nr;
#endif
@@ -1466,11 +1466,14 @@ static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity)
#ifdef CONFIG_PCI_DOMAINS
extern int pci_domains_supported;
int pci_get_new_domain_nr(void);
+void pci_put_domain_nr(struct pci_bus *bus);
#else
enum { pci_domains_supported = 0 };
static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
-static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
+static inline int pci_get_new_domain_nr(void)
+{ return -ENOSYS; }
+static inline void pci_put_domain_nr(struct pci_bus *bus) { }
#endif /* CONFIG_PCI_DOMAINS */
/*
--
1.9.1
next reply other threads:[~2017-06-27 0:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-27 0:31 Shawn Lin [this message]
2017-08-11 21:17 ` [PATCH v5] PCI: use IDA to manage domain number if not getting it from DT Bjorn Helgaas
2017-08-15 7:01 ` Shawn Lin
2017-08-15 11:43 ` Lorenzo Pieralisi
2017-08-15 12:23 ` Bjorn Helgaas
2017-08-15 17:50 ` Lorenzo Pieralisi
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=1498523473-157373-1-git-send-email-shawn.lin@rock-chips.com \
--to=shawn.lin@rock-chips.com \
--cc=bhelgaas@google.com \
--cc=linux-pci@vger.kernel.org \
/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).