[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251015195712.3813004-5-samuel.holland@sifive.com>
Date: Wed, 15 Oct 2025 12:55:15 -0700
From: Samuel Holland <samuel.holland@...ive.com>
To: Anup Patel <anup@...infault.org>,
Thomas Gleixner <tglx@...utronix.de>
Cc: Palmer Dabbelt <palmer@...belt.com>,
linux-kernel@...r.kernel.org,
Alexandre Ghiti <alex@...ti.fr>,
linux-riscv@...ts.infradead.org,
Paul Walmsley <pjw@...nel.org>,
Samuel Holland <samuel.holland@...ive.com>,
Albert Ou <aou@...s.berkeley.edu>
Subject: [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path
The IMSIC driver uses the IRQ matrix allocator, so there is an arbitrary
mapping from the per-CPU interrupt identity to the global irq number. As
a result, the driver maintains a table of vectors so it can look up the
virq number during interrupt handling. The driver uses the virq for one
main purpose: it gets passed to generic_handle_irq(), which then uses it
to look up the irq_desc in the sparse_irqs tree.
Taking inspiration from the loongarch AVEC irqchip driver, skip the tree
lookup by storing a pointer to the irq_desc in the vector table and
calling generic_handle_irq_desc() directly.
Signed-off-by: Samuel Holland <samuel.holland@...ive.com>
---
drivers/irqchip/irq-riscv-imsic-early.c | 2 +-
drivers/irqchip/irq-riscv-imsic-platform.c | 7 ++++---
drivers/irqchip/irq-riscv-imsic-state.c | 10 +++++-----
drivers/irqchip/irq-riscv-imsic-state.h | 4 ++--
4 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 6bac67cc0b6d..f3afcfa3242d 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -117,7 +117,7 @@ static void imsic_handle_irq(struct irq_desc *desc)
continue;
}
- generic_handle_irq(lpriv->vectors[local_id].irq);
+ generic_handle_irq_desc(lpriv->vectors[local_id].desc);
}
chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 7228a33f6c37..89618d2791c2 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -131,7 +131,7 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
return -EBUSY;
/* Get a new vector on the desired set of CPUs */
- new_vec = imsic_vector_alloc(old_vec->irq, mask_val);
+ new_vec = imsic_vector_alloc(old_vec->desc, mask_val);
if (!new_vec)
return -ENOSPC;
@@ -225,13 +225,14 @@ static struct irq_chip imsic_irq_base_chip = {
static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *args)
{
+ struct irq_data *data = irq_get_irq_data(virq);
struct imsic_vector *vec;
/* Multi-MSI is not supported yet. */
if (nr_irqs > 1)
return -EOPNOTSUPP;
- vec = imsic_vector_alloc(virq, cpu_online_mask);
+ vec = imsic_vector_alloc(irq_data_to_desc(data), cpu_online_mask);
if (!vec)
return -ENOSPC;
@@ -239,7 +240,7 @@ static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
handle_edge_irq, NULL, NULL);
irq_set_noprobe(virq);
irq_set_affinity(virq, cpu_online_mask);
- irq_data_update_effective_affinity(irq_get_irq_data(virq), cpumask_of(vec->cpu));
+ irq_data_update_effective_affinity(data, cpumask_of(vec->cpu));
return 0;
}
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 385368052d5c..f37800da3746 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -179,7 +179,8 @@ static bool __imsic_local_sync(struct imsic_local_priv *lpriv)
tvec = vec->local_id == mvec->local_id ?
NULL : &lpriv->vectors[mvec->local_id];
- if (tvec && !irq_can_move_in_process_context(irq_get_irq_data(vec->irq)) &&
+ if (tvec &&
+ !irq_can_move_in_process_context(irq_desc_get_irq_data(vec->desc)) &&
__imsic_id_read_clear_pending(tvec->local_id)) {
/* Retrigger temporary vector if it was already in-use */
if (READ_ONCE(tvec->enable)) {
@@ -434,7 +435,7 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
}
#endif
-struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
+struct imsic_vector *imsic_vector_alloc(struct irq_desc *desc, const struct cpumask *mask)
{
struct imsic_vector *vec = NULL;
struct imsic_local_priv *lpriv;
@@ -450,7 +451,7 @@ struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *
lpriv = per_cpu_ptr(imsic->lpriv, cpu);
vec = &lpriv->vectors[local_id];
- vec->irq = irq;
+ vec->desc = desc;
vec->enable = false;
vec->move_next = NULL;
vec->move_prev = NULL;
@@ -463,7 +464,7 @@ void imsic_vector_free(struct imsic_vector *vec)
unsigned long flags;
raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
- vec->irq = 0;
+ vec->desc = NULL;
irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
}
@@ -516,7 +517,6 @@ static int __init imsic_local_init(void)
vec = &lpriv->vectors[i];
vec->cpu = cpu;
vec->local_id = i;
- vec->irq = 0;
}
}
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 6332501dcbd8..a09dd140461b 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -20,7 +20,7 @@ struct imsic_vector {
unsigned int cpu;
unsigned int local_id;
/* Details saved by driver in the vector */
- unsigned int irq;
+ struct irq_desc *desc;
/* Details accessed using local lock held */
bool enable;
struct imsic_vector *move_next;
@@ -95,7 +95,7 @@ static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *ve
void imsic_vector_force_move_cleanup(struct imsic_vector *vec);
void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
-struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
+struct imsic_vector *imsic_vector_alloc(struct irq_desc *desc, const struct cpumask *mask);
void imsic_vector_free(struct imsic_vector *vector);
void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind);
--
2.47.2
Powered by blists - more mailing lists