summaryrefslogtreecommitdiff
path: root/include/linux/irqdomain.h
diff options
context:
space:
mode:
authorJohan Hovold <johan+linaro@kernel.org>2023-02-13 13:43:02 +0300
committerMarc Zyngier <maz@kernel.org>2023-02-13 22:31:25 +0300
commit9dbb8e3452aba34e6fa4f63054b3adc66aceb7ec (patch)
treedaea6486234e1521457889f53d5ca86757903435 /include/linux/irqdomain.h
parentf743f54fa8d2bcb3f2891b783687d91b76a144f5 (diff)
downloadlinux-9dbb8e3452aba34e6fa4f63054b3adc66aceb7ec.tar.xz
irqdomain: Switch to per-domain locking
The IRQ domain structures are currently protected by the global irq_domain_mutex. Switch to using more fine-grained per-domain locking, which can speed up parallel probing by reducing lock contention. On a recent arm64 laptop, the total time spent waiting for the locks during boot drops from 160 to 40 ms on average, while the maximum aggregate wait time drops from 550 to 90 ms over ten runs for example. Note that the domain lock of the root domain (innermost domain) must be used for hierarchical domains. For non-hierarchical domains (as for root domains), the new root pointer is set to the domain itself so that &domain->root->mutex always points to the right lock. Also note that hierarchical domains should be constructed using irq_domain_create_hierarchy() (or irq_domain_add_hierarchy()) to avoid having racing allocations access a not fully initialised domain. As a safeguard, the lockdep assertion in irq_domain_set_mapping() will catch any offenders that also fail to set the root domain pointer. Tested-by: Hsin-Yi Wang <hsinyi@chromium.org> Tested-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230213104302.17307-21-johan+linaro@kernel.org
Diffstat (limited to 'include/linux/irqdomain.h')
-rw-r--r--include/linux/irqdomain.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 16399de00b48..d320d15d4fba 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -125,6 +125,8 @@ struct irq_domain_chip_generic;
* core code.
* @flags: Per irq_domain flags
* @mapcount: The number of mapped interrupts
+ * @mutex: Domain lock, hierarchical domains use root domain's lock
+ * @root: Pointer to root domain, or containing structure if non-hierarchical
*
* Optional elements:
* @fwnode: Pointer to firmware node associated with the irq_domain. Pretty easy
@@ -152,6 +154,8 @@ struct irq_domain {
void *host_data;
unsigned int flags;
unsigned int mapcount;
+ struct mutex mutex;
+ struct irq_domain *root;
/* Optional data */
struct fwnode_handle *fwnode;