mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 06:55:13 +08:00
arch: fix has_transparent_hugepage()
I've just discovered that the useful-sounding has_transparent_hugepage() is actually an architecture-dependent minefield: on some arches it only builds if CONFIG_TRANSPARENT_HUGEPAGE=y, on others it's also there when not, but on some of those (arm and arm64) it then gives the wrong answer; and on mips alone it's marked __init, which would crash if called later (but so far it has not been called later). Straighten this out: make it available to all configs, with a sensible default in asm-generic/pgtable.h, removing its definitions from those arches (arc, arm, arm64, sparc, tile) which are served by the default, adding #define has_transparent_hugepage has_transparent_hugepage to those (mips, powerpc, s390, x86) which need to override the default at runtime, and removing the __init from mips (but maybe that kind of code should be avoided after init: set a static variable the first time it's called). Signed-off-by: Hugh Dickins <hughd@google.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Andres Lagar-Cavilla <andreslc@google.com> Cc: Yang Shi <yang.shi@linaro.org> Cc: Ning Qu <quning@gmail.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Vineet Gupta <vgupta@synopsys.com> [arch/arc] Acked-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> [arch/s390] Acked-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1d069b7dd5
commit
fd8cfd3000
@ -61,8 +61,6 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
|||||||
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
|
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||||
pmd_t *pmd);
|
pmd_t *pmd);
|
||||||
|
|
||||||
#define has_transparent_hugepage() 1
|
|
||||||
|
|
||||||
/* Generic variants assume pgtable_t is struct page *, hence need for these */
|
/* Generic variants assume pgtable_t is struct page *, hence need for these */
|
||||||
#define __HAVE_ARCH_PGTABLE_DEPOSIT
|
#define __HAVE_ARCH_PGTABLE_DEPOSIT
|
||||||
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
|
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
|
||||||
|
@ -281,11 +281,6 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
|||||||
flush_pmd_entry(pmdp);
|
flush_pmd_entry(pmdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int has_transparent_hugepage(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_PGTABLE_3LEVEL_H */
|
#endif /* _ASM_PGTABLE_3LEVEL_H */
|
||||||
|
@ -314,11 +314,6 @@ static inline int pmd_protnone(pmd_t pmd)
|
|||||||
|
|
||||||
#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
|
#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
|
||||||
|
|
||||||
static inline int has_transparent_hugepage(void)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __pgprot_modify(prot,mask,bits) \
|
#define __pgprot_modify(prot,mask,bits) \
|
||||||
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
|
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
|
||||||
|
|
||||||
|
@ -468,6 +468,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
|
|||||||
|
|
||||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
|
|
||||||
|
#define has_transparent_hugepage has_transparent_hugepage
|
||||||
extern int has_transparent_hugepage(void);
|
extern int has_transparent_hugepage(void);
|
||||||
|
|
||||||
static inline int pmd_trans_huge(pmd_t pmd)
|
static inline int pmd_trans_huge(pmd_t pmd)
|
||||||
|
@ -400,19 +400,20 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
|
|||||||
|
|
||||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
|
|
||||||
int __init has_transparent_hugepage(void)
|
int has_transparent_hugepage(void)
|
||||||
{
|
{
|
||||||
unsigned int mask;
|
static unsigned int mask = -1;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
local_irq_save(flags);
|
if (mask == -1) { /* first call comes during __init */
|
||||||
write_c0_pagemask(PM_HUGE_MASK);
|
unsigned long flags;
|
||||||
back_to_back_c0_hazard();
|
|
||||||
mask = read_c0_pagemask();
|
|
||||||
write_c0_pagemask(PM_DEFAULT_MASK);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
write_c0_pagemask(PM_HUGE_MASK);
|
||||||
|
back_to_back_c0_hazard();
|
||||||
|
mask = read_c0_pagemask();
|
||||||
|
write_c0_pagemask(PM_DEFAULT_MASK);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
return mask == PM_HUGE_MASK;
|
return mask == PM_HUGE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +219,7 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
|||||||
pmd_t *pmdp, pmd_t pmd);
|
pmd_t *pmdp, pmd_t pmd);
|
||||||
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
|
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||||
pmd_t *pmd);
|
pmd_t *pmd);
|
||||||
|
#define has_transparent_hugepage has_transparent_hugepage
|
||||||
extern int has_transparent_hugepage(void);
|
extern int has_transparent_hugepage(void);
|
||||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
|||||||
struct page **pages, int *nr);
|
struct page **pages, int *nr);
|
||||||
#ifndef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifndef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
#define pmd_large(pmd) 0
|
#define pmd_large(pmd) 0
|
||||||
#define has_transparent_hugepage() 0
|
|
||||||
#endif
|
#endif
|
||||||
pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
|
pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
|
||||||
bool *is_thp, unsigned *shift);
|
bool *is_thp, unsigned *shift);
|
||||||
|
@ -1223,6 +1223,7 @@ static inline int pmd_trans_huge(pmd_t pmd)
|
|||||||
return pmd_val(pmd) & _SEGMENT_ENTRY_LARGE;
|
return pmd_val(pmd) & _SEGMENT_ENTRY_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define has_transparent_hugepage has_transparent_hugepage
|
||||||
static inline int has_transparent_hugepage(void)
|
static inline int has_transparent_hugepage(void)
|
||||||
{
|
{
|
||||||
return MACHINE_HAS_HPAGE ? 1 : 0;
|
return MACHINE_HAS_HPAGE ? 1 : 0;
|
||||||
|
@ -681,8 +681,6 @@ static inline unsigned long pmd_trans_huge(pmd_t pmd)
|
|||||||
return pte_val(pte) & _PAGE_PMD_HUGE;
|
return pte_val(pte) & _PAGE_PMD_HUGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define has_transparent_hugepage() 1
|
|
||||||
|
|
||||||
static inline pmd_t pmd_mkold(pmd_t pmd)
|
static inline pmd_t pmd_mkold(pmd_t pmd)
|
||||||
{
|
{
|
||||||
pte_t pte = __pte(pmd_val(pmd));
|
pte_t pte = __pte(pmd_val(pmd));
|
||||||
|
@ -487,7 +487,6 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
#define has_transparent_hugepage() 1
|
|
||||||
#define pmd_trans_huge pmd_huge_page
|
#define pmd_trans_huge pmd_huge_page
|
||||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ static inline int pmd_trans_huge(pmd_t pmd)
|
|||||||
return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
|
return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define has_transparent_hugepage has_transparent_hugepage
|
||||||
static inline int has_transparent_hugepage(void)
|
static inline int has_transparent_hugepage(void)
|
||||||
{
|
{
|
||||||
return boot_cpu_has(X86_FEATURE_PSE);
|
return boot_cpu_has(X86_FEATURE_PSE);
|
||||||
|
@ -806,4 +806,12 @@ static inline int pmd_clear_huge(pmd_t *pmd)
|
|||||||
#define io_remap_pfn_range remap_pfn_range
|
#define io_remap_pfn_range remap_pfn_range
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef has_transparent_hugepage
|
||||||
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
|
#define has_transparent_hugepage() 1
|
||||||
|
#else
|
||||||
|
#define has_transparent_hugepage() 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_GENERIC_PGTABLE_H */
|
#endif /* _ASM_GENERIC_PGTABLE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user