lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ