Skip to content

Commit ad96ce3

Browse files
Petr TesarikChristoph Hellwig
authored andcommitted
swiotlb: determine potential physical address limit
The value returned by default_swiotlb_limit() should be constant, because it is used to decide whether DMA can be used. To allow allocating memory pools on the fly, use the maximum possible physical address rather than the highest address used by the default pool. For swiotlb_init_remap(), this is either an arch-specific limit used by memblock_alloc_low(), or the highest directly mapped physical address if the initialization flags include SWIOTLB_ANY. For swiotlb_init_late(), the highest address is determined by the GFP flags. Signed-off-by: Petr Tesarik <petr.tesarik.ext@huawei.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 79636ca commit ad96ce3

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

include/linux/swiotlb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct io_tlb_pool {
109109
* @force_bounce: %true if swiotlb bouncing is forced
110110
* @for_alloc: %true if the pool is used for memory allocation
111111
* @can_grow: %true if more pools can be allocated dynamically.
112+
* @phys_limit: Maximum allowed physical address.
112113
* @total_used: The total number of slots in the pool that are currently used
113114
* across all areas. Used only for calculating used_hiwater in
114115
* debugfs.
@@ -123,6 +124,7 @@ struct io_tlb_mem {
123124
bool for_alloc;
124125
#ifdef CONFIG_SWIOTLB_DYNAMIC
125126
bool can_grow;
127+
u64 phys_limit;
126128
#endif
127129
#ifdef CONFIG_DEBUG_FS
128130
atomic_long_t total_used;

kernel/dma/swiotlb.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
334334
#ifdef CONFIG_SWIOTLB_DYNAMIC
335335
if (!remap)
336336
io_tlb_default_mem.can_grow = true;
337+
if (flags & SWIOTLB_ANY)
338+
io_tlb_default_mem.phys_limit = virt_to_phys(high_memory - 1);
339+
else
340+
io_tlb_default_mem.phys_limit = ARCH_LOW_ADDRESS_LIMIT;
337341
#endif
338342

339343
if (!default_nareas)
@@ -409,6 +413,12 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
409413
#ifdef CONFIG_SWIOTLB_DYNAMIC
410414
if (!remap)
411415
io_tlb_default_mem.can_grow = true;
416+
if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp_mask & __GFP_DMA))
417+
io_tlb_default_mem.phys_limit = DMA_BIT_MASK(zone_dma_bits);
418+
else if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp_mask & __GFP_DMA32))
419+
io_tlb_default_mem.phys_limit = DMA_BIT_MASK(32);
420+
else
421+
io_tlb_default_mem.phys_limit = virt_to_phys(high_memory - 1);
412422
#endif
413423

414424
if (!default_nareas)
@@ -1397,7 +1407,11 @@ phys_addr_t default_swiotlb_base(void)
13971407
*/
13981408
phys_addr_t default_swiotlb_limit(void)
13991409
{
1410+
#ifdef CONFIG_SWIOTLB_DYNAMIC
1411+
return io_tlb_default_mem.phys_limit;
1412+
#else
14001413
return io_tlb_default_mem.defpool.end - 1;
1414+
#endif
14011415
}
14021416

14031417
#ifdef CONFIG_DEBUG_FS

0 commit comments

Comments
 (0)