aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/pci/hotplug/pciehp.h
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2018-07-19 17:27:38 -0500
committerBjorn Helgaas <helgaas@kernel.org>2018-07-23 17:04:12 -0500
commit7b4ce26bcf697e3a4aa9ba2a5b456562e0fb7af4 (patch)
tree98b715e30c9017dbb4cd92d09bbca7879f88fb24 /drivers/pci/hotplug/pciehp.h
parentPCI: pciehp: Document struct slot and struct controller (diff)
downloadwireguard-linux-7b4ce26bcf697e3a4aa9ba2a5b456562e0fb7af4.tar.xz
wireguard-linux-7b4ce26bcf697e3a4aa9ba2a5b456562e0fb7af4.zip
PCI: pciehp: Convert to threaded IRQ
pciehp's IRQ handler queues up a work item for each event signaled by the hardware. A more modern alternative is to let a long running kthread service the events. The IRQ handler's sole job is then to check whether the IRQ originated from the device in question, acknowledge its receipt to the hardware to quiesce the interrupt and wake up the kthread. One benefit is reduced latency to handle the IRQ, which is a necessity for realtime environments. Another benefit is that we can make pciehp simpler and more robust by handling events synchronously in process context, rather than asynchronously by queueing up work items. pciehp's usage of work items is a historic artifact, it predates the introduction of threaded IRQ handlers by two years. (The former was introduced in 2007 with commit 5d386e1ac402 ("pciehp: Event handling rework"), the latter in 2009 with commit 3aa551c9b4c4 ("genirq: add threaded interrupt handler support").) Convert pciehp to threaded IRQ handling by retrieving the pending events in pciehp_isr(), saving them for later consumption by the thread handler pciehp_ist() and clearing them in the Slot Status register. By clearing the Slot Status (and thereby acknowledging the events) in pciehp_isr(), we can avoid requesting the IRQ with IRQF_ONESHOT, which would have the unpleasant side effect of starving devices sharing the IRQ until pciehp_ist() has finished. pciehp_isr() does not count how many times each event occurred, but merely records the fact *that* an event occurred. If the same event occurs a second time before pciehp_ist() is woken, that second event will not be recorded separately, which is problematic according to commit fad214b0aa72 ("PCI: pciehp: Process all hotplug events before looking for new ones") because we may miss removal of a card in-between two back-to-back insertions. We're about to make pciehp_ist() resilient to missed events. The present commit regresses the driver's behavior temporarily in order to separate the changes into reviewable chunks. This doesn't affect regular slow-motion hotplug, only plug-unplug-plug operations that happen in a timespan shorter than wakeup of the IRQ thread. Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Mayurkumar Patel <mayurkumar.patel@intel.com> Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Diffstat (limited to 'drivers/pci/hotplug/pciehp.h')
-rw-r--r--drivers/pci/hotplug/pciehp.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index c3d63e5b650f..ab1d97a1822d 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -112,6 +112,8 @@ struct event_info {
* @notification_enabled: whether the IRQ was requested successfully
* @power_fault_detected: whether a power fault was detected by the hardware
* that has not yet been cleared by the user
+ * @pending_events: used by the IRQ handler to save events retrieved from the
+ * Slot Status register for later consumption by the IRQ thread
*/
struct controller {
struct mutex ctrl_lock;
@@ -126,6 +128,7 @@ struct controller {
unsigned int link_active_reporting:1;
unsigned int notification_enabled:1;
unsigned int power_fault_detected;
+ atomic_t pending_events;
};
#define INT_PRESENCE_ON 1