From: Matt Porter This fixes a memory leak when freeing pgds on PPC44x. --- 25-akpm/arch/ppc/kernel/misc.S | 7 +++++-- 25-akpm/arch/ppc/mm/pgtable.c | 4 ++-- 25-akpm/include/asm-ppc/page.h | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff -puN arch/ppc/kernel/misc.S~ppc64-memleak-fix arch/ppc/kernel/misc.S --- 25/arch/ppc/kernel/misc.S~ppc64-memleak-fix Tue Apr 6 15:55:37 2004 +++ 25-akpm/arch/ppc/kernel/misc.S Tue Apr 6 15:55:37 2004 @@ -738,12 +738,15 @@ _GLOBAL(__flush_dcache_icache_phys) blr /* - * Clear a page using the dcbz instruction, which doesn't cause any + * Clear pages using the dcbz instruction, which doesn't cause any * memory traffic (except to write out any cache lines which get * displaced). This only works on cacheable memory. + * + * void clear_pages(void *page, int order) ; */ -_GLOBAL(clear_page) +_GLOBAL(clear_pages) li r0,4096/L1_CACHE_LINE_SIZE + slw r0,r0,r4 mtctr r0 #ifdef CONFIG_8xx li r4, 0 diff -puN arch/ppc/mm/pgtable.c~ppc64-memleak-fix arch/ppc/mm/pgtable.c --- 25/arch/ppc/mm/pgtable.c~ppc64-memleak-fix Tue Apr 6 15:55:37 2004 +++ 25-akpm/arch/ppc/mm/pgtable.c Tue Apr 6 15:55:37 2004 @@ -71,13 +71,13 @@ pgd_t *pgd_alloc(struct mm_struct *mm) pgd_t *ret; if ((ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER)) != NULL) - clear_page(ret); + clear_pages(ret, PGDIR_ORDER); return ret; } void pgd_free(pgd_t *pgd) { - free_page((unsigned long)pgd); + free_pages((unsigned long)pgd, PGDIR_ORDER); } pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) diff -puN include/asm-ppc/page.h~ppc64-memleak-fix include/asm-ppc/page.h --- 25/include/asm-ppc/page.h~ppc64-memleak-fix Tue Apr 6 15:55:37 2004 +++ 25-akpm/include/asm-ppc/page.h Tue Apr 6 15:55:37 2004 @@ -84,7 +84,8 @@ typedef unsigned long pgprot_t; #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) struct page; -extern void clear_page(void *page); +extern void clear_pages(void *page, int order); +static inline void clear_page(void *page) { clear_pages(page, 0); } extern void copy_page(void *to, void *from); extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); extern void copy_user_page(void *to, void *from, unsigned long vaddr, _