Messages in this thread Patch in this message | | | Date | Fri, 8 Mar 2024 18:28:17 +0100 | From | Petr Tesařík <> | Subject | Re: [PATCH v6 6/6] swiotlb: Reinstate page-alignment for mappings >= PAGE_SIZE |
| |
On Fri, 8 Mar 2024 15:28:29 +0000 Will Deacon <will@kernel.org> wrote:
> For swiotlb allocations >= PAGE_SIZE, the slab search historically > adjusted the stride to avoid checking unaligned slots. This had the > side-effect of aligning large mapping requests to PAGE_SIZE, but that > was broken by 0eee5ae10256 ("swiotlb: fix slot alignment checks"). > > Since this alignment could be relied upon drivers, reinstate PAGE_SIZE > alignment for swiotlb mappings >= PAGE_SIZE. > > Reported-by: Michael Kelley <mhklinux@outlook.com> > Signed-off-by: Will Deacon <will@kernel.org> > > --- > kernel/dma/swiotlb.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c > index c381a7ed718f..c5851034523f 100644 > --- a/kernel/dma/swiotlb.c > +++ b/kernel/dma/swiotlb.c > @@ -992,6 +992,17 @@ static int swiotlb_search_pool_area(struct device *dev, struct io_tlb_pool *pool > BUG_ON(!nslots); > BUG_ON(area_index >= pool->nareas); > > + /* > + * Historically, swiotlb allocations >= PAGE_SIZE were guaranteed to be > + * page-aligned in the absence of any other alignment requirements. > + * 'alloc_align_mask' was later introduced to specify the alignment > + * explicitly, however this is passed as zero for streaming mappings > + * and so we preserve the old behaviour there in case any drivers are > + * relying on it. > + */ > + if (!alloc_align_mask && !iotlb_align_mask && alloc_size >= PAGE_SIZE) > + alloc_align_mask = PAGE_SIZE - 1; > +
This could be moved up the call chain to swiotlb_tbl_map_single(), but since there is already a plan to modify the call signatures for the next release, let's keep it here.
Reviewed-by: Petr Tesarik <petr.tesarik1@huawei-partners.com>
Petr T
> /* > * Ensure that the allocation is at least slot-aligned and update > * 'iotlb_align_mask' to ignore bits that will be preserved when > @@ -1006,13 +1017,6 @@ static int swiotlb_search_pool_area(struct device *dev, struct io_tlb_pool *pool > */ > stride = get_max_slots(max(alloc_align_mask, iotlb_align_mask)); > > - /* > - * For allocations of PAGE_SIZE or larger only look for page aligned > - * allocations. > - */ > - if (alloc_size >= PAGE_SIZE) > - stride = umax(stride, PAGE_SHIFT - IO_TLB_SHIFT + 1); > - > spin_lock_irqsave(&area->lock, flags); > if (unlikely(nslots > pool->area_nslabs - area->used)) > goto not_found;
| |