summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Mark <lmark@codeaurora.org>2017-02-08 10:30:49 -0800
committerLiam Mark <lmark@codeaurora.org>2017-02-09 09:27:24 -0800
commit335db258eb7c69f9229b48557b3f629f63dfb8de (patch)
tree0a04ae75846f2d9de8230385a5ecba3e5d212314
parent20e1ed9259bf1c7c40b76b13d74d476608cc1d49 (diff)
iommu: dma-mapping: alloc bitmap while fragmented
The bitmap size can be on the order of several pages. In a fragmented system it may not be possible to allocate the memory as contiguous. Handle fragmentation by falling back to vzalloc. Change-Id: Ie93c92705eed1bbe966d5f121b3393d8909982a6 Signed-off-by: Liam Mark <lmark@codeaurora.org>
-rw-r--r--arch/arm64/mm/dma-mapping.c10
-rw-r--r--drivers/iommu/dma-mapping-fast.c10
2 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 1ad799523a54..685c4577e65a 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -1923,7 +1923,11 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
if (!mapping)
goto err;
- mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL | __GFP_NOWARN |
+ __GFP_NORETRY);
+ if (!mapping->bitmap)
+ mapping->bitmap = vzalloc(bitmap_size);
+
if (!mapping->bitmap)
goto err2;
@@ -1938,7 +1942,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
kref_init(&mapping->kref);
return mapping;
err3:
- kfree(mapping->bitmap);
+ kvfree(mapping->bitmap);
err2:
kfree(mapping);
err:
@@ -1952,7 +1956,7 @@ static void release_iommu_mapping(struct kref *kref)
container_of(kref, struct dma_iommu_mapping, kref);
iommu_domain_free(mapping->domain);
- kfree(mapping->bitmap);
+ kvfree(mapping->bitmap);
kfree(mapping);
}
diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c
index 004f34ecbff8..5d4b9174db8d 100644
--- a/drivers/iommu/dma-mapping-fast.c
+++ b/drivers/iommu/dma-mapping-fast.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -695,7 +695,11 @@ static struct dma_fast_smmu_mapping *__fast_smmu_create_mapping_sized(
fast->num_4k_pages = size >> FAST_PAGE_SHIFT;
fast->bitmap_size = BITS_TO_LONGS(fast->num_4k_pages) * sizeof(long);
- fast->bitmap = kzalloc(fast->bitmap_size, GFP_KERNEL);
+ fast->bitmap = kzalloc(fast->bitmap_size, GFP_KERNEL | __GFP_NOWARN |
+ __GFP_NORETRY);
+ if (!fast->bitmap)
+ fast->bitmap = vzalloc(fast->bitmap_size);
+
if (!fast->bitmap)
goto err2;
@@ -779,7 +783,7 @@ void fast_smmu_detach_device(struct device *dev,
dev->archdata.mapping = NULL;
set_dma_ops(dev, NULL);
- kfree(mapping->fast->bitmap);
+ kvfree(mapping->fast->bitmap);
kfree(mapping->fast);
}
EXPORT_SYMBOL(fast_smmu_detach_device);