[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAEHaoC3t8nFhR4MAYV1AaR5mjN4ndkkWrKUyBY_smbtpDykAEA@mail.gmail.com>
Date: Sun, 3 Aug 2025 14:13:37 +0300
From: Constantine Gavrilov <cgavrilov@...inidat.com>
To: linux-kernel@...r.kernel.org, Marek Szyprowski <m.szyprowski@...sung.com>,
Robin Murphy <robin.murphy@....com>, iommu@...ts.linux.dev
Subject: [PATCH 5/8] Large DMA alloc/remove max32_alloc_size field
This is the sixth patch from the set of patches that enable large IOMMU
DMA registrations. Entire work is available at the master branch of the
master branch of git@...hub.com:cgavrilov/linux.git repo.
This patch removes max32_alloc_size field from the iova_domain structure.
This field was introduced to optimize the path of allocation failure (return
failed allocation without checking for available regions), but was not
implemented correctly, resulting in failed allocations when the space maybe
available.
commit cfdad4eb84e8c5dc7aa3f868575007de2e1fc1e4
Author: Constantine Gavrilov <cgavrilov@...inidat.com>
Date: Tue Jul 1 10:05:11 2025 +0300
Removed max32_alloc_size field from the iova_domain structure.
This field exists for the purpose of optimizing a path of failed
allocations in 32-bit DMA space, when the 32-bit range is depleted.
There are a number of issues:
1. max32_alloc_size is updated in __alloc_and_insert_iova_range()
without checking the size after allocation of the range fails. This
will cause a wrong failed small allocation after a "big" allocation
fails.
2. max32_alloc_size is updated in __cached_rbnode_delete_update()
without checking the top bound of the released range and the size
of the released range. This defeats the purpose of the intended
"optimization".
3. Alignment constraints and DMA address limits are not taken into account
when updating this field after the allocation fails. This results in
future allocation failures that can succeed if looking for available
ranges is not skipped.
Rather than fixing this "optimization", remove it altogether. We shall
not optimize for failed allocation path that is rare, and the optimizing
affect of this feature is questionable.
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index aba58630be12..0c436dd35404 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -52,7 +52,6 @@ init_iova_domain(struct iova_domain *iovad, unsigned
long granule,
iovad->granule = granule;
iovad->start_pfn = start_pfn;
iovad->dma_32bit_pfn = 1UL << (32 - iova_shift(iovad));
- iovad->max32_alloc_size = iovad->dma_32bit_pfn;
iovad->anchor.pfn_lo = iovad->anchor.pfn_hi = IOVA_ANCHOR;
rb_link_node(&iovad->anchor.node, NULL, &iovad->rbroot.rb_node);
rb_insert_color(&iovad->anchor.node, &iovad->rbroot);
@@ -88,9 +87,6 @@ __cached_rbnode_delete_update(struct iova_domain
*iovad, struct iova *free)
free->pfn_lo >= cached_iova->pfn_lo))
iovad->cached32_node = rb_next(&free->node);
- if (free->pfn_lo < iovad->dma_32bit_pfn)
- iovad->max32_alloc_size = iovad->dma_32bit_pfn;
-
cached_iova = to_iova(iovad->cached_node);
if (free->pfn_lo >= cached_iova->pfn_lo)
iovad->cached_node = rb_next(&free->node);
@@ -182,9 +178,6 @@ static int __alloc_and_insert_iova_range(struct
iova_domain *iovad,
/* Walk the tree backwards */
spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
- if (limit_pfn <= iovad->dma_32bit_pfn &&
- size >= iovad->max32_alloc_size)
- goto iova32_full;
curr = __get_cached_rbnode(iovad, limit_pfn);
curr_iova = to_iova(curr);
@@ -207,7 +200,6 @@ static int __alloc_and_insert_iova_range(struct
iova_domain *iovad,
curr_iova = to_iova(curr);
goto retry;
}
- iovad->max32_alloc_size = size;
goto iova32_full;
}
diff --git a/include/linux/iova.h b/include/linux/iova.h
index 30ce5ad499d2..2800bdc203b1 100644
--- a/include/linux/iova.h
+++ b/include/linux/iova.h
@@ -33,7 +33,6 @@ struct iova_domain {
unsigned long granule; /* pfn granularity for this domain */
unsigned long start_pfn; /* Lower limit for this domain */
unsigned long dma_32bit_pfn;
- unsigned long max32_alloc_size; /* Size of last failed allocation */
struct iova anchor; /* rbtree lookup anchor */
struct iova_rcache *rcaches;
--
----------------------------------------
Constantine Gavrilov
System Architect and Platform Engineer
Infinidat
----------------------------------------
Powered by blists - more mailing lists