Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1589474 > unrolled thread
| Started by | Rui Wang <rui.y.wang@intel.com> |
|---|---|
| First post | 2017-02-28 15:00 +0100 |
| Last post | 2017-03-01 11:50 +0100 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v2 0/2] Improvement on ioapic hotplug Rui Wang <rui.y.wang@intel.com> - 2017-02-28 15:00 +0100
[PATCH v2 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps Rui Wang <rui.y.wang@intel.com> - 2017-02-28 15:00 +0100
[tip:x86/urgent] x86/ioapic: Split IOAPIC hot-removal into two steps tip-bot for Rui Wang <tipbot@zytor.com> - 2017-03-01 11:50 +0100
[PATCH v2 1/2] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC Rui Wang <rui.y.wang@intel.com> - 2017-02-28 15:00 +0100
[tip:x86/urgent] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC tip-bot for Rui Wang <tipbot@zytor.com> - 2017-03-01 11:50 +0100
| From | Rui Wang <rui.y.wang@intel.com> |
|---|---|
| Date | 2017-02-28 15:00 +0100 |
| Subject | [PATCH v2 0/2] Improvement on ioapic hotplug |
| Message-ID | <tfQtP-5bx-7@gated-at.bofh.it> |
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. If
a device under the IOAPIC doesn't call pci_disable_device(), then
the hot-removal of the IOAPIC causes kernel stack dump.
This patchset can fix the problem. IOAPIC hot-removal works correctly
after applying this patchset.
v2: 0001 Fixed a missing stub function causing compiling error on i386
0002 Fixed a typo on the subject line.
Rui Wang (2):
x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC
x86/ioapic: Split IOAPIC hot-removal into two steps
arch/x86/pci/common.c | 9 +++++++++
drivers/acpi/internal.h | 2 ++
drivers/acpi/ioapic.c | 22 ++++++++++++++++------
drivers/acpi/pci_root.c | 4 ++--
4 files changed, 29 insertions(+), 8 deletions(-)
--
1.8.3.1
[toc] | [next] | [standalone]
| From | Rui Wang <rui.y.wang@intel.com> |
|---|---|
| Date | 2017-02-28 15:00 +0100 |
| Subject | [PATCH v2 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps |
| Message-ID | <tfQtQ-5bx-19@gated-at.bofh.it> |
| In reply to | #1589474 |
The hot-removal of IOAPIC is broken into two parts: the PCI part and
the ACPI part. The PCI part releases PCI resources before the PCI bus
is gone, and the ACPI part is moved to a stage later than the hot-removal
of the PCI root bus, so that the IOAPIC driver is able to hook the
pcibios_release_device() of every PCI device under the same parent root
bus, before the IOAPIC is hot-removed. This makes it possible for the
IOAPIC to free any IRQ resource previously unable to get freed.
v2: Fixed compiling error on i386 (missing stub of pci_ioapic_remove())
Signed-off-by: Rui Wang <rui.y.wang@intel.com>
---
drivers/acpi/internal.h | 2 ++
drivers/acpi/ioapic.c | 22 ++++++++++++++++------
drivers/acpi/pci_root.c | 4 ++--
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ static inline void acpi_amba_init(void) {}
void acpi_container_init(void);
void acpi_memory_hotplug_init(void);
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
int acpi_ioapic_remove(struct acpi_pci_root *root);
#else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
#endif
#ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
}
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
{
- int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
mutex_lock(&ioapic_list_lock);
list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
- if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
- retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+ }
+ mutex_unlock(&ioapic_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+ int retval = 0;
+ struct acpi_pci_ioapic *ioapic, *tmp;
+
+ mutex_lock(&ioapic_list_lock);
+ list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
+ if (root->device->handle != ioapic->root_handle)
+ continue;
+ if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+ retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(&ioapic->res);
list_del(&ioapic->list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device *device)
pci_stop_root_bus(root->bus);
- WARN_ON(acpi_ioapic_remove(root));
-
+ pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
pci_remove_root_bus(root->bus);
+ WARN_ON(acpi_ioapic_remove(root));
dmar_device_remove(device->handle);
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Rui Wang <tipbot@zytor.com> |
|---|---|
| Date | 2017-03-01 11:50 +0100 |
| Subject | [tip:x86/urgent] x86/ioapic: Split IOAPIC hot-removal into two steps |
| Message-ID | <tg9Zw-1Pu-31@gated-at.bofh.it> |
| In reply to | #1589478 |
Commit-ID: f2ae5da726172fcf82f7be801489dd585f6a38eb
Gitweb: http://git.kernel.org/tip/f2ae5da726172fcf82f7be801489dd585f6a38eb
Author: Rui Wang <rui.y.wang@intel.com>
AuthorDate: Tue, 28 Feb 2017 21:34:29 +0800
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100
x86/ioapic: Split IOAPIC hot-removal into two steps
The hot removal of IOAPIC is handling PCI and ACPI removal in one go. That
only works when the PCI drivers released the interrupt resources, but
breaks when a IOAPIC interrupt is still associated to a PCI device.
The new pcibios_release_device() callback allows to solve that problem by
splitting the removal into two steps:
1) PCI removal:
Release all PCI resources including eventually not yet released IOAPIC
interrupts via the new pcibios_release_device() callback.
2) ACPI removal:
After release of all PCI resources the ACPI resources can be released
without issue.
[ tglx: Rewrote changelog ]
Signed-off-by: Rui Wang <rui.y.wang@intel.com>
Cc: tony.luck@intel.com
Cc: linux-pci@vger.kernel.org
Cc: rjw@rjwysocki.net
Cc: linux-acpi@vger.kernel.org
Cc: fengguang.wu@intel.com
Cc: helgaas@kernel.org
Cc: kbuild-all@01.org
Cc: bhelgaas@google.com
Link: http://lkml.kernel.org/r/1488288869-31290-3-git-send-email-rui.y.wang@intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/acpi/internal.h | 2 ++
drivers/acpi/ioapic.c | 22 ++++++++++++++++------
drivers/acpi/pci_root.c | 4 ++--
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ void acpi_gpe_apply_masked_gpes(void);
void acpi_container_init(void);
void acpi_memory_hotplug_init(void);
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
int acpi_ioapic_remove(struct acpi_pci_root *root);
#else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
#endif
#ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
}
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
{
- int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
mutex_lock(&ioapic_list_lock);
list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
- if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
- retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+ }
+ mutex_unlock(&ioapic_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+ int retval = 0;
+ struct acpi_pci_ioapic *ioapic, *tmp;
+
+ mutex_lock(&ioapic_list_lock);
+ list_for_each_entry_safe(ioapic, tmp, &ioapic_list, list) {
+ if (root->device->handle != ioapic->root_handle)
+ continue;
+ if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+ retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(&ioapic->res);
list_del(&ioapic->list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device *device)
pci_stop_root_bus(root->bus);
- WARN_ON(acpi_ioapic_remove(root));
-
+ pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
pci_remove_root_bus(root->bus);
+ WARN_ON(acpi_ioapic_remove(root));
dmar_device_remove(device->handle);
[toc] | [prev] | [next] | [standalone]
| From | Rui Wang <rui.y.wang@intel.com> |
|---|---|
| Date | 2017-02-28 15:00 +0100 |
| Subject | [PATCH v2 1/2] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC |
| Message-ID | <tfQtQ-5bx-25@gated-at.bofh.it> |
| In reply to | #1589474 |
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:
[149335.697989] pin16 on IOAPIC2 is still in use.
It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.
Besides implementing pcibios_release_device(), the hot-removal of
IOAPIC needs to be broken into two parts: the PCI part and the ACPI
part. The PCI part releases PCI resources before the PCI bus is gone,
and the ACPI part is moved to a stage later than the hot-removal of
the PCI root bus, so we have the chance to hook every PCI device's
pcibios_release_device(), before we remove the IOAPIC.
This patch implements pcibios_release_device() on x86 to release any
IRQ not released by the driver, so that the IOAPIC can then be safely
hot-removed.
v2: Fixed a typo (pcibios_release_device)
Signed-off-by: Rui Wang <rui.y.wang@intel.com>
---
arch/x86/pci/common.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
}
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+ if (atomic_dec_return(&dev->enable_cnt) >= 0)
+ pcibios_disable_device(dev);
+
+}
+#endif
+
int pci_ext_cfg_avail(void)
{
if (raw_pci_ext_ops)
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Rui Wang <tipbot@zytor.com> |
|---|---|
| Date | 2017-03-01 11:50 +0100 |
| Subject | [tip:x86/urgent] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC |
| Message-ID | <tg9Zv-1Pu-1@gated-at.bofh.it> |
| In reply to | #1589480 |
Commit-ID: 153654dbe595a68845ba14d5b0bfe299fa6a7e99
Gitweb: http://git.kernel.org/tip/153654dbe595a68845ba14d5b0bfe299fa6a7e99
Author: Rui Wang <rui.y.wang@intel.com>
AuthorDate: Tue, 28 Feb 2017 21:34:28 +0800
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100
x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:
[149335.697989] pin16 on IOAPIC2 is still in use.
It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.
Implement pcibios_release_device() for x86 to release any IRQ not released
by the driver.
Signed-off-by: Rui Wang <rui.y.wang@intel.com>
Cc: tony.luck@intel.com
Cc: linux-pci@vger.kernel.org
Cc: rjw@rjwysocki.net
Cc: linux-acpi@vger.kernel.org
Cc: fengguang.wu@intel.com
Cc: helgaas@kernel.org
Cc: kbuild-all@01.org
Cc: bhelgaas@google.com
Link: http://lkml.kernel.org/r/1488288869-31290-2-git-send-email-rui.y.wang@intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/pci/common.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
}
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+ if (atomic_dec_return(&dev->enable_cnt) >= 0)
+ pcibios_disable_device(dev);
+
+}
+#endif
+
int pci_ext_cfg_avail(void)
{
if (raw_pci_ext_ops)
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web