public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations
@ 2025-10-15 19:55 Samuel Holland
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Samuel Holland @ 2025-10-15 19:55 UTC (permalink / raw)
  To: Anup Patel, Thomas Gleixner
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

This series includes a small cleanup to imsic_irq_set_affinity() and a
series of optimizations to the IMSIC IRQ handling hot path.

Benchmarks on a SiFive P470-based board (95% confidence interval):
  perf bench sched messaging: 5.20% to  7.08% improvement
  perf bench sched pipe     : 8.47% to 13.85% improvement


Samuel Holland (4):
  irqchip/riscv-imsic: Remove redundant irq_data lookups
  irqchip/riscv-imsic: Embed the vector array in lpriv
  irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  irqchip/riscv-imsic: Remove irq_desc lookup from hot path

 drivers/irqchip/irq-riscv-imsic-early.c    | 11 +++-----
 drivers/irqchip/irq-riscv-imsic-platform.c | 11 ++++----
 drivers/irqchip/irq-riscv-imsic-state.c    | 30 +++++-----------------
 drivers/irqchip/irq-riscv-imsic-state.h    |  8 +++---
 4 files changed, 19 insertions(+), 41 deletions(-)

-- 
2.47.2

base-commit: 9b332cece987ee1790b2ed4c989e28162fa47860
branch: up/imsic-opt

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups
  2025-10-15 19:55 [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations Samuel Holland
@ 2025-10-15 19:55 ` Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
                     ` (2 more replies)
  2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 15+ messages in thread
From: Samuel Holland @ 2025-10-15 19:55 UTC (permalink / raw)
  To: Anup Patel, Thomas Gleixner
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

imsic_irq_set_affinity() already takes the irq_data pointer as a
parameter, so it is pointless to look it up again from the IRQ number.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---

 drivers/irqchip/irq-riscv-imsic-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 643c8e459611..7228a33f6c37 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
+		imsic_msi_update_msg(d, &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
+	imsic_msi_update_msg(d, new_vec);
 
 	/* Update irq descriptors with the new vector */
 	d->chip_data = new_vec;
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv
  2025-10-15 19:55 [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations Samuel Holland
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
@ 2025-10-15 19:55 ` Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
                     ` (2 more replies)
  2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
  2025-10-15 19:55 ` [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path Samuel Holland
  3 siblings, 3 replies; 15+ messages in thread
From: Samuel Holland @ 2025-10-15 19:55 UTC (permalink / raw)
  To: Anup Patel, Thomas Gleixner
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

Reduce pointer chasing and the number of allocations by using a flexible
array member for the vector array instead of a separate allocation.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---

 drivers/irqchip/irq-riscv-imsic-state.c | 10 ++--------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index dc95ad856d80..9a499efdebe3 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -487,7 +487,6 @@ static void __init imsic_local_cleanup(void)
 		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
 
 		bitmap_free(lpriv->dirty_bitmap);
-		kfree(lpriv->vectors);
 	}
 
 	free_percpu(imsic->lpriv);
@@ -501,7 +500,8 @@ static int __init imsic_local_init(void)
 	int cpu, i;
 
 	/* Allocate per-CPU private state */
-	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	imsic->lpriv = __alloc_percpu(struct_size(imsic->lpriv, vectors, global->nr_ids + 1),
+				      __alignof__(*imsic->lpriv));
 	if (!imsic->lpriv)
 		return -ENOMEM;
 
@@ -521,12 +521,6 @@ static int __init imsic_local_init(void)
 		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
 #endif
 
-		/* Allocate vector array */
-		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
-					 GFP_KERNEL);
-		if (!lpriv->vectors)
-			goto fail_local_cleanup;
-
 		/* Setup vector array */
 		for (i = 0; i <= global->nr_ids; i++) {
 			vec = &lpriv->vectors[i];
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 57f951952b0c..196457f1bbca 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -40,7 +40,7 @@ struct imsic_local_priv {
 #endif
 
 	/* Local vector table */
-	struct imsic_vector			*vectors;
+	struct imsic_vector			vectors[];
 };
 
 struct imsic_priv {
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  2025-10-15 19:55 [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations Samuel Holland
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
  2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
@ 2025-10-15 19:55 ` Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
                     ` (2 more replies)
  2025-10-15 19:55 ` [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path Samuel Holland
  3 siblings, 3 replies; 15+ messages in thread
From: Samuel Holland @ 2025-10-15 19:55 UTC (permalink / raw)
  To: Anup Patel, Thomas Gleixner
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

This function is only called from one place, which is in the IRQ
handling hot path. Inline it to improve code generation and to take
advantage of this_cpu operations. lpriv and imsic->base_domain can
never be NULL because irq_set_chained_handler() is called after they
are allocated.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---

 drivers/irqchip/irq-riscv-imsic-early.c | 11 +++--------
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ----------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 --
 3 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 2c4c682627b8..6bac67cc0b6d 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
  */
 static void imsic_handle_irq(struct irq_desc *desc)
 {
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int cpu = smp_processor_id();
-	struct imsic_vector *vec;
 	unsigned long local_id;
 
 	/*
@@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
 			continue;
 		}
 
-		if (unlikely(!imsic->base_domain))
-			continue;
-
-		vec = imsic_vector_from_local_id(cpu, local_id);
-		if (!vec) {
+		if (unlikely(local_id > imsic->global.nr_ids)) {
 			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
 			continue;
 		}
 
-		generic_handle_irq(vec->irq);
+		generic_handle_irq(lpriv->vectors[local_id].irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 9a499efdebe3..385368052d5c 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
 }
 #endif
 
-struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
-{
-	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
-
-	if (!lpriv || imsic->global.nr_ids < local_id)
-		return NULL;
-
-	return &lpriv->vectors[local_id];
-}
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
 {
 	struct imsic_vector *vec = NULL;
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 196457f1bbca..6332501dcbd8 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -95,8 +95,6 @@ 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_from_local_id(unsigned int cpu, unsigned int local_id);
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
 void imsic_vector_free(struct imsic_vector *vector);
 
-- 
2.47.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path
  2025-10-15 19:55 [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations Samuel Holland
                   ` (2 preceding siblings ...)
  2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
@ 2025-10-15 19:55 ` Samuel Holland
  2025-10-16 10:01   ` Thomas Gleixner
  3 siblings, 1 reply; 15+ messages in thread
From: Samuel Holland @ 2025-10-15 19:55 UTC (permalink / raw)
  To: Anup Patel, Thomas Gleixner
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

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@sifive.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


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path
  2025-10-15 19:55 ` [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path Samuel Holland
@ 2025-10-16 10:01   ` Thomas Gleixner
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Gleixner @ 2025-10-16 10:01 UTC (permalink / raw)
  To: Samuel Holland, Anup Patel
  Cc: Palmer Dabbelt, linux-kernel, Alexandre Ghiti, linux-riscv,
	Paul Walmsley, Samuel Holland, Albert Ou

On Wed, Oct 15 2025 at 12:55, Samuel Holland wrote:
> 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

which got the idea from x86 :)

> -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);

This is only correct when it is guaranteed that the interrupt can't be
raised in the CPU _before_ a interrupt allocation completed throughout
the hierarchy and _after_ the freeing hierarchy walk started. Otherwise
this might end up accessing a half initialized or half torn down
descriptor.

If it is, then please add a comment describing it. If not then you need
to implement the activate/deactivate callbacks for your interrupt domain
and do the store/clear of vec->desc there.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
@ 2025-10-16 12:55   ` tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 12:55 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     45f8fdcfbf4e49075172cf1a3fd812b90160e903
Gitweb:        https://git.kernel.org/tip/45f8fdcfbf4e49075172cf1a3fd812b90160e903
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:14 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 13:12:50 +02:00

irqchip/riscv-imsic: Inline imsic_vector_from_local_id()

This function is only called from one place, which is in the interrupt
handling hot path. Inline it to improve code generation and to take
advantage of this_cpu operations. lpriv and imsic->base_domain can never be
NULL because irq_set_chained_handler() is called after they are allocated.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-early.c | 11 +++--------
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ----------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 --
 3 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 2c4c682..6bac67c 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
  */
 static void imsic_handle_irq(struct irq_desc *desc)
 {
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int cpu = smp_processor_id();
-	struct imsic_vector *vec;
 	unsigned long local_id;
 
 	/*
@@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
 			continue;
 		}
 
-		if (unlikely(!imsic->base_domain))
-			continue;
-
-		vec = imsic_vector_from_local_id(cpu, local_id);
-		if (!vec) {
+		if (unlikely(local_id > imsic->global.nr_ids)) {
 			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
 			continue;
 		}
 
-		generic_handle_irq(vec->irq);
+		generic_handle_irq(lpriv->vectors[local_id].irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 9a499ef..3853680 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
 }
 #endif
 
-struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
-{
-	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
-
-	if (!lpriv || imsic->global.nr_ids < local_id)
-		return NULL;
-
-	return &lpriv->vectors[local_id];
-}
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
 {
 	struct imsic_vector *vec = NULL;
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 196457f..6332501 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -95,8 +95,6 @@ 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_from_local_id(unsigned int cpu, unsigned int local_id);
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
 void imsic_vector_free(struct imsic_vector *vector);
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Embed the vector array in lpriv
  2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
@ 2025-10-16 12:55   ` tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 12:55 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     424eafac024552b352d765afc392b090e55bfbf6
Gitweb:        https://git.kernel.org/tip/424eafac024552b352d765afc392b090e55bfbf6
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:13 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 13:12:50 +02:00

irqchip/riscv-imsic: Embed the vector array in lpriv

Reduce pointer chasing and the number of allocations by using a flexible
array member for the vector array instead of a separate allocation.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ++--------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index dc95ad8..9a499ef 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -487,7 +487,6 @@ static void __init imsic_local_cleanup(void)
 		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
 
 		bitmap_free(lpriv->dirty_bitmap);
-		kfree(lpriv->vectors);
 	}
 
 	free_percpu(imsic->lpriv);
@@ -501,7 +500,8 @@ static int __init imsic_local_init(void)
 	int cpu, i;
 
 	/* Allocate per-CPU private state */
-	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	imsic->lpriv = __alloc_percpu(struct_size(imsic->lpriv, vectors, global->nr_ids + 1),
+				      __alignof__(*imsic->lpriv));
 	if (!imsic->lpriv)
 		return -ENOMEM;
 
@@ -521,12 +521,6 @@ static int __init imsic_local_init(void)
 		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
 #endif
 
-		/* Allocate vector array */
-		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
-					 GFP_KERNEL);
-		if (!lpriv->vectors)
-			goto fail_local_cleanup;
-
 		/* Setup vector array */
 		for (i = 0; i <= global->nr_ids; i++) {
 			vec = &lpriv->vectors[i];
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 57f9519..196457f 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -40,7 +40,7 @@ struct imsic_local_priv {
 #endif
 
 	/* Local vector table */
-	struct imsic_vector			*vectors;
+	struct imsic_vector			vectors[];
 };
 
 struct imsic_priv {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Remove redundant irq_data lookups
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
@ 2025-10-16 12:55   ` tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 12:55 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     bbec970f417aa9796d6b36b60b5fc5df09ce5904
Gitweb:        https://git.kernel.org/tip/bbec970f417aa9796d6b36b60b5fc5df09ce5904
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:12 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 13:12:50 +02:00

irqchip/riscv-imsic: Remove redundant irq_data lookups

imsic_irq_set_affinity() already takes the irq_data pointer as a
parameter, so it is pointless to look it up again from the IRQ number.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 643c8e4..7228a33 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
+		imsic_msi_update_msg(d, &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
+	imsic_msi_update_msg(d, new_vec);
 
 	/* Update irq descriptors with the new vector */
 	d->chip_data = new_vec;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
@ 2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 15:46 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     a8b91cb35847a316d5609b6819b6fa65dd7fbf5b
Gitweb:        https://git.kernel.org/tip/a8b91cb35847a316d5609b6819b6fa65dd7fbf5b
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:14 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 17:26:35 +02:00

irqchip/riscv-imsic: Inline imsic_vector_from_local_id()

This function is only called from one place, which is in the interrupt
handling hot path. Inline it to improve code generation and to take
advantage of this_cpu operations. lpriv and imsic->base_domain can never be
NULL because irq_set_chained_handler() is called after they are allocated.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-early.c | 11 +++--------
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ----------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 --
 3 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 2c4c682..6bac67c 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
  */
 static void imsic_handle_irq(struct irq_desc *desc)
 {
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int cpu = smp_processor_id();
-	struct imsic_vector *vec;
 	unsigned long local_id;
 
 	/*
@@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
 			continue;
 		}
 
-		if (unlikely(!imsic->base_domain))
-			continue;
-
-		vec = imsic_vector_from_local_id(cpu, local_id);
-		if (!vec) {
+		if (unlikely(local_id > imsic->global.nr_ids)) {
 			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
 			continue;
 		}
 
-		generic_handle_irq(vec->irq);
+		generic_handle_irq(lpriv->vectors[local_id].irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 9a499ef..3853680 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
 }
 #endif
 
-struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
-{
-	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
-
-	if (!lpriv || imsic->global.nr_ids < local_id)
-		return NULL;
-
-	return &lpriv->vectors[local_id];
-}
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
 {
 	struct imsic_vector *vec = NULL;
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 196457f..6332501 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -95,8 +95,6 @@ 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_from_local_id(unsigned int cpu, unsigned int local_id);
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
 void imsic_vector_free(struct imsic_vector *vector);
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Embed the vector array in lpriv
  2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
@ 2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 15:46 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     6efefb71195ae1c93913615bcf0e7c5a63083e35
Gitweb:        https://git.kernel.org/tip/6efefb71195ae1c93913615bcf0e7c5a63083e35
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:13 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 17:26:35 +02:00

irqchip/riscv-imsic: Embed the vector array in lpriv

Reduce pointer chasing and the number of allocations by using a flexible
array member for the vector array instead of a separate allocation.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ++--------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index dc95ad8..9a499ef 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -487,7 +487,6 @@ static void __init imsic_local_cleanup(void)
 		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
 
 		bitmap_free(lpriv->dirty_bitmap);
-		kfree(lpriv->vectors);
 	}
 
 	free_percpu(imsic->lpriv);
@@ -501,7 +500,8 @@ static int __init imsic_local_init(void)
 	int cpu, i;
 
 	/* Allocate per-CPU private state */
-	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	imsic->lpriv = __alloc_percpu(struct_size(imsic->lpriv, vectors, global->nr_ids + 1),
+				      __alignof__(*imsic->lpriv));
 	if (!imsic->lpriv)
 		return -ENOMEM;
 
@@ -521,12 +521,6 @@ static int __init imsic_local_init(void)
 		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
 #endif
 
-		/* Allocate vector array */
-		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
-					 GFP_KERNEL);
-		if (!lpriv->vectors)
-			goto fail_local_cleanup;
-
 		/* Setup vector array */
 		for (i = 0; i <= global->nr_ids; i++) {
 			vec = &lpriv->vectors[i];
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 57f9519..196457f 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -40,7 +40,7 @@ struct imsic_local_priv {
 #endif
 
 	/* Local vector table */
-	struct imsic_vector			*vectors;
+	struct imsic_vector			vectors[];
 };
 
 struct imsic_priv {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Remove redundant irq_data lookups
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
@ 2025-10-16 15:46   ` tip-bot2 for Samuel Holland
  2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 15:46 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     69f81d15ae737f3e22451aa00fdaed95bfa2d65d
Gitweb:        https://git.kernel.org/tip/69f81d15ae737f3e22451aa00fdaed95bfa2d65d
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:12 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 17:26:35 +02:00

irqchip/riscv-imsic: Remove redundant irq_data lookups

imsic_irq_set_affinity() already takes the irq_data pointer as a
parameter, so it is pointless to look it up again from the IRQ number.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 643c8e4..7228a33 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
+		imsic_msi_update_msg(d, &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
+	imsic_msi_update_msg(d, new_vec);
 
 	/* Update irq descriptors with the new vector */
 	d->chip_data = new_vec;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Inline imsic_vector_from_local_id()
  2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
@ 2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 19:01 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     3a16b053840e04c45325dc313a23986ec7f37a50
Gitweb:        https://git.kernel.org/tip/3a16b053840e04c45325dc313a23986ec7f37a50
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:14 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 18:17:28 +02:00

irqchip/riscv-imsic: Inline imsic_vector_from_local_id()

This function is only called from one place, which is in the interrupt
handling hot path. Inline it to improve code generation and to take
advantage of this_cpu operations. lpriv and imsic->base_domain can never be
NULL because irq_set_chained_handler() is called after they are allocated.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-early.c | 11 +++--------
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ----------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 --
 3 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index 2c4c682..6bac67c 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0; }
  */
 static void imsic_handle_irq(struct irq_desc *desc)
 {
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int cpu = smp_processor_id();
-	struct imsic_vector *vec;
 	unsigned long local_id;
 
 	/*
@@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc)
 			continue;
 		}
 
-		if (unlikely(!imsic->base_domain))
-			continue;
-
-		vec = imsic_vector_from_local_id(cpu, local_id);
-		if (!vec) {
+		if (unlikely(local_id > imsic->global.nr_ids)) {
 			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
 			continue;
 		}
 
-		generic_handle_irq(vec->irq);
+		generic_handle_irq(lpriv->vectors[local_id].irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 9a499ef..3853680 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
 }
 #endif
 
-struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
-{
-	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
-
-	if (!lpriv || imsic->global.nr_ids < local_id)
-		return NULL;
-
-	return &lpriv->vectors[local_id];
-}
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask)
 {
 	struct imsic_vector *vec = NULL;
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 196457f..6332501 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -95,8 +95,6 @@ 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_from_local_id(unsigned int cpu, unsigned int local_id);
-
 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask);
 void imsic_vector_free(struct imsic_vector *vector);
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Embed the vector array in lpriv
  2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
@ 2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 19:01 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     79eaabc61dfbf5a4b680f42d3a113d05333c3960
Gitweb:        https://git.kernel.org/tip/79eaabc61dfbf5a4b680f42d3a113d05333c3960
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:13 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 18:17:28 +02:00

irqchip/riscv-imsic: Embed the vector array in lpriv

Reduce pointer chasing and the number of allocations by using a flexible
array member for the vector array instead of a separate allocation.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-state.c | 10 ++--------
 drivers/irqchip/irq-riscv-imsic-state.h |  2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index dc95ad8..9a499ef 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -487,7 +487,6 @@ static void __init imsic_local_cleanup(void)
 		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
 
 		bitmap_free(lpriv->dirty_bitmap);
-		kfree(lpriv->vectors);
 	}
 
 	free_percpu(imsic->lpriv);
@@ -501,7 +500,8 @@ static int __init imsic_local_init(void)
 	int cpu, i;
 
 	/* Allocate per-CPU private state */
-	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	imsic->lpriv = __alloc_percpu(struct_size(imsic->lpriv, vectors, global->nr_ids + 1),
+				      __alignof__(*imsic->lpriv));
 	if (!imsic->lpriv)
 		return -ENOMEM;
 
@@ -521,12 +521,6 @@ static int __init imsic_local_init(void)
 		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
 #endif
 
-		/* Allocate vector array */
-		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
-					 GFP_KERNEL);
-		if (!lpriv->vectors)
-			goto fail_local_cleanup;
-
 		/* Setup vector array */
 		for (i = 0; i <= global->nr_ids; i++) {
 			vec = &lpriv->vectors[i];
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 57f9519..196457f 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -40,7 +40,7 @@ struct imsic_local_priv {
 #endif
 
 	/* Local vector table */
-	struct imsic_vector			*vectors;
+	struct imsic_vector			vectors[];
 };
 
 struct imsic_priv {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip: irq/drivers] irqchip/riscv-imsic: Remove redundant irq_data lookups
  2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
  2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
  2025-10-16 15:46   ` tip-bot2 for Samuel Holland
@ 2025-10-16 19:01   ` tip-bot2 for Samuel Holland
  2 siblings, 0 replies; 15+ messages in thread
From: tip-bot2 for Samuel Holland @ 2025-10-16 19:01 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Samuel Holland, Thomas Gleixner, x86, linux-kernel

The following commit has been merged into the irq/drivers branch of tip:

Commit-ID:     c475c0b71314b222af576f93e2d32df077f14ad2
Gitweb:        https://git.kernel.org/tip/c475c0b71314b222af576f93e2d32df077f14ad2
Author:        Samuel Holland <samuel.holland@sifive.com>
AuthorDate:    Wed, 15 Oct 2025 12:55:12 -07:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Thu, 16 Oct 2025 18:17:28 +02:00

irqchip/riscv-imsic: Remove redundant irq_data lookups

imsic_irq_set_affinity() already takes the irq_data pointer as a
parameter, so it is pointless to look it up again from the IRQ number.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 643c8e4..7228a33 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		tmp_vec.local_id = new_vec->local_id;
 
 		/* Point device to the temporary vector */
-		imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec);
+		imsic_msi_update_msg(d, &tmp_vec);
 	}
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
+	imsic_msi_update_msg(d, new_vec);
 
 	/* Update irq descriptors with the new vector */
 	d->chip_data = new_vec;

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-10-16 19:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-15 19:55 [PATCH 0/4] irqchip/riscv-imsic: IRQ handling optimizations Samuel Holland
2025-10-15 19:55 ` [PATCH 1/4] irqchip/riscv-imsic: Remove redundant irq_data lookups Samuel Holland
2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
2025-10-16 15:46   ` tip-bot2 for Samuel Holland
2025-10-16 19:01   ` tip-bot2 for Samuel Holland
2025-10-15 19:55 ` [PATCH 2/4] irqchip/riscv-imsic: Embed the vector array in lpriv Samuel Holland
2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
2025-10-16 15:46   ` tip-bot2 for Samuel Holland
2025-10-16 19:01   ` tip-bot2 for Samuel Holland
2025-10-15 19:55 ` [PATCH 3/4] irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Samuel Holland
2025-10-16 12:55   ` [tip: irq/drivers] " tip-bot2 for Samuel Holland
2025-10-16 15:46   ` tip-bot2 for Samuel Holland
2025-10-16 19:01   ` tip-bot2 for Samuel Holland
2025-10-15 19:55 ` [PATCH 4/4] irqchip/riscv-imsic: Remove irq_desc lookup from hot path Samuel Holland
2025-10-16 10:01   ` Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox