Skip to content

Commit 6aefbf1

Browse files
niklas88Vasily Gorbik
authored andcommitted
s390/pci: add s390_iommu_aperture kernel parameter
Some applications map the same memory area for DMA multiple times while also mapping significant amounts of memory. With our current DMA code these applications will run out of DMA addresses after mapping half of the available memory because the number of DMA mappings is constrained by the number of concurrently active DMA addresses we support which in turn is limited by the minimum of hardware constraints and high_memory. Limiting the number of active DMA addresses to high_memory is only a heuristic to save memory used by the iommu_bitmap and DMA page tables however. This was added under the assumption that it rarely makes sense to DMA map more than system memory. To accommodate special applications which insist on double mapping, which works on other platforms, allow specifying a factor of how many times installed memory is available as DMA address space. Use 0 as a special value to apply no constraints beyond what hardware dictates at the expense of significantly more memory use. Reviewed-by: Matthew Rosato <[email protected]> Reviewed-by: Pierre Morel <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 74e74f9 commit 6aefbf1

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4982,6 +4982,18 @@
49824982
an IOTLB flush. Default is lazy flushing before reuse,
49834983
which is faster.
49844984

4985+
s390_iommu_aperture= [KNL,S390]
4986+
Specifies the size of the per device DMA address space
4987+
accessible through the DMA and IOMMU APIs as a decimal
4988+
factor of the size of main memory.
4989+
The default is 1 meaning that one can concurrently use
4990+
as many DMA addresses as physical memory is installed,
4991+
if supported by hardware, and thus map all of memory
4992+
once. With a value of 2 one can map all of memory twice
4993+
and so on. As a special case a factor of 0 imposes no
4994+
restrictions other than those given by hardware at the
4995+
cost of significant additional memory use for tables.
4996+
49854997
sa1100ir [NET]
49864998
See drivers/net/irda/sa1100_ir.c.
49874999

arch/s390/pci/pci_dma.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
static struct kmem_cache *dma_region_table_cache;
1919
static struct kmem_cache *dma_page_table_cache;
2020
static int s390_iommu_strict;
21+
static u64 s390_iommu_aperture;
22+
static u32 s390_iommu_aperture_factor = 1;
2123

2224
static int zpci_refresh_global(struct zpci_dev *zdev)
2325
{
@@ -565,15 +567,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
565567

566568
/*
567569
* Restrict the iommu bitmap size to the minimum of the following:
568-
* - main memory size
570+
* - s390_iommu_aperture which defaults to high_memory
569571
* - 3-level pagetable address limit minus start_dma offset
570572
* - DMA address range allowed by the hardware (clp query pci fn)
571573
*
572574
* Also set zdev->end_dma to the actual end address of the usable
573575
* range, instead of the theoretical maximum as reported by hardware.
576+
*
577+
* This limits the number of concurrently usable DMA mappings since
578+
* for each DMA mapped memory address we need a DMA address including
579+
* extra DMA addresses for multiple mappings of the same memory address.
574580
*/
575581
zdev->start_dma = PAGE_ALIGN(zdev->start_dma);
576-
zdev->iommu_size = min3((u64) high_memory,
582+
zdev->iommu_size = min3(s390_iommu_aperture,
577583
ZPCI_TABLE_SIZE_RT - zdev->start_dma,
578584
zdev->end_dma - zdev->start_dma + 1);
579585
zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
@@ -660,6 +666,12 @@ static int __init dma_alloc_cpu_table_caches(void)
660666

661667
int __init zpci_dma_init(void)
662668
{
669+
s390_iommu_aperture = (u64)high_memory;
670+
if (!s390_iommu_aperture_factor)
671+
s390_iommu_aperture = ULONG_MAX;
672+
else
673+
s390_iommu_aperture *= s390_iommu_aperture_factor;
674+
663675
return dma_alloc_cpu_table_caches();
664676
}
665677

@@ -692,3 +704,12 @@ static int __init s390_iommu_setup(char *str)
692704
}
693705

694706
__setup("s390_iommu=", s390_iommu_setup);
707+
708+
static int __init s390_iommu_aperture_setup(char *str)
709+
{
710+
if (kstrtou32(str, 10, &s390_iommu_aperture_factor))
711+
s390_iommu_aperture_factor = 1;
712+
return 1;
713+
}
714+
715+
__setup("s390_iommu_aperture=", s390_iommu_aperture_setup);

0 commit comments

Comments
 (0)