[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v10 2/6] arm/irq: Migrate IRQs during CPU up/down operations


  • To: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>
  • From: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Date: Fri, 23 Oct 2026 01:05:50 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=/Rtz+fASszqVVsZR66/MhDDBBqFxZVLmOlGsqIYpI+8=; b=lNhpzcBsZXNdWsd9rD1p/N7NUlU3DKN3fcy4hRsPVldDnlx1qLV0iFAybKuPHt9Y24OZmSBvX8POaGQpwwAcxnuRWSxCBOhLaD7Q5p6TQ1JtqczxeSJKfe/bvABUF7ykKjljNe7x+Uyl2LVzMGuQfZnbKACNgPxm1UaUhw5aYDnuu3b+52T+46FS3QS8qVtYQBtgGGZ7MVwZXkdBxQTttgW48nR3UV9WealZ5ox260MsfLvstYHDudsqDzOQFyDlcSrznf0ydfhWixL3vlo93t5D6aokmfuvCeiuhn1EAKrbgdETNBeFk/ABzNNF6CmotWZn+JRycn7VVcAdmlq4gA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=chdNeMXwAJRLilKC1tackzLIUp7TCmogkKdwPBd0a+dW3BzF9Vq1depPJP4Nv3YFpsnMntG7uG3MJ1HbEbEM7OcAnCqXSGPSLnpbnD1dDTfdQjAYrZqWwAyIENLtgx8FJpOmj5savBoGRDWAuQlKT8/Ui3ibLvTMOhFDUpSb1EVt6zHegbQ0AWRlNEzlpqINrKAAYd8fbNIkLpxXuGYv/o1KKhhpoAeUbaan+PH8UL9RbwHVD9naTI4RZeR5E/mAsLmU1a2RxrTJt6qOkCI1f98gcOPjw7cJnVZ3tcDM37bhetfqRwIa8k13E6zQU2cYdAFlbFkVe4OKYq9LRfRPBQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=epam.com header.i="@epam.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
  • Authentication-results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Fri, 23 Oct 2026 01:05:56 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHdYHbuWxOoSM3qDECYUmtGRYf7WA==
  • Thread-topic: [PATCH v10 2/6] arm/irq: Migrate IRQs during CPU up/down operations

Hi Mykyta,

Mykyta Poturai <Mykyta_Poturai@xxxxxxxx> writes:

> Move IRQs from dying CPU to the online ones when a CPU is getting
> offlined. When onlining, rebalance all IRQs in a round-robin fashion.
> Guest-bound IRQs are already handled by scheduler in the process of
> moving vCPUs to active pCPUs, so we only need to handle IRQs used by Xen
> itself.
>
> Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>

Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>

> ---
> v9->v10:
> * make cpu_next static to balance_irq
> * move the offline path to the CPU_DEAD notifier
> * make rebalance_irqs static
>
> v8->v9:
> * replace CONFIG_CPU_HOTPLUG with CONFIG_CPU_ONLINE_OFFLINE
>
> v7->v8:
> * check only existings ESPIs
>
> v6->v7:
> * replace ifdef with IS_ENABLED
>
> v5->v6:
> * don't do any balancing on boot
> * only do balancing when cpu hotplug is enabled
>
> v4->v5:
> * handle CPU onlining as well
> * more comments
> * fix crash when ESPI is disabled
> * don't assume CPU 0 is a boot CPU
> * use insigned int for irq number
> * remove assumption that all irqs a bound to CPU 0 by default from the
>   commit message
>
> v3->v4:
> * patch introduced
> ---
>  xen/arch/arm/irq.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
>
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 594aaedd22..d5145a4723 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -166,6 +166,58 @@ static int init_local_irq_data(unsigned int cpu)
>      return 0;
>  }
>  
> +static void balance_irq(int irq, unsigned int from, bool up)
> +{
> +    static int cpu_next;
> +    struct irq_desc *desc = irq_to_desc(irq);
> +    unsigned long flags;
> +
> +    ASSERT(!cpumask_empty(&cpu_online_map));
> +
> +    spin_lock_irqsave(&desc->lock, flags);
> +    if ( likely(!desc->action) )
> +        goto out;
> +
> +    if ( likely(test_bit(_IRQ_GUEST, &desc->status) ||
> +                test_bit(_IRQ_MOVE_PENDING, &desc->status)) )
> +        goto out;
> +
> +    /*
> +     * Setting affinity to a mask of multiple CPUs causes the GIC drivers to
> +     * select one CPU from that mask. If the dying CPU was included in the 
> IRQ's
> +     * affinity mask, we cannot determine exactly which CPU the interrupt is
> +     * currently routed to, as GIC drivers lack a concrete get_affinity API. 
> So
> +     * to be safe we must reroute it to a new, definitely online, CPU. In the
> +     * case of CPU going down, we move only the interrupt that could reside 
> on
> +     * it. Otherwise, we rearrange all interrupts in a round-robin fashion.
> +     */
> +    if ( !up && !cpumask_test_cpu(from, desc->affinity) )
> +        goto out;
> +
> +    cpu_next = cpumask_cycle(cpu_next, &cpu_online_map);
> +    irq_set_affinity(desc, cpumask_of(cpu_next));
> +
> +out:
> +    spin_unlock_irqrestore(&desc->lock, flags);
> +}
> +
> +static void rebalance_irqs(unsigned int from, bool up)
> +{
> +    int irq;
> +
> +    if ( cpumask_empty(&cpu_online_map) )
> +        return;
> +
> +    for ( irq = NR_LOCAL_IRQS; irq < NR_IRQS; irq++ )
> +        balance_irq(irq, from, up);
> +
> +#ifdef CONFIG_GICV3_ESPI
> +    for ( irq = ESPI_BASE_INTID; irq < ESPI_BASE_INTID + gic_number_espis();
> +          irq++ )
> +        balance_irq(irq, from, up);
> +#endif
> +}
> +
>  static int cpu_callback(struct notifier_block *nfb, unsigned long action,
>                          void *hcpu)
>  {
> @@ -180,6 +232,15 @@ static int cpu_callback(struct notifier_block *nfb, 
> unsigned long action,
>              printk(XENLOG_ERR "Unable to allocate local IRQ for CPU%u\n",
>                     cpu);
>          break;
> +    case CPU_ONLINE:
> +        if ( IS_ENABLED(CONFIG_CPU_ONLINE_OFFLINE) &&
> +             system_state >= SYS_STATE_active )
> +            rebalance_irqs(cpu, true);
> +        break;
> +    case CPU_DEAD:
> +        if ( IS_ENABLED(CONFIG_CPU_ONLINE_OFFLINE) )
> +            rebalance_irqs(cpu, false);
> +        break;
>      }
>  
>      return notifier_from_errno(rc);

-- 
WBR, Volodymyr


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.