lib: sbi: Prevent redundant sbi_ipi_process
authorXiang W <wxjstz@126.com>
Wed, 22 Nov 2023 12:54:38 +0000 (20:54 +0800)
committerAnup Patel <anup@brainfault.org>
Fri, 8 Dec 2023 11:37:03 +0000 (17:07 +0530)
Multiple harts may try to send IPI to a particular target hart A
in which case the send_ipi() should be called only when the old
value of the hart A ipi_type is zero.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
lib/sbi/sbi_ipi.c

index 0bf446a046e707cd0595fd191abfd718e04bcfde..5c33a78b2f3af6ac659802f2c6c04ea5cafa4b39 100644 (file)
@@ -39,7 +39,7 @@ static const struct sbi_ipi_event_ops *ipi_ops_array[SBI_IPI_EVENT_MAX];
 static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartindex,
                        u32 event, void *data)
 {
-       int ret;
+       int ret = 0;
        struct sbi_scratch *remote_scratch = NULL;
        struct sbi_ipi_data *ipi_data;
        const struct sbi_ipi_event_ops *ipi_ops;
@@ -64,11 +64,15 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartindex,
 
        /*
         * Set IPI type on remote hart's scratch area and
-        * trigger the interrupt
+        * trigger the interrupt.
+        *
+        * Multiple harts may be trying to send IPI to the
+        * remote hart so call sbi_ipi_raw_send() only when
+        * the ipi_type was previously zero.
         */
-       atomic_raw_set_bit(event, &ipi_data->ipi_type);
-
-       ret = sbi_ipi_raw_send(remote_hartindex);
+       if (!__atomic_fetch_or(&ipi_data->ipi_type,
+                               BIT(event), __ATOMIC_RELAXED))
+               ret = sbi_ipi_raw_send(remote_hartindex);
 
        sbi_pmu_ctr_incr_fw(SBI_PMU_FW_IPI_SENT);