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

Commit dd2bb392 authored by Qingqing Zhou's avatar Qingqing Zhou
Browse files

arm: dma-mapping: fix memory leak about dma iommu mapping



When doing multiple attach/detach tests in iommu-debug,
arch_setup_dma_ops/arch_teardown_dma_ops will be executed multiple
times, the created mapping and its bitmaps by arch_setup_dma_ops
are not freed by arch_teardown_dma_ops because refcount of
mapping->kref is 1 not 0, so memory leak happens, in iommu-debug cases,
each bitmap is requested to allocate PAGE_SIZE with kmalloc, the memory
of slub named kmalloc-4096 is observed to become bigger and bigger, then
will result in OOM easily because of limited lowmem on 32 bit system.

The reason is arch_setup_dma_ops has one needless kref_get operation:
    arch_setup_dma_ops -> kref_init(&mapping->kref)
                          && kref_get(&mapping->kref).
    arch_teardown_dma_ops -> kref_put(&mapping->kref).

Change-Id: I9823ff0ccd5b752774f843592d788e37199166c4
Signed-off-by: default avatarQingqing Zhou <qqzhou@codeaurora.org>
parent 74879d9a
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -2696,7 +2696,6 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
		return false;
	}

	kref_get(&mapping->kref);
	to_dma_iommu_mapping(dev) = mapping;

	return true;
@@ -2711,12 +2710,13 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
	if (!mapping)
		return;

	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
			&s1_bypass);

	kref_put(&mapping->kref, arm_iommu_dma_release_mapping);
	to_dma_iommu_mapping(dev) = NULL;

	/* Let arch_setup_dma_ops() start again from scratch upon re-probe */
	iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS,
			&s1_bypass);
	if (!s1_bypass)
		set_dma_ops(dev, NULL);