summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@rivosinc.com>2025-05-14 10:13:20 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-29 11:13:57 +0200
commitef60a8e4fdc22e25721cbe22d89bba9fa953caf2 (patch)
treeb478147be37247350de03c529fbf975a7664315c
parentf9670b2e81e8a3cbf2e1e757190dd0b920a9d43f (diff)
irqchip/riscv-imsic: Start local sync timer on correct CPU
[ Upstream commit 08fb624802d8786253994d8ebdbbcdaa186f04f5 ] When starting the local sync timer to synchronize the state of a remote CPU it should be added on the CPU to be synchronized, not the initiating CPU. This results in interrupt delivery being delayed until the timer eventually runs (due to another mask/unmask/migrate operation) on the target CPU. Fixes: 0f67911e821c ("irqchip/riscv-imsic: Separate next and previous pointers in IMSIC vector") Signed-off-by: Andrew Bresticker <abrestic@rivosinc.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/all/20250514171320.3494917-1-abrestic@rivosinc.com Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/irqchip/irq-riscv-imsic-state.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index 1aeba76d7279..06ff0e17c0c3 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -186,17 +186,17 @@ skip:
}
#ifdef CONFIG_SMP
-static void __imsic_local_timer_start(struct imsic_local_priv *lpriv)
+static void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
lockdep_assert_held(&lpriv->lock);
if (!timer_pending(&lpriv->timer)) {
lpriv->timer.expires = jiffies + 1;
- add_timer_on(&lpriv->timer, smp_processor_id());
+ add_timer_on(&lpriv->timer, cpu);
}
}
#else
-static inline void __imsic_local_timer_start(struct imsic_local_priv *lpriv)
+static inline void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
}
#endif
@@ -211,7 +211,7 @@ void imsic_local_sync_all(bool force_all)
if (force_all)
bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
if (!__imsic_local_sync(lpriv))
- __imsic_local_timer_start(lpriv);
+ __imsic_local_timer_start(lpriv, smp_processor_id());
raw_spin_unlock_irqrestore(&lpriv->lock, flags);
}
@@ -256,7 +256,7 @@ static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu
return;
}
- __imsic_local_timer_start(lpriv);
+ __imsic_local_timer_start(lpriv, cpu);
}
}
#else