summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-03 17:27:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-03 17:27:42 -0700
commit8c073517a992124e385040c0da0df809abfa8f61 (patch)
treeb0b3f2c4c6cf96ca358d58d8376d4b5e8e89eba1 /drivers/pci
parent03ffbcdd7898c0b5299efeb9f18de927487ec1cf (diff)
parentdf65c1bcd9b7b639177a5a15da1b8dc3bee4f5fa (diff)
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 PCI updates from Thomas Gleixner: "This update provides the seperation of x86 PCI accessors from the global PCI lock in the generic PCI config space accessors. The reasons for this are: - x86 has it's own PCI config lock for various reasons, so the accessors have to lock two locks nested. - The ECAM (mmconfig) access to the extended configuration space does not require locking. The existing generic locking causes a massive lock contention when accessing the extended config space of the Uncore facility for performance monitoring. The commit which switched the access to the primary config space over to ECAM mode has been removed from the branch, so the primary config space is still accessed with type1 accessors properly serialized by the x86 internal locking. Bjorn agreed on merging this through the x86 tree" * 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/PCI: Select CONFIG_PCI_LOCKLESS_CONFIG PCI: Provide Kconfig option for lockless config space accessors x86/PCI/ce4100: Properly lock accessor functions x86/PCI: Abort if legacy init fails x86/PCI: Remove duplicate defines
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig3
-rw-r--r--drivers/pci/access.c16
2 files changed, 15 insertions, 4 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index e0cacb7b8563..c32a77fc8b03 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -86,6 +86,9 @@ config PCI_ATS
config PCI_ECAM
bool
+config PCI_LOCKLESS_CONFIG
+ bool
+
config PCI_IOV
bool "PCI IOV support"
depends on PCI
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index c80e37a69305..913d6722ece9 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -25,6 +25,14 @@ DEFINE_RAW_SPINLOCK(pci_lock);
#define PCI_word_BAD (pos & 1)
#define PCI_dword_BAD (pos & 3)
+#ifdef CONFIG_PCI_LOCKLESS_CONFIG
+# define pci_lock_config(f) do { (void)(f); } while (0)
+# define pci_unlock_config(f) do { (void)(f); } while (0)
+#else
+# define pci_lock_config(f) raw_spin_lock_irqsave(&pci_lock, f)
+# define pci_unlock_config(f) raw_spin_unlock_irqrestore(&pci_lock, f)
+#endif
+
#define PCI_OP_READ(size, type, len) \
int pci_bus_read_config_##size \
(struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
@@ -33,10 +41,10 @@ int pci_bus_read_config_##size \
unsigned long flags; \
u32 data = 0; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
- raw_spin_lock_irqsave(&pci_lock, flags); \
+ pci_lock_config(flags); \
res = bus->ops->read(bus, devfn, pos, len, &data); \
*value = (type)data; \
- raw_spin_unlock_irqrestore(&pci_lock, flags); \
+ pci_unlock_config(flags); \
return res; \
}
@@ -47,9 +55,9 @@ int pci_bus_write_config_##size \
int res; \
unsigned long flags; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
- raw_spin_lock_irqsave(&pci_lock, flags); \
+ pci_lock_config(flags); \
res = bus->ops->write(bus, devfn, pos, len, value); \
- raw_spin_unlock_irqrestore(&pci_lock, flags); \
+ pci_unlock_config(flags); \
return res; \
}