Skip to content

Commit 48b15a7

Browse files
author
Marc Zyngier
committed
irqdomain: Cache irq_data instead of a virq number in the revmap
Caching a virq number in the revmap is pretty inefficient, as it means we will need to convert it back to either an irq_data or irq_desc to do anything with it. It is also a bit odd, as the radix tree does cache irq_data pointers. Change the revmap type to be an irq_data pointer instead of an unsigned int, and preserve the current API for now. Signed-off-by: Marc Zyngier <[email protected]>
1 parent 426fa31 commit 48b15a7

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

include/linux/irqdomain.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ struct irq_domain_chip_generic;
151151
* Revmap data, used internally by irq_domain
152152
* @revmap_size: Size of the linear map table @revmap[]
153153
* @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
154-
* @revmap: Linear table of hwirq->virq reverse mappings
154+
* @revmap: Linear table of irq_data pointers
155155
*/
156156
struct irq_domain {
157157
struct list_head link;
@@ -174,7 +174,7 @@ struct irq_domain {
174174
unsigned int revmap_size;
175175
struct radix_tree_root revmap_tree;
176176
struct mutex revmap_tree_mutex;
177-
unsigned int revmap[];
177+
struct irq_data *revmap[];
178178
};
179179

180180
/* Irq domain flags */

kernel/irq/irqdomain.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
505505
return;
506506

507507
if (hwirq < domain->revmap_size) {
508-
domain->revmap[hwirq] = 0;
508+
domain->revmap[hwirq] = NULL;
509509
} else {
510510
mutex_lock(&domain->revmap_tree_mutex);
511511
radix_tree_delete(&domain->revmap_tree, hwirq);
@@ -521,7 +521,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
521521
return;
522522

523523
if (hwirq < domain->revmap_size) {
524-
domain->revmap[hwirq] = irq_data->irq;
524+
domain->revmap[hwirq] = irq_data;
525525
} else {
526526
mutex_lock(&domain->revmap_tree_mutex);
527527
radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
@@ -913,7 +913,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
913913

914914
/* Check if the hwirq is in the linear revmap. */
915915
if (hwirq < domain->revmap_size)
916-
return domain->revmap[hwirq];
916+
return domain->revmap[hwirq]->irq;
917917

918918
rcu_read_lock();
919919
data = radix_tree_lookup(&domain->revmap_tree, hwirq);
@@ -1496,8 +1496,14 @@ static void irq_domain_fix_revmap(struct irq_data *d)
14961496
{
14971497
void __rcu **slot;
14981498

1499-
if (irq_domain_is_nomap(d->domain) || d->hwirq < d->domain->revmap_size)
1500-
return; /* Not using radix tree. */
1499+
if (irq_domain_is_nomap(d->domain))
1500+
return;
1501+
1502+
if (d->hwirq < d->domain->revmap_size) {
1503+
/* Not using radix tree */
1504+
d->domain->revmap[d->hwirq] = d;
1505+
return;
1506+
}
15011507

15021508
/* Fix up the revmap. */
15031509
mutex_lock(&d->domain->revmap_tree_mutex);

0 commit comments

Comments
 (0)