lib: sbi: Allow relaxed MMIO writes in device ipi_send() callback
authorAnup Patel <apatel@ventanamicro.com>
Tue, 21 Nov 2023 09:19:42 +0000 (14:49 +0530)
committerAnup Patel <anup@brainfault.org>
Sun, 26 Nov 2023 13:15:06 +0000 (18:45 +0530)
Currently, we have a smp_wmb() between atomic_raw_set_bit() and
ipi_send() device callback whereas the MMIO writes done by the
device ipi_send() callback will also include a barrier.

We can avoid unnecessary/redundant barriers described above by
allowing relaxed MMIO writes in device ipi_send() callback. To
achieve this, we simply use  wmb() instead of smp_wmb() before
calling device ipi_send().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reported-by: Bo Gan <ganboing@gmail.com>
lib/sbi/sbi_ipi.c
lib/utils/ipi/aclint_mswi.c
lib/utils/irqchip/imsic.c

index 5571b37bdf6965afe92853e83936de37608ad578..1694a23fd8cb680db9741807dd2c4e9e5545431b 100644 (file)
@@ -67,14 +67,12 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartindex,
         * trigger the interrupt
         */
        atomic_raw_set_bit(event, &ipi_data->ipi_type);
-       smp_wmb();
 
-       if (ipi_dev && ipi_dev->ipi_send)
-               ipi_dev->ipi_send(remote_hartindex);
+       ret = sbi_ipi_raw_send(remote_hartindex);
 
        sbi_pmu_ctr_incr_fw(SBI_PMU_FW_IPI_SENT);
 
-       return 0;
+       return ret;
 }
 
 static int sbi_ipi_sync(struct sbi_scratch *scratch, u32 event)
@@ -243,6 +241,15 @@ int sbi_ipi_raw_send(u32 hartindex)
        if (!ipi_dev || !ipi_dev->ipi_send)
                return SBI_EINVAL;
 
+       /*
+        * Ensure that memory or MMIO writes done before
+        * this function are not observed after the memory
+        * or MMIO writes done by the ipi_send() device
+        * callback. This also allows the ipi_send() device
+        * callback to use relaxed MMIO writes.
+        */
+       wmb();
+
        ipi_dev->ipi_send(hartindex);
        return 0;
 }
index a3bfb4a9e3bbeeb0fa9c5a4ff44371da48277b5b..bfd6a45b88eba51c9f4e49c104fbd477d72ad585 100644 (file)
@@ -41,7 +41,7 @@ static void mswi_ipi_send(u32 hart_index)
 
        /* Set ACLINT IPI */
        msip = (void *)mswi->addr;
-       writel(1, &msip[sbi_hartindex_to_hartid(hart_index) -
+       writel_relaxed(1, &msip[sbi_hartindex_to_hartid(hart_index) -
                        mswi->first_hartid]);
 }
 
index 78f5895ac541e717022ead57336ea977df0d6533..36ef66cf1ebbdb81411d0e67440494f19407ff28 100644 (file)
@@ -186,8 +186,8 @@ static void imsic_ipi_send(u32 hart_index)
        }
 
        if (regs->size && (reloff < regs->size))
-               writel(IMSIC_IPI_ID,
-                      (void *)(regs->addr + reloff + IMSIC_MMIO_PAGE_LE));
+               writel_relaxed(IMSIC_IPI_ID,
+                       (void *)(regs->addr + reloff + IMSIC_MMIO_PAGE_LE));
 }
 
 static struct sbi_ipi_device imsic_ipi_device = {