git: db0110a536bf - main - iommu: Shrink the iommu map entry structure

From: Alan Cox <alc_at_FreeBSD.org>
Date: Sat, 16 Jul 2022 03:26:55 UTC
The branch main has been updated by alc:

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

commit db0110a536bf70c1ff55f3b3f46a0b5a9af46058
Author:     Alan Cox <alc@FreeBSD.org>
AuthorDate: 2022-07-11 03:52:52 +0000
Commit:     Alan Cox <alc@FreeBSD.org>
CommitDate: 2022-07-16 03:24:52 +0000

    iommu: Shrink the iommu map entry structure
    
    Eliminate the unroll_entry field from struct iommu_map_entry, shrinking
    the struct by 16 bytes on 64-bit architectures.
    
    Reviewed by:    kib
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D35769
---
 sys/dev/iommu/busdma_iommu.c | 33 ++++++++++-----------------------
 sys/dev/iommu/iommu.h        |  2 --
 sys/x86/iommu/intel_ctx.c    |  4 ++--
 sys/x86/iommu/intel_drv.c    |  2 +-
 4 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c
index 69cf9dd12e7e..10e7476b35eb 100644
--- a/sys/dev/iommu/busdma_iommu.c
+++ b/sys/dev/iommu/busdma_iommu.c
@@ -558,7 +558,7 @@ static int
 iommu_bus_dmamap_load_something1(struct bus_dma_tag_iommu *tag,
     struct bus_dmamap_iommu *map, vm_page_t *ma, int offset, bus_size_t buflen,
     int flags, bus_dma_segment_t *segs, int *segp,
-    struct iommu_map_entries_tailq *unroll_list)
+    struct iommu_map_entries_tailq *entries)
 {
 	struct iommu_ctx *ctx;
 	struct iommu_domain *domain;
@@ -626,10 +626,7 @@ iommu_bus_dmamap_load_something1(struct bus_dma_tag_iommu *tag,
 
 		KASSERT((entry->flags & IOMMU_MAP_ENTRY_MAP) != 0,
 		    ("entry %p missing IOMMU_MAP_ENTRY_MAP", entry));
-		IOMMU_DMAMAP_LOCK(map);
-		TAILQ_INSERT_TAIL(&map->map_entries, entry, dmamap_link);
-		IOMMU_DMAMAP_UNLOCK(map);
-		TAILQ_INSERT_TAIL(unroll_list, entry, unroll_link);
+		TAILQ_INSERT_TAIL(entries, entry, dmamap_link);
 
 		segs[seg].ds_addr = entry->start + offset;
 		segs[seg].ds_len = buflen1;
@@ -651,36 +648,26 @@ iommu_bus_dmamap_load_something(struct bus_dma_tag_iommu *tag,
 {
 	struct iommu_ctx *ctx;
 	struct iommu_domain *domain;
-	struct iommu_map_entry *entry;
-	struct iommu_map_entries_tailq entries, unroll_list;
+	struct iommu_map_entries_tailq entries;
 	int error;
 
 	ctx = tag->ctx;
 	domain = ctx->domain;
 	atomic_add_long(&ctx->loads, 1);
 
-	TAILQ_INIT(&unroll_list);
+	TAILQ_INIT(&entries);
 	error = iommu_bus_dmamap_load_something1(tag, map, ma, offset,
-	    buflen, flags, segs, segp, &unroll_list);
-	if (error != 0 && !TAILQ_EMPTY(&unroll_list)) {
+	    buflen, flags, segs, segp, &entries);
+	if (error == 0) {
+		IOMMU_DMAMAP_LOCK(map);
+		TAILQ_CONCAT(&map->map_entries, &entries, dmamap_link);
+		IOMMU_DMAMAP_UNLOCK(map);
+	} else if (!TAILQ_EMPTY(&entries)) {
 		/*
 		 * The busdma interface does not allow us to report
 		 * partial buffer load, so unfortunately we have to
 		 * revert all work done.
 		 */
-		TAILQ_INIT(&entries);
-		IOMMU_DMAMAP_LOCK(map);
-		TAILQ_FOREACH(entry, &unroll_list, unroll_link) {
-			/*
-			 * No entries other than what we have created
-			 * during the failed run might have been
-			 * inserted there in between, since we own ctx
-			 * pglock.
-			 */
-			TAILQ_REMOVE(&map->map_entries, entry, dmamap_link);
-			TAILQ_INSERT_TAIL(&entries, entry, dmamap_link);
-		}
-		IOMMU_DMAMAP_UNLOCK(map);
 		IOMMU_DOMAIN_LOCK(domain);
 		TAILQ_CONCAT(&domain->unload_entries, &entries, dmamap_link);
 		IOMMU_DOMAIN_UNLOCK(domain);
diff --git a/sys/dev/iommu/iommu.h b/sys/dev/iommu/iommu.h
index 3800213a1d64..62b5659b6e83 100644
--- a/sys/dev/iommu/iommu.h
+++ b/sys/dev/iommu/iommu.h
@@ -58,8 +58,6 @@ struct iommu_map_entry {
 	u_int flags;
 	TAILQ_ENTRY(iommu_map_entry) dmamap_link; /* Link for dmamap entries */
 	RB_ENTRY(iommu_map_entry) rb_entry;	 /* Links for domain entries */
-	TAILQ_ENTRY(iommu_map_entry) unroll_link; /* Link for unroll after
-						    dmamap_load failure */
 	struct iommu_domain *domain;
 	struct iommu_qi_genseq gseq;
 };
diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c
index 815dc6146b00..79e2a15d80c7 100644
--- a/sys/x86/iommu/intel_ctx.c
+++ b/sys/x86/iommu/intel_ctx.c
@@ -245,7 +245,7 @@ domain_init_rmrr(struct dmar_domain *domain, device_t dev, int bus,
 	TAILQ_INIT(&rmrr_entries);
 	dmar_dev_parse_rmrr(domain, dev_domain, dev_busno, dev_path,
 	    dev_path_len, &rmrr_entries);
-	TAILQ_FOREACH_SAFE(entry, &rmrr_entries, unroll_link, entry1) {
+	TAILQ_FOREACH_SAFE(entry, &rmrr_entries, dmamap_link, entry1) {
 		/*
 		 * VT-d specification requires that the start of an
 		 * RMRR entry is 4k-aligned.  Buggy BIOSes put
@@ -306,7 +306,7 @@ domain_init_rmrr(struct dmar_domain *domain, device_t dev, int bus,
 				    error1);
 				error = error1;
 			}
-			TAILQ_REMOVE(&rmrr_entries, entry, unroll_link);
+			TAILQ_REMOVE(&rmrr_entries, entry, dmamap_link);
 			iommu_gas_free_entry(DOM2IODOM(domain), entry);
 		}
 		for (i = 0; i < size; i++)
diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c
index 10709fc0db61..020e97e2dff3 100644
--- a/sys/x86/iommu/intel_drv.c
+++ b/sys/x86/iommu/intel_drv.c
@@ -932,7 +932,7 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
 			/* The RMRR entry end address is inclusive. */
 			entry->end = resmem->EndAddress;
 			TAILQ_INSERT_TAIL(ria->rmrr_entries, entry,
-			    unroll_link);
+			    dmamap_link);
 		}
 	}