[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v1 03/30] RISC-V: Use atomic_cmpxchg to update P
From: |
Alistair Francis |
Subject: |
Re: [Qemu-devel] [PATCH v1 03/30] RISC-V: Use atomic_cmpxchg to update PLIC bitmaps |
Date: |
Tue, 29 May 2018 16:32:11 -0700 |
On Tue, May 22, 2018 at 5:14 PM, Michael Clark <address@hidden> wrote:
> The PLIC previously used a mutex to protect against concurrent
> access to the claimed and pending bitfields. Instead of using
> a mutex, we update the bitfields using atomic_cmpxchg.
>
> Rename sifive_plic_num_irqs_pending to sifive_plic_irqs_pending
> and add an early out if any interrupts are pending as the
> count of pending interrupts is not used.
>
> Cc: Sagar Karandikar <address@hidden>
> Cc: Bastian Koppelmann <address@hidden>
> Cc: Palmer Dabbelt <address@hidden>
> Cc: Alistair Francis <address@hidden>
> Signed-off-by: Michael Clark <address@hidden>
> Reviewed-by: Richard Henderson <address@hidden>
Reviewed-by: Alistair Francis <address@hidden>
Alistair
> ---
> hw/riscv/sifive_plic.c | 49
> +++++++++++++++++++-----------------------
> include/hw/riscv/sifive_plic.h | 1 -
> 2 files changed, 22 insertions(+), 28 deletions(-)
>
> diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
> index 874de2ebaf77..1af23c76e603 100644
> --- a/hw/riscv/sifive_plic.c
> +++ b/hw/riscv/sifive_plic.c
> @@ -81,36 +81,32 @@ static void sifive_plic_print_state(SiFivePLICState *plic)
> }
> }
>
> -static
> -void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool pending)
> +static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value)
> {
> - qemu_mutex_lock(&plic->lock);
> - uint32_t word = irq >> 5;
> - if (pending) {
> - plic->pending[word] |= (1 << (irq & 31));
> - } else {
> - plic->pending[word] &= ~(1 << (irq & 31));
> - }
> - qemu_mutex_unlock(&plic->lock);
> + uint32_t old, new, cmp = atomic_read(a);
> +
> + do {
> + old = cmp;
> + new = (old & ~mask) | (value & mask);
> + cmp = atomic_cmpxchg(a, old, new);
> + } while (old != cmp);
> +
> + return old;
> }
>
> -static
> -void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool claimed)
> +static void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool
> level)
> {
> - qemu_mutex_lock(&plic->lock);
> - uint32_t word = irq >> 5;
> - if (claimed) {
> - plic->claimed[word] |= (1 << (irq & 31));
> - } else {
> - plic->claimed[word] &= ~(1 << (irq & 31));
> - }
> - qemu_mutex_unlock(&plic->lock);
> + atomic_set_masked(&plic->pending[irq >> 5], 1 << (irq & 31), -!!level);
> }
>
> -static
> -int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
> +static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool
> level)
> {
> - int i, j, count = 0;
> + atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level);
> +}
> +
> +static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
> +{
> + int i, j;
> for (i = 0; i < plic->bitfield_words; i++) {
> uint32_t pending_enabled_not_claimed =
> (plic->pending[i] & ~plic->claimed[i]) &
> @@ -123,11 +119,11 @@ int sifive_plic_num_irqs_pending(SiFivePLICState *plic,
> uint32_t addrid)
> uint32_t prio = plic->source_priority[irq];
> int enabled = pending_enabled_not_claimed & (1 << j);
> if (enabled && prio > plic->target_priority[addrid]) {
> - count++;
> + return 1;
> }
> }
> }
> - return count;
> + return 0;
> }
>
> static void sifive_plic_update(SiFivePLICState *plic)
> @@ -143,7 +139,7 @@ static void sifive_plic_update(SiFivePLICState *plic)
> if (!env) {
> continue;
> }
> - int level = sifive_plic_num_irqs_pending(plic, addrid) > 0;
> + int level = sifive_plic_irqs_pending(plic, addrid);
> switch (mode) {
> case PLICMode_M:
> riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level);
> @@ -440,7 +436,6 @@ static void sifive_plic_realize(DeviceState *dev, Error
> **errp)
> memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
> TYPE_SIFIVE_PLIC, plic->aperture_size);
> parse_hart_config(plic);
> - qemu_mutex_init(&plic->lock);
> plic->bitfield_words = (plic->num_sources + 31) >> 5;
> plic->source_priority = g_new0(uint32_t, plic->num_sources);
> plic->target_priority = g_new(uint32_t, plic->num_addrs);
> diff --git a/include/hw/riscv/sifive_plic.h b/include/hw/riscv/sifive_plic.h
> index 11a5a98df1f9..ff09a288261e 100644
> --- a/include/hw/riscv/sifive_plic.h
> +++ b/include/hw/riscv/sifive_plic.h
> @@ -55,7 +55,6 @@ typedef struct SiFivePLICState {
> uint32_t *pending;
> uint32_t *claimed;
> uint32_t *enable;
> - QemuMutex lock;
> qemu_irq *irqs;
>
> /* config */
> --
> 2.7.0
>
>
- [Qemu-devel] [PATCH v1 00/30] QEMU 2.13 RISC-V updates, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 01/30] RISC-V: Update address bits to support sv39 and sv48, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 02/30] RISC-V: Improve page table walker spec compliance, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 03/30] RISC-V: Use atomic_cmpxchg to update PLIC bitmaps, Michael Clark, 2018/05/22
- Re: [Qemu-devel] [PATCH v1 03/30] RISC-V: Use atomic_cmpxchg to update PLIC bitmaps,
Alistair Francis <=
- [Qemu-devel] [PATCH v1 04/30] RISC-V: Simplify riscv_cpu_local_irqs_pending, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 05/30] RISC-V: Allow setting and clearing multiple irqs, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 06/30] RISC-V: Move non-ops from op_helper to cpu_helper, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 07/30] RISC-V: Update CSR and interrupt definitions, Michael Clark, 2018/05/22
- [Qemu-devel] [PATCH v1 09/30] RISC-V: Implement atomic mip/sip CSR updates, Michael Clark, 2018/05/22