Bruce Ashfield
2024-07-12 03:00
I'd still like more explanation on this change and if it was tested in a 
heavily loaded system (and for how long). Looking at the spinlock change and 
the comments immediately below the patch, we have a write memory barrier AND a 
mention of ipis. When a rawlock is taken, we need to understand what happens 
between the take and release. I'm seeing a lot of retry logic / looping, etc. 
If that lock is held for too long or there's some way that the current thread 
might be suspended, we could easily end up with high latency or a system 
deadlock.
The frequency of IPI loss is low. After half an hour of stress-ng testing, I 
captured
only one instance of IPI retransmission.
This mechanism detects and resends IPIs, and despite the looping code, it does
not cause significant latency or deadlock.

Thanks,
Ruiqiang
________________________________
From: Bruce Ashfield <bruce.ashfi...@gmail.com>
Sent: Friday, July 12, 2024 03:00
To: Hao, Ruiqiang <ruiqiang....@windriver.com>
Cc: linux-yocto@lists.yoctoproject.org <linux-yocto@lists.yoctoproject.org>
Subject: Re: [PATCH] irqchip/gic-v3: change gic_ipi_track::lock type

CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender and know 
the content is safe.

In message: [PATCH] irqchip/gic-v3: change gic_ipi_track::lock type
on 10/07/2024 Ruiqiang Hao wrote:

> From: Ruiqiang Hao <ruiqiang....@windriver.com>
>
> When start with preempt-rt kernel, the following problem occurs.
> Change the type of gic_ipi_track::lock from spinlock_t to raw_spinlock_t
> to fix this.
>
> BUG: sleeping function called from invalid context at 
> kernel/locking/spinlock_rt.c:46
> in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/15
> preempt_count: 6, expected: 0
> RCU nest depth: 0, expected: 0
> Preemption disabled at:
> [<ffff800008246370>] __create_object+0x110/0x380
> CPU: 15 PID: 0 Comm: swapper/15 Tainted: G        W          
> 6.1.90-rt18-yocto-preempt-rt #1
> Hardware name: Marvell OcteonTX CN96XX board (DT)
> Call trace:
>  dump_backtrace.part.0+0xe8/0xf4
>  show_stack+0x20/0x30
>  dump_stack_lvl+0x64/0x80
>  dump_stack+0x18/0x34
>  __might_resched+0x160/0x1c0
>  rt_spin_lock+0x38/0xd0
>  gic_write_sgi1r_retry+0x58/0x120
>  gic_ipi_send_mask+0x148/0x184
>  __ipi_send_mask+0x34/0x11c
>  smp_cross_call+0x4c/0x10c
>  arch_irq_work_raise+0x3c/0x4c
>  __irq_work_queue_local+0x9c/0xb0
>  irq_work_queue+0x48/0x80
>  sugov_update_shared+0x258/0x260
>  enqueue_top_rt_rq+0x7c/0x124
>  enqueue_task_rt+0x1cc/0x2ec
>  ttwu_do_activate+0x84/0x170
>  try_to_wake_up+0x21c/0x5c0
>  wake_up_process+0x20/0x30
>  irq_exit_rcu+0x134/0x140
>  el1_interrupt+0x38/0x70
>  el1h_64_irq_handler+0x18/0x2c
>  el1h_64_irq+0x64/0x68
>  arch_cpu_idle+0x18/0x2c
>  default_idle_call+0x40/0x1d0
>  do_idle+0x230/0x2a0
>  cpu_startup_entry+0x3c/0x4c
>  secondary_start_kernel+0x120/0x14c
>  __secondary_switched+0xb0/0xb4
>
> Signed-off-by: Ruiqiang Hao <ruiqiang....@windriver.com>
> ---
>  drivers/irqchip/irq-gic-v3-fixes.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3-fixes.c 
> b/drivers/irqchip/irq-gic-v3-fixes.c
> index 7d88e3295686..62d41cb4e9a4 100644
> --- a/drivers/irqchip/irq-gic-v3-fixes.c
> +++ b/drivers/irqchip/irq-gic-v3-fixes.c
> @@ -31,7 +31,7 @@ enum ipi_msg_type {
>  struct gic_ipi_track {
>       atomic_t tx_count;
>       atomic_t rx_count;
> -     spinlock_t lock;
> +     raw_spinlock_t lock;
>  };
>
>  static struct gic_ipi_track gic_ipitrack[NR_CPUS][NR_IPIS];
> @@ -79,7 +79,7 @@ void gic_write_sgi1r_retry(int dest_cpu, int irq, u64 val)
>  {
>       unsigned long flags;
>
> -     spin_lock_irqsave(&gic_ipitrack[dest_cpu][irq].lock, flags);
> +     raw_spin_lock_irqsave(&gic_ipitrack[dest_cpu][irq].lock, flags);

Because this is only destined for a BSP branch, I'm not overly
concerned about the changes.

BUT

I'd still like more explanation on this change and if it was
tested in a heavily loaded system (and for how long).

Looking at the spinlock change and the comments immediately
below the patch, we have a write memory barrier AND a mention
of ipis.

When a rawlock is taken, we need to understand what happens
between the take and release. I'm seeing a lot of retry
logic / looping, etc.

If that lock is held for too long or there's some way that
the current thread might be suspended, we could easily
end up with high latency or a system deadlock.

Bruce


>       wmb(); /* Ensure lock is acquired before we generate an IPI */
>  retry:
>       gic_write_sgi1r(val);
> @@ -95,7 +95,7 @@ void gic_write_sgi1r_retry(int dest_cpu, int irq, u64 val)
>       wmb(); /* Ensure the write is completed before we start again */
>       goto retry;
>  out:
> -     spin_unlock_irqrestore(&gic_ipitrack[dest_cpu][irq].lock, flags);
> +     raw_spin_unlock_irqrestore(&gic_ipitrack[dest_cpu][irq].lock, flags);
>  }
>
>  static bool __maybe_unused gicv3_enable_quirk_otx(void *data)
> @@ -107,7 +107,7 @@ static bool __maybe_unused gicv3_enable_quirk_otx(void 
> *data)
>       /* Initialize necessary lock */
>       for_each_possible_cpu(cpu)
>               for (ipi = 0; ipi < NR_IPIS; ipi++)
> -                     spin_lock_init(&gic_ipitrack[cpu][ipi].lock);
> +                     raw_spin_lock_init(&gic_ipitrack[cpu][ipi].lock);
>
>       return true;
>  }
> --
> 2.45.0
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#14176): 
https://lists.yoctoproject.org/g/linux-yocto/message/14176
Mute This Topic: https://lists.yoctoproject.org/mt/107139152/21656
Group Owner: linux-yocto+ow...@lists.yoctoproject.org
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to