Patch "iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     iommu-arm-smmu-v3-acknowledge-pri-event-queue-overfl.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 8eb35f24160476b9e1edf09f3bb81c2a162c00b6
Author: Tomas Krcka <krckatom@xxxxxxxxx>
Date:   Wed Mar 29 12:34:19 2023 +0000

    iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any
    
    [ Upstream commit 67ea0b7ce41844eae7c10bb04dfe66a23318c224 ]
    
    When an overflow occurs in the PRI queue, the SMMU toggles the overflow
    flag in the PROD register. To exit the overflow condition, the PRI thread
    is supposed to acknowledge it by toggling this flag in the CONS register.
    Unacknowledged overflow causes the queue to stop adding anything new.
    
    Currently, the priq thread always writes the CONS register back to the
    SMMU after clearing the queue.
    
    The writeback is not necessary if the OVFLG in the PROD register has not
    been changed, no overflow has occured.
    
    This commit checks the difference of the overflow flag between CONS and
    PROD register. If it's different, toggles the OVACKFLG flag in the CONS
    register and write it to the SMMU.
    
    The situation is similar for the event queue.
    The acknowledge register is also toggled after clearing the event
    queue but never propagated to the hardware. This would only be done the
    next time when executing evtq thread.
    
    Unacknowledged event queue overflow doesn't affect the event
    queue, because the SMMU still adds elements to that queue when the
    overflow condition is active.
    But it feel nicer to keep SMMU in sync when possible, so use the same
    way here as well.
    
    Signed-off-by: Tomas Krcka <krckatom@xxxxxxxxx>
    Link: https://lore.kernel.org/r/20230329123420.34641-1-tomas.krcka@xxxxxxxxx
    Signed-off-by: Will Deacon <will@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4f64c3a9ee88d..b3c5d7b4547a4 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -760,6 +760,18 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q)
 	q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
 }
 
+static void queue_sync_cons_ovf(struct arm_smmu_queue *q)
+{
+	struct arm_smmu_ll_queue *llq = &q->llq;
+
+	if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
+		return;
+
+	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+		      Q_IDX(llq, llq->cons);
+	queue_sync_cons_out(q);
+}
+
 static int queue_sync_prod_in(struct arm_smmu_queue *q)
 {
 	int ret = 0;
@@ -1720,8 +1732,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
 	} while (!queue_empty(llq));
 
 	/* Sync our overflow flag, as we believe we're up to speed */
-	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
-		    Q_IDX(llq, llq->cons);
+	queue_sync_cons_ovf(q);
 	return IRQ_HANDLED;
 }
 
@@ -1779,9 +1790,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
 	} while (!queue_empty(llq));
 
 	/* Sync our overflow flag, as we believe we're up to speed */
-	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
-		      Q_IDX(llq, llq->cons);
-	queue_sync_cons_out(q);
+	queue_sync_cons_ovf(q);
 	return IRQ_HANDLED;
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux