The branch main has been updated by alc:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4eaaacc75535befdb9894cca4e0d8da376328fa4

commit 4eaaacc75535befdb9894cca4e0d8da376328fa4
Author:     Alan Cox <a...@freebsd.org>
AuthorDate: 2022-07-18 00:56:39 +0000
Commit:     Alan Cox <a...@freebsd.org>
CommitDate: 2022-07-19 03:23:13 +0000

    x86/iommu: Shrink the critical section in dmar_qi_task()
    
    It is safe to test and clear the Invalidation Wait Descriptor
    Complete flag before acquiring the DMAR lock in dmar_qi_task(),
    rather than waiting until the lock is held.
    
    Reviewed by:    kib
    MFC after:      2 weeks
---
 sys/x86/iommu/intel_qi.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c
index 894e3d537ac7..ca58715a227c 100644
--- a/sys/x86/iommu/intel_qi.c
+++ b/sys/x86/iommu/intel_qi.c
@@ -343,6 +343,16 @@ dmar_qi_task(void *arg, int pending __unused)
 
        unit = arg;
 
+       /*
+        * Request an interrupt on the completion of the next invalidation
+        * wait descriptor with the IF field set.
+        */
+       ics = dmar_read4(unit, DMAR_ICS_REG);
+       if ((ics & DMAR_ICS_IWC) != 0) {
+               ics = DMAR_ICS_IWC;
+               dmar_write4(unit, DMAR_ICS_REG, ics);
+       }
+
        DMAR_LOCK(unit);
        for (;;) {
                entry = TAILQ_FIRST(&unit->tlb_flush_entries);
@@ -356,11 +366,6 @@ dmar_qi_task(void *arg, int pending __unused)
                    IOMMU_MAP_ENTRY_QI_NF) == 0);
                DMAR_LOCK(unit);
        }
-       ics = dmar_read4(unit, DMAR_ICS_REG);
-       if ((ics & DMAR_ICS_IWC) != 0) {
-               ics = DMAR_ICS_IWC;
-               dmar_write4(unit, DMAR_ICS_REG, ics);
-       }
        if (unit->inv_seq_waiters > 0)
                wakeup(&unit->inv_seq_waiters);
        DMAR_UNLOCK(unit);

Reply via email to