Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d4fbba9 authored by Liam Mark's avatar Liam Mark Committed by Patrick Daly
Browse files

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: default avatarLiam Mark <lmark@codeaurora.org>
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent e7ebb936
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -1901,7 +1901,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;

@@ -1916,7 +1920,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:
@@ -1930,7 +1934,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);
}

+7 −3
Original line number Diff line number Diff line
/* 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
@@ -696,7 +696,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;

@@ -780,7 +784,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);