octeontx2-af: Use separate handlers for interrupts
authorSubbaraya Sundeep <sbhatta@marvell.com>
Mon, 18 Mar 2024 09:29:58 +0000 (14:59 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Mar 2024 10:49:07 +0000 (10:49 +0000)
For PF to AF interrupt vector and VF to AF vector same
interrupt handler is registered which is causing race condition.
When two interrupts are raised to two CPUs at same time
then two cores serve same event corrupting the data.

Fixes: 7304ac4567bc ("octeontx2-af: Add mailbox IRQ and msg handlers")
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/rvu.c

index 0b65a18c3a882c73da27c266aa334c48322c21ce..ff78251f92d4480a72f9c1ce0c268bf8aaa76f4f 100644 (file)
@@ -2533,10 +2533,9 @@ static void rvu_queue_work(struct mbox_wq_info *mw, int first,
        }
 }
 
-static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq)
 {
        struct rvu *rvu = (struct rvu *)rvu_irq;
-       int vfs = rvu->vfs;
        u64 intr;
 
        intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT);
@@ -2550,6 +2549,18 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
 
        rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr);
 
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+{
+       struct rvu *rvu = (struct rvu *)rvu_irq;
+       int vfs = rvu->vfs;
+       u64 intr;
+
+       /* Sync with mbox memory region */
+       rmb();
+
        /* Handle VF interrupts */
        if (vfs > 64) {
                intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1));
@@ -2894,7 +2905,7 @@ static int rvu_register_interrupts(struct rvu *rvu)
        /* Register mailbox interrupt handler */
        sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox");
        ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX),
-                         rvu_mbox_intr_handler, 0,
+                         rvu_mbox_pf_intr_handler, 0,
                          &rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu);
        if (ret) {
                dev_err(rvu->dev,