aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/iommu
diff options
context:
space:
mode:
authorRuslan Bukin <br@FreeBSD.org>2020-08-06 12:49:25 +0000
committerRuslan Bukin <br@FreeBSD.org>2020-08-06 12:49:25 +0000
commit0424f19e9e85f280834b4879febea79b1115cc06 (patch)
tree6b10c216e93eb3374808dfea6be0cc2878823b5f /sys/dev/iommu
parenta89b0586a35c53e4155973e8f528e0dbbaedd00c (diff)
Notes
Diffstat (limited to 'sys/dev/iommu')
-rw-r--r--sys/dev/iommu/busdma_iommu.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c
index a9db66ecc387..8e266f9f3eb1 100644
--- a/sys/dev/iommu/busdma_iommu.c
+++ b/sys/dev/iommu/busdma_iommu.c
@@ -1064,6 +1064,26 @@ bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map1,
return (error);
}
+static void
+iommu_domain_unload_task(void *arg, int pending)
+{
+ struct iommu_domain *domain;
+ struct iommu_map_entries_tailq entries;
+
+ domain = arg;
+ TAILQ_INIT(&entries);
+
+ for (;;) {
+ IOMMU_DOMAIN_LOCK(domain);
+ TAILQ_SWAP(&domain->unload_entries, &entries,
+ iommu_map_entry, dmamap_link);
+ IOMMU_DOMAIN_UNLOCK(domain);
+ if (TAILQ_EMPTY(&entries))
+ break;
+ iommu_domain_unload(domain, &entries, true);
+ }
+}
+
void
iommu_domain_init(struct iommu_unit *unit, struct iommu_domain *domain,
const struct iommu_domain_map_ops *ops)
@@ -1072,6 +1092,7 @@ iommu_domain_init(struct iommu_unit *unit, struct iommu_domain *domain,
domain->ops = ops;
domain->iommu = unit;
+ TASK_INIT(&domain->unload_task, 0, iommu_domain_unload_task, domain);
RB_INIT(&domain->rb_root);
TAILQ_INIT(&domain->unload_entries);
mtx_init(&domain->lock, "iodom", NULL, MTX_DEF);