aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/pgalloc.h
diff options
context:
space:
mode:
authorYaliang Wang <Yaliang.Wang@windriver.com>2022-03-10 19:31:16 +0800
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>2022-03-14 15:05:18 +0100
commit2bc5bab9a763d520937e4f3fe8df51c6a1eceb97 (patch)
treeecc5d717f9363a82689ba44a0f09e0dc9c486694 /arch/mips/include/asm/pgalloc.h
parentMIPS: RB532: fix return value of __setup handler (diff)
downloadlinux-dev-2bc5bab9a763d520937e4f3fe8df51c6a1eceb97.tar.xz
linux-dev-2bc5bab9a763d520937e4f3fe8df51c6a1eceb97.zip
MIPS: pgalloc: fix memory leak caused by pgd_free()
pgd page is freed by generic implementation pgd_free() since commit f9cb654cb550 ("asm-generic: pgalloc: provide generic pgd_free()"), however, there are scenarios that the system uses more than one page as the pgd table, in such cases the generic implementation pgd_free() won't be applicable anymore. For example, when PAGE_SIZE_4KB is enabled and MIPS_VA_BITS_48 is not enabled in a 64bit system, the macro "PGD_ORDER" will be set as "1", which will cause allocating two pages as the pgd table. Well, at the same time, the generic implementation pgd_free() just free one pgd page, which will result in the memory leak. The memory leak can be easily detected by executing shell command: "while true; do ls > /dev/null; grep MemFree /proc/meminfo; done" Fixes: f9cb654cb550 ("asm-generic: pgalloc: provide generic pgd_free()") Signed-off-by: Yaliang Wang <Yaliang.Wang@windriver.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Diffstat (limited to 'arch/mips/include/asm/pgalloc.h')
-rw-r--r--arch/mips/include/asm/pgalloc.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
index c7925d0e9874..867e9c3db76e 100644
--- a/arch/mips/include/asm/pgalloc.h
+++ b/arch/mips/include/asm/pgalloc.h
@@ -15,6 +15,7 @@
#define __HAVE_ARCH_PMD_ALLOC_ONE
#define __HAVE_ARCH_PUD_ALLOC_ONE
+#define __HAVE_ARCH_PGD_FREE
#include <asm-generic/pgalloc.h>
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
@@ -48,6 +49,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
extern void pgd_init(unsigned long page);
extern pgd_t *pgd_alloc(struct mm_struct *mm);
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
#define __pte_free_tlb(tlb,pte,address) \
do { \
pgtable_pte_page_dtor(pte); \