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

Commit 0186f47e authored by Kumar Gala's avatar Kumar Gala Committed by Paul Mackerras
Browse files

powerpc: Use RCU based pte freeing mechanism for all powerpc



Refactor the RCU based pte free code that was used on ppc64 to be used
on all powerpc.

Additionally refactor pte_free() & pte_free_kernel() into common code
between ppc32 & ppc64.

Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent df3b8611
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@

#include <linux/threads.h>

#define PTE_NONCACHE_NUM	0  /* dummy for now to share code w/ppc64 */

extern void __bad_pte(pmd_t *pmd);

extern pgd_t *pgd_alloc(struct mm_struct *mm);
@@ -33,10 +35,13 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);

extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
extern void pte_free(struct mm_struct *mm, pgtable_t pte);

#define __pte_free_tlb(tlb, pte)	pte_free((tlb)->mm, (pte))
static inline void pgtable_free(pgtable_free_t pgf)
{
	void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);

	free_page((unsigned long)p);
}

#define check_pgt_cache()	do { } while (0)

+0 −34
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
@@ -108,31 +107,6 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
	return page;
}

static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
	free_page((unsigned long)pte);
}

static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
{
	pgtable_page_dtor(ptepage);
	__free_page(ptepage);
}

#define PGF_CACHENUM_MASK	0x7

typedef struct pgtable_free {
	unsigned long val;
} pgtable_free_t;

static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
						unsigned long mask)
{
	BUG_ON(cachenum > PGF_CACHENUM_MASK);

	return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
}

static inline void pgtable_free(pgtable_free_t pgf)
{
	void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
@@ -144,14 +118,6 @@ static inline void pgtable_free(pgtable_free_t pgf)
		kmem_cache_free(pgtable_cache[cachenum], p);
}

extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);

#define __pte_free_tlb(tlb,ptepage)	\
do { \
	pgtable_page_dtor(ptepage); \
	pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
		PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
} while (0)
#define __pmd_free_tlb(tlb, pmd) 	\
	pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
		PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
+41 −0
Original line number Diff line number Diff line
@@ -2,11 +2,52 @@
#define _ASM_POWERPC_PGALLOC_H
#ifdef __KERNEL__

#include <linux/mm.h>

static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
	free_page((unsigned long)pte);
}

static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
{
	pgtable_page_dtor(ptepage);
	__free_page(ptepage);
}

typedef struct pgtable_free {
	unsigned long val;
} pgtable_free_t;

#define PGF_CACHENUM_MASK	0x7

static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
						unsigned long mask)
{
	BUG_ON(cachenum > PGF_CACHENUM_MASK);

	return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
}

#ifdef CONFIG_PPC64
#include <asm/pgalloc-64.h>
#else
#include <asm/pgalloc-32.h>
#endif

extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);

#ifdef CONFIG_SMP
#define __pte_free_tlb(tlb,ptepage)	\
do { \
	pgtable_page_dtor(ptepage); \
	pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
		PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
} while (0)
#else
#define __pte_free_tlb(tlb, pte)	pte_free((tlb)->mm, (pte))
#endif


#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGALLOC_H */
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ ifeq ($(CONFIG_PPC64),y)
EXTRA_CFLAGS	+= -mno-minimal-toc
endif

obj-y				:= fault.o mem.o \
obj-y				:= fault.o mem.o pgtable.o \
				   init_$(CONFIG_WORD_SIZE).o \
				   pgtable_$(CONFIG_WORD_SIZE).o \
				   mmu_context_$(CONFIG_WORD_SIZE).o
+0 −30
Original line number Diff line number Diff line
@@ -35,36 +35,6 @@ mmu_hash_lock:
	.space	4
#endif /* CONFIG_SMP */

/*
 * Sync CPUs with hash_page taking & releasing the hash
 * table lock
 */
#ifdef CONFIG_SMP
	.text
_GLOBAL(hash_page_sync)
	mfmsr   r10
	rlwinm  r0,r10,0,17,15          /* clear bit 16 (MSR_EE) */
	mtmsr   r0
	lis	r8,mmu_hash_lock@h
	ori	r8,r8,mmu_hash_lock@l
	lis	r0,0x0fff
	b	10f
11:	lwz	r6,0(r8)
	cmpwi	0,r6,0
	bne	11b
10:	lwarx	r6,0,r8
	cmpwi	0,r6,0
	bne-	11b
	stwcx.	r0,0,r8
	bne-	10b
	isync
	eieio
	li	r0,0
	stw	r0,0(r8)
	mtmsr	r10
	blr
#endif /* CONFIG_SMP */

/*
 * Load a PTE into the hash table, if possible.
 * The address is in r4, and r3 contains an access flag:
Loading