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

Commit 2df40789 authored by Amir Levy's avatar Amir Levy
Browse files

msm: ipa3: fix memory leak in __ipa_reap_sys_rt_tbls



__ipa_reap_sys_rt_tbls always deletes a routing table from
head_rt_tbl_list, but it releases the routing table memory only if
it matches the rule type (hashabale\ non hashable). This function was
called twice each time with a different rule type, therefore if a DMA
memory was allocated for the non hashable type, calling the function for
the hashable type first will delete the routing table entry and the
next call will not release the memory.
This change releases the memory for both rule types and only then deletes
the routing table entry.

Change-Id: Id7f655b324a20c9681a3c48877d825929bc205aa
Signed-off-by: default avatarAmir Levy <alevy@codeaurora.org>
parent ac6766f8
Loading
Loading
Loading
Loading
+28 −23
Original line number Diff line number Diff line
@@ -260,40 +260,46 @@ err:
	return -EPERM;
}

static void __ipa_reap_sys_rt_tbls(enum ipa_ip_type ip,
	enum ipa_rule_type rlt)
static void __ipa_reap_sys_rt_tbls(enum ipa_ip_type ip)
{
	struct ipa3_rt_tbl *tbl;
	struct ipa3_rt_tbl *next;
	struct ipa3_rt_tbl_set *set;
	int i;

	set = &ipa3_ctx->rt_tbl_set[ip];
	list_for_each_entry(tbl, &set->head_rt_tbl_list, link) {
		if (tbl->prev_mem[rlt].phys_base) {
			IPADBG("reaping sys rt tbl name=%s ip=%d rlt=%d\n",
				tbl->name, ip, rlt);
		for (i = 0; i < IPA_RULE_TYPE_MAX; i++) {
			if (tbl->prev_mem[i].phys_base) {
				IPADBG(
				"reaping sys rt tbl name=%s ip=%d rlt=%d\n",
				tbl->name, ip, i);
				dma_free_coherent(ipa3_ctx->pdev,
				tbl->prev_mem[rlt].size,
				tbl->prev_mem[rlt].base,
				tbl->prev_mem[rlt].phys_base);
			memset(&tbl->prev_mem[rlt], 0,
				sizeof(tbl->prev_mem[rlt]));
					tbl->prev_mem[i].size,
					tbl->prev_mem[i].base,
					tbl->prev_mem[i].phys_base);
				memset(&tbl->prev_mem[i], 0,
					sizeof(tbl->prev_mem[i]));
			}
		}
	}

	set = &ipa3_ctx->reap_rt_tbl_set[ip];
	list_for_each_entry_safe(tbl, next, &set->head_rt_tbl_list, link) {
		list_del(&tbl->link);
		WARN_ON(tbl->prev_mem[rlt].phys_base != 0);
		if (tbl->curr_mem[rlt].phys_base) {
			IPADBG("reaping sys rt tbl name=%s ip=%d rlt=%d\n",
				tbl->name, ip, rlt);
		for (i = 0; i < IPA_RULE_TYPE_MAX; i++) {
			WARN_ON(tbl->prev_mem[i].phys_base != 0);
			if (tbl->curr_mem[i].phys_base) {
				IPADBG(
				"reaping sys rt tbl name=%s ip=%d rlt=%d\n",
				tbl->name, ip, i);
				dma_free_coherent(ipa3_ctx->pdev,
				tbl->curr_mem[rlt].size,
				tbl->curr_mem[rlt].base,
				tbl->curr_mem[rlt].phys_base);
			kmem_cache_free(ipa3_ctx->rt_tbl_cache, tbl);
					tbl->curr_mem[i].size,
					tbl->curr_mem[i].base,
					tbl->curr_mem[i].phys_base);
			}
		}
		list_del(&tbl->link);
		kmem_cache_free(ipa3_ctx->rt_tbl_cache, tbl);
	}
}

@@ -780,8 +786,7 @@ int __ipa_commit_rt_v3(enum ipa_ip_type ip)
			nhash_bdy.phys_base, nhash_bdy.size);
	}

	__ipa_reap_sys_rt_tbls(ip, IPA_RULE_HASHABLE);
	__ipa_reap_sys_rt_tbls(ip, IPA_RULE_NON_HASHABLE);
	__ipa_reap_sys_rt_tbls(ip);

fail_size_valid:
	dma_free_coherent(ipa3_ctx->pdev, hash_hdr.size,