Skip to content

Commit 47d1932

Browse files
jhovoldMarc Zyngier
authored andcommitted
irqdomain: Drop revmap mutex
The revmap mutex is essentially only used to maintain the integrity of the radix tree during updates (lookups use RCU). As the global irq_domain_mutex is now held in all paths that update the revmap structures there is strictly no longer any need for the dedicated mutex, which can be removed. Drop the revmap mutex and add lockdep assertions to the revmap helpers to make sure that the global lock is always held when updating the revmap. Tested-by: Hsin-Yi Wang <[email protected]> Tested-by: Mark-PK Tsai <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 8932c32 commit 47d1932

File tree

2 files changed

+6
-9
lines changed

2 files changed

+6
-9
lines changed

include/linux/irqdomain.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ struct irq_domain_chip_generic;
143143
* Revmap data, used internally by the irq domain code:
144144
* @revmap_size: Size of the linear map table @revmap[]
145145
* @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
146-
* @revmap_mutex: Lock for the revmap
147146
* @revmap: Linear table of irq_data pointers
148147
*/
149148
struct irq_domain {
@@ -171,7 +170,6 @@ struct irq_domain {
171170
irq_hw_number_t hwirq_max;
172171
unsigned int revmap_size;
173172
struct radix_tree_root revmap_tree;
174-
struct mutex revmap_mutex;
175173
struct irq_data __rcu *revmap[];
176174
};
177175

kernel/irq/irqdomain.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode,
206206

207207
/* Fill structure */
208208
INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
209-
mutex_init(&domain->revmap_mutex);
210209
domain->ops = ops;
211210
domain->host_data = host_data;
212211
domain->hwirq_max = hwirq_max;
@@ -526,30 +525,30 @@ static bool irq_domain_is_nomap(struct irq_domain *domain)
526525
static void irq_domain_clear_mapping(struct irq_domain *domain,
527526
irq_hw_number_t hwirq)
528527
{
528+
lockdep_assert_held(&irq_domain_mutex);
529+
529530
if (irq_domain_is_nomap(domain))
530531
return;
531532

532-
mutex_lock(&domain->revmap_mutex);
533533
if (hwirq < domain->revmap_size)
534534
rcu_assign_pointer(domain->revmap[hwirq], NULL);
535535
else
536536
radix_tree_delete(&domain->revmap_tree, hwirq);
537-
mutex_unlock(&domain->revmap_mutex);
538537
}
539538

540539
static void irq_domain_set_mapping(struct irq_domain *domain,
541540
irq_hw_number_t hwirq,
542541
struct irq_data *irq_data)
543542
{
543+
lockdep_assert_held(&irq_domain_mutex);
544+
544545
if (irq_domain_is_nomap(domain))
545546
return;
546547

547-
mutex_lock(&domain->revmap_mutex);
548548
if (hwirq < domain->revmap_size)
549549
rcu_assign_pointer(domain->revmap[hwirq], irq_data);
550550
else
551551
radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
552-
mutex_unlock(&domain->revmap_mutex);
553552
}
554553

555554
static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
@@ -1580,11 +1579,12 @@ static void irq_domain_fix_revmap(struct irq_data *d)
15801579
{
15811580
void __rcu **slot;
15821581

1582+
lockdep_assert_held(&irq_domain_mutex);
1583+
15831584
if (irq_domain_is_nomap(d->domain))
15841585
return;
15851586

15861587
/* Fix up the revmap. */
1587-
mutex_lock(&d->domain->revmap_mutex);
15881588
if (d->hwirq < d->domain->revmap_size) {
15891589
/* Not using radix tree */
15901590
rcu_assign_pointer(d->domain->revmap[d->hwirq], d);
@@ -1593,7 +1593,6 @@ static void irq_domain_fix_revmap(struct irq_data *d)
15931593
if (slot)
15941594
radix_tree_replace_slot(&d->domain->revmap_tree, slot, d);
15951595
}
1596-
mutex_unlock(&d->domain->revmap_mutex);
15971596
}
15981597

15991598
/**

0 commit comments

Comments
 (0)