@@ -213,7 +213,7 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
213213
214214 /* Fill structure */
215215 INIT_RADIX_TREE (& domain -> revmap_tree , GFP_KERNEL );
216- mutex_init (& domain -> revmap_tree_mutex );
216+ mutex_init (& domain -> revmap_mutex );
217217 domain -> ops = ops ;
218218 domain -> host_data = host_data ;
219219 domain -> hwirq_max = hwirq_max ;
@@ -504,13 +504,12 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
504504 if (irq_domain_is_nomap (domain ))
505505 return ;
506506
507- if ( hwirq < domain -> revmap_size ) {
508- domain -> revmap [ hwirq ] = NULL ;
509- } else {
510- mutex_lock ( & domain -> revmap_tree_mutex );
507+ mutex_lock ( & domain -> revmap_mutex );
508+ if ( hwirq < domain -> revmap_size )
509+ rcu_assign_pointer ( domain -> revmap [ hwirq ], NULL );
510+ else
511511 radix_tree_delete (& domain -> revmap_tree , hwirq );
512- mutex_unlock (& domain -> revmap_tree_mutex );
513- }
512+ mutex_unlock (& domain -> revmap_mutex );
514513}
515514
516515static void irq_domain_set_mapping (struct irq_domain * domain ,
@@ -520,13 +519,12 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
520519 if (irq_domain_is_nomap (domain ))
521520 return ;
522521
523- if ( hwirq < domain -> revmap_size ) {
524- domain -> revmap [ hwirq ] = irq_data ;
525- } else {
526- mutex_lock ( & domain -> revmap_tree_mutex );
522+ mutex_lock ( & domain -> revmap_mutex );
523+ if ( hwirq < domain -> revmap_size )
524+ rcu_assign_pointer ( domain -> revmap [ hwirq ], irq_data );
525+ else
527526 radix_tree_insert (& domain -> revmap_tree , hwirq , irq_data );
528- mutex_unlock (& domain -> revmap_tree_mutex );
529- }
527+ mutex_unlock (& domain -> revmap_mutex );
530528}
531529
532530static void irq_domain_disassociate (struct irq_domain * domain , unsigned int irq )
@@ -911,12 +909,12 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
911909 return 0 ;
912910 }
913911
912+ rcu_read_lock ();
914913 /* Check if the hwirq is in the linear revmap. */
915914 if (hwirq < domain -> revmap_size )
916- return domain -> revmap [hwirq ]-> irq ;
917-
918- rcu_read_lock ();
919- data = radix_tree_lookup (& domain -> revmap_tree , hwirq );
915+ data = rcu_dereference (domain -> revmap [hwirq ]);
916+ else
917+ data = radix_tree_lookup (& domain -> revmap_tree , hwirq );
920918 rcu_read_unlock ();
921919 return data ? data -> irq : 0 ;
922920}
@@ -1499,18 +1497,17 @@ static void irq_domain_fix_revmap(struct irq_data *d)
14991497 if (irq_domain_is_nomap (d -> domain ))
15001498 return ;
15011499
1500+ /* Fix up the revmap. */
1501+ mutex_lock (& d -> domain -> revmap_mutex );
15021502 if (d -> hwirq < d -> domain -> revmap_size ) {
15031503 /* Not using radix tree */
1504- d -> domain -> revmap [d -> hwirq ] = d ;
1505- return ;
1504+ rcu_assign_pointer (d -> domain -> revmap [d -> hwirq ], d );
1505+ } else {
1506+ slot = radix_tree_lookup_slot (& d -> domain -> revmap_tree , d -> hwirq );
1507+ if (slot )
1508+ radix_tree_replace_slot (& d -> domain -> revmap_tree , slot , d );
15061509 }
1507-
1508- /* Fix up the revmap. */
1509- mutex_lock (& d -> domain -> revmap_tree_mutex );
1510- slot = radix_tree_lookup_slot (& d -> domain -> revmap_tree , d -> hwirq );
1511- if (slot )
1512- radix_tree_replace_slot (& d -> domain -> revmap_tree , slot , d );
1513- mutex_unlock (& d -> domain -> revmap_tree_mutex );
1510+ mutex_unlock (& d -> domain -> revmap_mutex );
15141511}
15151512
15161513/**
0 commit comments