Index: sys/arm64/iommu/iommu.c =================================================================== --- sys/arm64/iommu/iommu.c +++ sys/arm64/iommu/iommu.c @@ -410,16 +410,10 @@ static void iommu_domain_free_entry(struct iommu_map_entry *entry, bool free) { - struct iommu_domain *iodom; - - iodom = entry->domain; - - IOMMU_DOMAIN_LOCK(iodom); - iommu_gas_free_space(iodom, entry); - IOMMU_DOMAIN_UNLOCK(iodom); + iommu_gas_free_space(entry); if (free) - iommu_gas_free_entry(iodom, entry); + iommu_gas_free_entry(entry); else entry->flags = 0; } Index: sys/dev/iommu/busdma_iommu.c =================================================================== --- sys/dev/iommu/busdma_iommu.c +++ sys/dev/iommu/busdma_iommu.c @@ -1040,7 +1040,7 @@ ma = malloc(sizeof(vm_page_t) * atop(length), M_TEMP, waitok ? M_WAITOK : M_NOWAIT); if (ma == NULL) { - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); return (ENOMEM); } for (i = 0; i < atop(length); i++) { @@ -1055,7 +1055,7 @@ TAILQ_INSERT_TAIL(&map->map_entries, entry, dmamap_link); IOMMU_DMAMAP_UNLOCK(map); } else { - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); } for (i = 0; i < atop(length); i++) vm_page_putfake(ma[i]); Index: sys/dev/iommu/iommu.h =================================================================== --- sys/dev/iommu/iommu.h +++ sys/dev/iommu/iommu.h @@ -169,15 +169,12 @@ void iommu_gas_fini_domain(struct iommu_domain *domain); struct iommu_map_entry *iommu_gas_alloc_entry(struct iommu_domain *domain, u_int flags); -void iommu_gas_free_entry(struct iommu_domain *domain, - struct iommu_map_entry *entry); -void iommu_gas_free_space(struct iommu_domain *domain, - struct iommu_map_entry *entry); +void iommu_gas_free_entry(struct iommu_map_entry *entry); +void iommu_gas_free_space(struct iommu_map_entry *entry); int iommu_gas_map(struct iommu_domain *domain, const struct bus_dma_tag_common *common, iommu_gaddr_t size, int offset, u_int eflags, u_int flags, vm_page_t *ma, struct iommu_map_entry **res); -void iommu_gas_free_region(struct iommu_domain *domain, - struct iommu_map_entry *entry); +void iommu_gas_free_region(struct iommu_map_entry *entry); int iommu_gas_map_region(struct iommu_domain *domain, struct iommu_map_entry *entry, u_int eflags, u_int flags, vm_page_t *ma); int iommu_gas_reserve_region(struct iommu_domain *domain, iommu_gaddr_t start, Index: sys/dev/iommu/iommu_gas.c =================================================================== --- sys/dev/iommu/iommu_gas.c +++ sys/dev/iommu/iommu_gas.c @@ -107,12 +107,11 @@ } void -iommu_gas_free_entry(struct iommu_domain *domain, struct iommu_map_entry *entry) +iommu_gas_free_entry(struct iommu_map_entry *entry) { + struct iommu_domain *domain; - KASSERT(domain == entry->domain, - ("mismatched free domain %p entry %p entry->domain %p", domain, - entry, entry->domain)); + domain = entry->domain; if (domain != NULL) atomic_subtract_int(&domain->entries_cnt, 1); uma_zfree(iommu_map_entry_zone, entry); @@ -261,7 +260,7 @@ (IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED), ("start entry flags %p", domain)); RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry); - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); entry = RB_MAX(iommu_gas_entries_tree, &domain->rb_root); KASSERT(entry->start == domain->end, ("end entry start %p", domain)); @@ -270,7 +269,7 @@ (IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED), ("end entry flags %p", domain)); RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry); - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); RB_FOREACH_SAFE(entry, iommu_gas_entries_tree, &domain->rb_root, entry1) { @@ -278,7 +277,7 @@ ("non-RMRR entry left %p", domain)); RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry); - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); } } @@ -558,32 +557,37 @@ } void -iommu_gas_free_space(struct iommu_domain *domain, struct iommu_map_entry *entry) +iommu_gas_free_space(struct iommu_map_entry *entry) { + struct iommu_domain *domain; - IOMMU_DOMAIN_ASSERT_LOCKED(domain); + domain = entry->domain; KASSERT((entry->flags & (IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_RMRR | IOMMU_MAP_ENTRY_MAP)) == IOMMU_MAP_ENTRY_MAP, ("permanent entry %p %p", domain, entry)); + IOMMU_DOMAIN_LOCK(domain); iommu_gas_rb_remove(domain, entry); entry->flags &= ~IOMMU_MAP_ENTRY_MAP; #ifdef INVARIANTS if (iommu_check_free) iommu_gas_check_free(domain); #endif + IOMMU_DOMAIN_UNLOCK(domain); } void -iommu_gas_free_region(struct iommu_domain *domain, struct iommu_map_entry *entry) +iommu_gas_free_region(struct iommu_map_entry *entry) { + struct iommu_domain *domain; struct iommu_map_entry *next, *prev; - IOMMU_DOMAIN_ASSERT_LOCKED(domain); + domain = entry->domain; KASSERT((entry->flags & (IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_RMRR | IOMMU_MAP_ENTRY_MAP)) == IOMMU_MAP_ENTRY_RMRR, ("non-RMRR entry %p %p", domain, entry)); + IOMMU_DOMAIN_LOCK(domain); prev = RB_PREV(iommu_gas_entries_tree, &domain->rb_root, entry); next = RB_NEXT(iommu_gas_entries_tree, &domain->rb_root, entry); iommu_gas_rb_remove(domain, entry); @@ -593,6 +597,7 @@ iommu_gas_rb_insert(domain, domain->first_place); if (next == NULL) iommu_gas_rb_insert(domain, domain->last_place); + IOMMU_DOMAIN_UNLOCK(domain); } int @@ -621,7 +626,7 @@ error = iommu_gas_find_space(&a); if (error == ENOMEM) { IOMMU_DOMAIN_UNLOCK(domain); - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); return (error); } #ifdef INVARIANTS @@ -716,7 +721,7 @@ error = iommu_gas_reserve_region_locked(domain, start, end, entry); IOMMU_DOMAIN_UNLOCK(domain); if (error != 0) - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); else if (entry0 != NULL) *entry0 = entry; return (error); @@ -770,7 +775,7 @@ } /* Release a preallocated entry if it was not used. */ if (entry != NULL) - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); return (error); } @@ -788,11 +793,9 @@ domain->ops->unmap(domain, entry->start, entry->end - entry->start, IOMMU_PGF_WAITOK); - IOMMU_DOMAIN_LOCK(domain); - iommu_gas_free_space(domain, entry); - IOMMU_DOMAIN_UNLOCK(domain); + iommu_gas_free_space(entry); - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); domain->msi_entry = NULL; domain->msi_base = 0; @@ -832,7 +835,7 @@ * We lost the race and already have an * MSI page allocated. Free the unneeded entry. */ - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); } } else if (domain->msi_entry != NULL) { /* Index: sys/x86/iommu/intel_ctx.c =================================================================== --- sys/x86/iommu/intel_ctx.c +++ sys/x86/iommu/intel_ctx.c @@ -307,7 +307,7 @@ error = error1; } TAILQ_REMOVE(&rmrr_entries, entry, dmamap_link); - iommu_gas_free_entry(DOM2IODOM(domain), entry); + iommu_gas_free_entry(entry); } for (i = 0; i < size; i++) vm_page_putfake(ma[i]); @@ -852,17 +852,12 @@ void dmar_domain_free_entry(struct iommu_map_entry *entry, bool free) { - struct iommu_domain *domain; - - domain = entry->domain; - IOMMU_DOMAIN_LOCK(domain); if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) - iommu_gas_free_region(domain, entry); + iommu_gas_free_region(entry); else - iommu_gas_free_space(domain, entry); - IOMMU_DOMAIN_UNLOCK(domain); + iommu_gas_free_space(entry); if (free) - iommu_gas_free_entry(domain, entry); + iommu_gas_free_entry(entry); else entry->flags = 0; } Index: sys/x86/iommu/intel_qi.c =================================================================== --- sys/x86/iommu/intel_qi.c +++ sys/x86/iommu/intel_qi.c @@ -415,7 +415,6 @@ dmar_qi_task(void *arg, int pending __unused) { struct dmar_unit *unit; - struct iommu_domain *domain; struct iommu_map_entry *entry, *head; uint32_t ics; @@ -440,14 +439,11 @@ if (!dmar_qi_seq_processed(unit, &entry->gseq)) break; unit->tlb_flush_head = entry; - iommu_gas_free_entry(head->domain, head); - domain = entry->domain; - IOMMU_DOMAIN_LOCK(domain); + iommu_gas_free_entry(head); if ((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0) - iommu_gas_free_region(domain, entry); + iommu_gas_free_region(entry); else - iommu_gas_free_space(domain, entry); - IOMMU_DOMAIN_UNLOCK(domain); + iommu_gas_free_space(entry); } if (unit->inv_seq_waiters > 0) { /*