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
This commit is contained in:
Alan Cox 2022-07-17 19:56:39 -05:00
parent 05350f0936
commit 4eaaacc755

View File

@ -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);