forked from Minki/linux
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: - a few hot fixes - ocfs2 updates - almost all of -mm (slab-generic, slab, slub, kmemleak, kasan, cleanups, debug, pagecache, memcg, gup, pagemap, memory-hotplug, sparsemem, vmalloc, initialization, z3fold, compaction, mempolicy, oom-kill, hugetlb, migration, thp, mmap, madvise, shmem, zswap, zsmalloc) * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (132 commits) mm/zsmalloc.c: fix a -Wunused-function warning zswap: do not map same object twice zswap: use movable memory if zpool support allocate movable memory zpool: add malloc_support_movable to zpool_driver shmem: fix obsolete comment in shmem_getpage_gfp() mm/madvise: reduce code duplication in error handling paths mm: mmap: increase sockets maximum memory size pgoff for 32bits mm/mmap.c: refine find_vma_prev() with rb_last() riscv: make mmap allocation top-down by default mips: use generic mmap top-down layout and brk randomization mips: replace arch specific way to determine 32bit task with generic version mips: adjust brk randomization offset to fit generic version mips: use STACK_TOP when computing mmap base address mips: properly account for stack randomization and stack guard gap arm: use generic mmap top-down layout and brk randomization arm: use STACK_TOP when computing mmap base address arm: properly account for stack randomization and stack guard gap arm64, mm: make randomization selected by generic topdown mmap layout arm64, mm: move generic mmap layout functions to mm arm64: consider stack randomization for mmap base only when necessary ...
This commit is contained in:
commit
9c9fa97a8e
@ -429,10 +429,15 @@ KernelVersion: 2.6.22
|
||||
Contact: Pekka Enberg <penberg@cs.helsinki.fi>,
|
||||
Christoph Lameter <cl@linux-foundation.org>
|
||||
Description:
|
||||
The shrink file is written when memory should be reclaimed from
|
||||
a cache. Empty partial slabs are freed and the partial list is
|
||||
sorted so the slabs with the fewest available objects are used
|
||||
first.
|
||||
The shrink file is used to reclaim unused slab cache
|
||||
memory from a cache. Empty per-cpu or partial slabs
|
||||
are freed and the partial list is sorted so the slabs
|
||||
with the fewest available objects are used first.
|
||||
It only accepts a value of "1" on write for shrinking
|
||||
the cache. Other input values are considered invalid.
|
||||
Shrinking slab caches might be expensive and can
|
||||
adversely impact other running applications. So it
|
||||
should be used with care.
|
||||
|
||||
What: /sys/kernel/slab/cache/slab_size
|
||||
Date: May 2007
|
||||
|
@ -85,8 +85,10 @@ Brief summary of control files.
|
||||
memory.oom_control set/show oom controls.
|
||||
memory.numa_stat show the number of memory usage per numa
|
||||
node
|
||||
|
||||
memory.kmem.limit_in_bytes set/show hard limit for kernel memory
|
||||
This knob is deprecated and shouldn't be
|
||||
used. It is planned that this be removed in
|
||||
the foreseeable future.
|
||||
memory.kmem.usage_in_bytes show current kernel memory allocation
|
||||
memory.kmem.failcnt show the number of kernel memory usage
|
||||
hits limits
|
||||
|
@ -809,6 +809,8 @@
|
||||
enables the feature at boot time. By default, it is
|
||||
disabled and the system will work mostly the same as a
|
||||
kernel built without CONFIG_DEBUG_PAGEALLOC.
|
||||
Note: to get most of debug_pagealloc error reports, it's
|
||||
useful to also enable the page_owner functionality.
|
||||
on: enable the feature
|
||||
|
||||
debugpat [X86] Enable PAT debugging
|
||||
|
11
arch/Kconfig
11
arch/Kconfig
@ -706,6 +706,17 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
|
||||
and vice-versa 32-bit applications to call 64-bit mmap().
|
||||
Required for applications doing different bitness syscalls.
|
||||
|
||||
# This allows to use a set of generic functions to determine mmap base
|
||||
# address by giving priority to top-down scheme only if the process
|
||||
# is not in legacy mode (compat task, unlimited stack size or
|
||||
# sysctl_legacy_va_layout).
|
||||
# Architecture that selects this option can provide its own version of:
|
||||
# - STACK_RND_MASK
|
||||
config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
||||
bool
|
||||
depends on MMU
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
|
||||
config HAVE_COPY_THREAD_TLS
|
||||
bool
|
||||
help
|
||||
|
@ -53,6 +53,4 @@ pmd_free(struct mm_struct *mm, pmd_t *pmd)
|
||||
free_page((unsigned long)pmd);
|
||||
}
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif /* _ALPHA_PGALLOC_H */
|
||||
|
@ -359,11 +359,6 @@ extern void paging_init(void);
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT. */
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
|
||||
|
@ -129,7 +129,6 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptep)
|
||||
|
||||
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
#define pmd_pgtable(pmd) ((pgtable_t) pmd_page_vaddr(pmd))
|
||||
|
||||
#endif /* _ASM_ARC_PGALLOC_H */
|
||||
|
@ -395,11 +395,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
/* to cope with aliasing VIPT cache */
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@ config ARM
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_CMPXCHG_LOCKREF
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
|
||||
select BUILDTIME_EXTABLE_SORT if MMU
|
||||
|
@ -15,8 +15,6 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
|
||||
|
@ -70,11 +70,6 @@ typedef pte_t *pte_addr_t;
|
||||
*/
|
||||
extern unsigned int kobjsize(const void *objp);
|
||||
|
||||
/*
|
||||
* No page table caches to initialise.
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/*
|
||||
* All 32bit addresses are effectively valid for vmalloc...
|
||||
* Sort of meaningless for non-VM targets.
|
||||
|
@ -368,8 +368,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
|
||||
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
@ -140,8 +140,6 @@ static inline void prefetchw(const void *ptr)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define HAVE_ARCH_PICK_MMAP_LAYOUT
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ARM_PROCESSOR_H */
|
||||
|
@ -319,11 +319,6 @@ unsigned long get_wchan(struct task_struct *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||
{
|
||||
return randomize_page(mm->brk, 0x02000000);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#ifdef CONFIG_KUSER_HELPERS
|
||||
/*
|
||||
|
@ -204,18 +204,17 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
|
||||
* coherent with the kernels mapping.
|
||||
*/
|
||||
if (!PageHighMem(page)) {
|
||||
size_t page_size = PAGE_SIZE << compound_order(page);
|
||||
__cpuc_flush_dcache_area(page_address(page), page_size);
|
||||
__cpuc_flush_dcache_area(page_address(page), page_size(page));
|
||||
} else {
|
||||
unsigned long i;
|
||||
if (cache_is_vipt_nonaliasing()) {
|
||||
for (i = 0; i < (1 << compound_order(page)); i++) {
|
||||
for (i = 0; i < compound_nr(page); i++) {
|
||||
void *addr = kmap_atomic(page + i);
|
||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
||||
kunmap_atomic(addr);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (1 << compound_order(page)); i++) {
|
||||
for (i = 0; i < compound_nr(page); i++) {
|
||||
void *addr = kmap_high_get(page + i);
|
||||
if (addr) {
|
||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
||||
|
@ -17,33 +17,6 @@
|
||||
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
|
||||
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
|
||||
|
||||
/* gap between mmap and stack */
|
||||
#define MIN_GAP (128*1024*1024UL)
|
||||
#define MAX_GAP ((TASK_SIZE)/6*5)
|
||||
|
||||
static int mmap_is_legacy(struct rlimit *rlim_stack)
|
||||
{
|
||||
if (current->personality & ADDR_COMPAT_LAYOUT)
|
||||
return 1;
|
||||
|
||||
if (rlim_stack->rlim_cur == RLIM_INFINITY)
|
||||
return 1;
|
||||
|
||||
return sysctl_legacy_va_layout;
|
||||
}
|
||||
|
||||
static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long gap = rlim_stack->rlim_cur;
|
||||
|
||||
if (gap < MIN_GAP)
|
||||
gap = MIN_GAP;
|
||||
else if (gap > MAX_GAP)
|
||||
gap = MAX_GAP;
|
||||
|
||||
return PAGE_ALIGN(TASK_SIZE - gap - rnd);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to ensure that shared mappings are correctly aligned to
|
||||
* avoid aliasing issues with VIPT caches. We need to ensure that
|
||||
@ -171,31 +144,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
||||
return addr;
|
||||
}
|
||||
|
||||
unsigned long arch_mmap_rnd(void)
|
||||
{
|
||||
unsigned long rnd;
|
||||
|
||||
rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
|
||||
|
||||
return rnd << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long random_factor = 0UL;
|
||||
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
random_factor = arch_mmap_rnd();
|
||||
|
||||
if (mmap_is_legacy(rlim_stack)) {
|
||||
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
|
||||
mm->get_unmapped_area = arch_get_unmapped_area;
|
||||
} else {
|
||||
mm->mmap_base = mmap_base(random_factor, rlim_stack);
|
||||
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* You really shouldn't be using read() or write() on /dev/mem. This
|
||||
* might go away in the future.
|
||||
|
@ -15,7 +15,6 @@ config ARM64
|
||||
select ARCH_HAS_DMA_COHERENT_TO_PFN
|
||||
select ARCH_HAS_DMA_PREP_COHERENT
|
||||
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
@ -71,6 +70,7 @@ config ARM64
|
||||
select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
|
||||
select ARCH_HAS_UBSAN_SANITIZE_ALL
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
#include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS > 2
|
||||
|
@ -861,8 +861,6 @@ extern int kern_addr_valid(unsigned long addr);
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
static inline void pgtable_cache_init(void) { }
|
||||
|
||||
/*
|
||||
* On AArch64, the cache coherency is handled via the set_pte_at() function.
|
||||
*/
|
||||
|
@ -280,8 +280,6 @@ static inline void spin_lock_prefetch(const void *ptr)
|
||||
"nop") : : "p" (ptr));
|
||||
}
|
||||
|
||||
#define HAVE_ARCH_PICK_MMAP_LAYOUT
|
||||
|
||||
extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */
|
||||
extern void __init minsigstksz_setup(void);
|
||||
|
||||
|
@ -557,14 +557,6 @@ unsigned long arch_align_stack(unsigned long sp)
|
||||
return sp & ~0xf;
|
||||
}
|
||||
|
||||
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||
{
|
||||
if (is_compat_task())
|
||||
return randomize_page(mm->brk, SZ_32M);
|
||||
else
|
||||
return randomize_page(mm->brk, SZ_1G);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY.
|
||||
*/
|
||||
|
@ -56,8 +56,7 @@ void __sync_icache_dcache(pte_t pte)
|
||||
struct page *page = pte_page(pte);
|
||||
|
||||
if (!test_and_set_bit(PG_dcache_clean, &page->flags))
|
||||
sync_icache_aliases(page_address(page),
|
||||
PAGE_SIZE << compound_order(page));
|
||||
sync_icache_aliases(page_address(page), page_size(page));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__sync_icache_dcache);
|
||||
|
||||
|
@ -20,78 +20,6 @@
|
||||
|
||||
#include <asm/cputype.h>
|
||||
|
||||
/*
|
||||
* Leave enough space between the mmap area and the stack to honour ulimit in
|
||||
* the face of randomisation.
|
||||
*/
|
||||
#define MIN_GAP (SZ_128M)
|
||||
#define MAX_GAP (STACK_TOP/6*5)
|
||||
|
||||
static int mmap_is_legacy(struct rlimit *rlim_stack)
|
||||
{
|
||||
if (current->personality & ADDR_COMPAT_LAYOUT)
|
||||
return 1;
|
||||
|
||||
if (rlim_stack->rlim_cur == RLIM_INFINITY)
|
||||
return 1;
|
||||
|
||||
return sysctl_legacy_va_layout;
|
||||
}
|
||||
|
||||
unsigned long arch_mmap_rnd(void)
|
||||
{
|
||||
unsigned long rnd;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (test_thread_flag(TIF_32BIT))
|
||||
rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
|
||||
else
|
||||
#endif
|
||||
rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
|
||||
return rnd << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long gap = rlim_stack->rlim_cur;
|
||||
unsigned long pad = (STACK_RND_MASK << PAGE_SHIFT) + stack_guard_gap;
|
||||
|
||||
/* Values close to RLIM_INFINITY can overflow. */
|
||||
if (gap + pad > gap)
|
||||
gap += pad;
|
||||
|
||||
if (gap < MIN_GAP)
|
||||
gap = MIN_GAP;
|
||||
else if (gap > MAX_GAP)
|
||||
gap = MAX_GAP;
|
||||
|
||||
return PAGE_ALIGN(STACK_TOP - gap - rnd);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function, called very early during the creation of a new process VM
|
||||
* image, sets up which VM layout function to use:
|
||||
*/
|
||||
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long random_factor = 0UL;
|
||||
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
random_factor = arch_mmap_rnd();
|
||||
|
||||
/*
|
||||
* Fall back to the standard layout if the personality bit is set, or
|
||||
* if the expected stack growth is unlimited:
|
||||
*/
|
||||
if (mmap_is_legacy(rlim_stack)) {
|
||||
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
|
||||
mm->get_unmapped_area = arch_get_unmapped_area;
|
||||
} else {
|
||||
mm->mmap_base = mmap_base(random_factor, rlim_stack);
|
||||
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* You really shouldn't be using read() or write() on /dev/mem. This might go
|
||||
* away in the future.
|
||||
|
@ -35,7 +35,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
kmem_cache_free(pgd_cache, pgd);
|
||||
}
|
||||
|
||||
void __init pgd_cache_init(void)
|
||||
void __init pgtable_cache_init(void)
|
||||
{
|
||||
if (PGD_SIZE == PAGE_SIZE)
|
||||
return;
|
||||
|
@ -59,11 +59,6 @@ extern unsigned long empty_zero_page;
|
||||
|
||||
#define swapper_pg_dir ((pgd_t *) 0)
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/*
|
||||
* c6x is !MMU, so define the simpliest implementation
|
||||
*/
|
||||
|
@ -75,8 +75,6 @@ do { \
|
||||
tlb_remove_page(tlb, pte); \
|
||||
} while (0)
|
||||
|
||||
#define check_pgt_cache() do {} while (0)
|
||||
|
||||
extern void pagetable_init(void);
|
||||
extern void pre_mmu_init(void);
|
||||
extern void pre_trap_init(void);
|
||||
|
@ -296,11 +296,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do {} while (0)
|
||||
|
||||
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
|
||||
remap_pfn_range(vma, vaddr, pfn, size, prot)
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#define __ARCH_USE_5LEVEL_HACK
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
#include <asm-generic/pgtable.h>
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
extern void paging_init(void);
|
||||
#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
|
||||
#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
|
||||
@ -34,11 +33,6 @@ static inline int pte_file(pte_t pte) { return 0; }
|
||||
extern unsigned int kobjsize(const void *objp);
|
||||
extern int is_in_rom(unsigned long);
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/*
|
||||
* All 32bit addresses are effectively valid for vmalloc...
|
||||
* Sort of meaningless for non-VM targets.
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
#include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */
|
||||
|
||||
#define check_pgt_cache() do {} while (0)
|
||||
|
||||
extern unsigned long long kmap_generation;
|
||||
|
||||
/*
|
||||
|
@ -431,9 +431,6 @@ static inline int pte_exec(pte_t pte)
|
||||
|
||||
#define __pte_offset(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
||||
|
||||
/* I think this is in case we have page table caches; needed by init/main.c */
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/*
|
||||
* Swap/file PTE definitions. If _PAGE_PRESENT is zero, the rest of the PTE is
|
||||
* interpreted as swap information. The remaining free bits are interpreted as
|
||||
|
@ -3,5 +3,5 @@
|
||||
# Makefile for Hexagon memory management subsystem
|
||||
#
|
||||
|
||||
obj-y := init.o pgalloc.o ioremap.o uaccess.o vm_fault.o cache.o
|
||||
obj-y := init.o ioremap.o uaccess.o vm_fault.o cache.o
|
||||
obj-y += copy_to_user.o copy_from_user.o strnlen_user.o vm_tlb.o
|
||||
|
@ -1,10 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
void __init pgtable_cache_init(void)
|
||||
{
|
||||
}
|
@ -72,10 +72,6 @@ config 64BIT
|
||||
config ZONE_DMA32
|
||||
def_bool y
|
||||
|
||||
config QUICKLIST
|
||||
bool
|
||||
default y
|
||||
|
||||
config MMU
|
||||
bool
|
||||
default y
|
||||
|
@ -19,18 +19,19 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/quicklist.h>
|
||||
|
||||
#include <asm-generic/pgalloc.h>
|
||||
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
{
|
||||
return quicklist_alloc(0, GFP_KERNEL, NULL);
|
||||
return (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
|
||||
}
|
||||
|
||||
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
{
|
||||
quicklist_free(0, NULL, pgd);
|
||||
free_page((unsigned long)pgd);
|
||||
}
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS == 4
|
||||
@ -42,12 +43,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
|
||||
|
||||
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return quicklist_alloc(0, GFP_KERNEL, NULL);
|
||||
return (pud_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
|
||||
}
|
||||
|
||||
static inline void pud_free(struct mm_struct *mm, pud_t *pud)
|
||||
{
|
||||
quicklist_free(0, NULL, pud);
|
||||
free_page((unsigned long)pud);
|
||||
}
|
||||
#define __pud_free_tlb(tlb, pud, address) pud_free((tlb)->mm, pud)
|
||||
#endif /* CONFIG_PGTABLE_LEVELS == 4 */
|
||||
@ -60,12 +61,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
|
||||
|
||||
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return quicklist_alloc(0, GFP_KERNEL, NULL);
|
||||
return (pmd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
|
||||
}
|
||||
|
||||
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
|
||||
{
|
||||
quicklist_free(0, NULL, pmd);
|
||||
free_page((unsigned long)pmd);
|
||||
}
|
||||
|
||||
#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd)
|
||||
@ -83,43 +84,6 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
|
||||
pmd_val(*pmd_entry) = __pa(pte);
|
||||
}
|
||||
|
||||
static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
|
||||
{
|
||||
struct page *page;
|
||||
void *pg;
|
||||
|
||||
pg = quicklist_alloc(0, GFP_KERNEL, NULL);
|
||||
if (!pg)
|
||||
return NULL;
|
||||
page = virt_to_page(pg);
|
||||
if (!pgtable_page_ctor(page)) {
|
||||
quicklist_free(0, NULL, pg);
|
||||
return NULL;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
|
||||
{
|
||||
return quicklist_alloc(0, GFP_KERNEL, NULL);
|
||||
}
|
||||
|
||||
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
|
||||
{
|
||||
pgtable_page_dtor(pte);
|
||||
quicklist_free_page(0, NULL, pte);
|
||||
}
|
||||
|
||||
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
|
||||
{
|
||||
quicklist_free(0, NULL, pte);
|
||||
}
|
||||
|
||||
static inline void check_pgt_cache(void)
|
||||
{
|
||||
quicklist_trim(0, NULL, 25, 16);
|
||||
}
|
||||
|
||||
#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte)
|
||||
|
||||
#endif /* _ASM_IA64_PGALLOC_H */
|
||||
|
@ -566,11 +566,6 @@ extern struct page *zero_page_memmap_ptr;
|
||||
#define KERNEL_TR_PAGE_SHIFT _PAGE_SIZE_64M
|
||||
#define KERNEL_TR_PAGE_SIZE (1 << KERNEL_TR_PAGE_SHIFT)
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/* These tell get_user_pages() that the first gate page is accessible from user-level. */
|
||||
#define FIXADDR_USER_START GATE_ADDR
|
||||
#ifdef HAVE_BUGGY_SEGREL
|
||||
|
@ -64,7 +64,7 @@ __ia64_sync_icache_dcache (pte_t pte)
|
||||
if (test_bit(PG_arch_1, &page->flags))
|
||||
return; /* i-cache is already coherent with d-cache */
|
||||
|
||||
flush_icache_range(addr, addr + (PAGE_SIZE << compound_order(page)));
|
||||
flush_icache_range(addr, addr + page_size(page));
|
||||
set_bit(PG_arch_1, &page->flags); /* mark page as clean */
|
||||
}
|
||||
|
||||
|
@ -176,11 +176,4 @@ pgprot_t pgprot_dmacoherent(pgprot_t prot);
|
||||
#include <asm-generic/pgtable.h>
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif /* _M68K_PGTABLE_H */
|
||||
|
@ -44,11 +44,6 @@ extern void paging_init(void);
|
||||
*/
|
||||
#define ZERO_PAGE(vaddr) (virt_to_page(0))
|
||||
|
||||
/*
|
||||
* No page table caches to initialise.
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
/*
|
||||
* All 32bit addresses are effectively valid for vmalloc...
|
||||
* Sort of meaningless for non-VM targets.
|
||||
@ -60,6 +55,4 @@ extern void paging_init(void);
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif /* _M68KNOMMU_PGTABLE_H */
|
||||
|
@ -21,83 +21,23 @@
|
||||
#include <asm/cache.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define PGDIR_ORDER 0
|
||||
|
||||
/*
|
||||
* This is handled very differently on MicroBlaze since out page tables
|
||||
* are all 0's and I want to be able to use these zero'd pages elsewhere
|
||||
* as well - it gives us quite a speedup.
|
||||
* -- Cort
|
||||
*/
|
||||
extern struct pgtable_cache_struct {
|
||||
unsigned long *pgd_cache;
|
||||
unsigned long *pte_cache;
|
||||
unsigned long pgtable_cache_sz;
|
||||
} quicklists;
|
||||
|
||||
#define pgd_quicklist (quicklists.pgd_cache)
|
||||
#define pmd_quicklist ((unsigned long *)0)
|
||||
#define pte_quicklist (quicklists.pte_cache)
|
||||
#define pgtable_cache_size (quicklists.pgtable_cache_sz)
|
||||
|
||||
extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */
|
||||
extern atomic_t zero_sz; /* # currently pre-zero'd pages */
|
||||
extern atomic_t zeropage_hits; /* # zero'd pages request that we've done */
|
||||
extern atomic_t zeropage_calls; /* # zero'd pages request that've been made */
|
||||
extern atomic_t zerototal; /* # pages zero'd over time */
|
||||
|
||||
#define zero_quicklist (zero_cache)
|
||||
#define zero_cache_sz (zero_sz)
|
||||
#define zero_cache_calls (zeropage_calls)
|
||||
#define zero_cache_hits (zeropage_hits)
|
||||
#define zero_cache_total (zerototal)
|
||||
|
||||
/*
|
||||
* return a pre-zero'd page from the list,
|
||||
* return NULL if none available -- Cort
|
||||
*/
|
||||
extern unsigned long get_zero_page_fast(void);
|
||||
#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
|
||||
#include <asm-generic/pgalloc.h>
|
||||
|
||||
extern void __bad_pte(pmd_t *pmd);
|
||||
|
||||
static inline pgd_t *get_pgd_slow(void)
|
||||
static inline pgd_t *get_pgd(void)
|
||||
{
|
||||
pgd_t *ret;
|
||||
|
||||
ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER);
|
||||
if (ret != NULL)
|
||||
clear_page(ret);
|
||||
return ret;
|
||||
return (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0);
|
||||
}
|
||||
|
||||
static inline pgd_t *get_pgd_fast(void)
|
||||
{
|
||||
unsigned long *ret;
|
||||
|
||||
ret = pgd_quicklist;
|
||||
if (ret != NULL) {
|
||||
pgd_quicklist = (unsigned long *)(*ret);
|
||||
ret[0] = 0;
|
||||
pgtable_cache_size--;
|
||||
} else
|
||||
ret = (unsigned long *)get_pgd_slow();
|
||||
return (pgd_t *)ret;
|
||||
}
|
||||
|
||||
static inline void free_pgd_fast(pgd_t *pgd)
|
||||
{
|
||||
*(unsigned long **)pgd = pgd_quicklist;
|
||||
pgd_quicklist = (unsigned long *) pgd;
|
||||
pgtable_cache_size++;
|
||||
}
|
||||
|
||||
static inline void free_pgd_slow(pgd_t *pgd)
|
||||
static inline void free_pgd(pgd_t *pgd)
|
||||
{
|
||||
free_page((unsigned long)pgd);
|
||||
}
|
||||
|
||||
#define pgd_free(mm, pgd) free_pgd_fast(pgd)
|
||||
#define pgd_alloc(mm) get_pgd_fast()
|
||||
#define pgd_free(mm, pgd) free_pgd(pgd)
|
||||
#define pgd_alloc(mm) get_pgd()
|
||||
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
@ -110,50 +50,6 @@ static inline void free_pgd_slow(pgd_t *pgd)
|
||||
|
||||
extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
|
||||
|
||||
static inline struct page *pte_alloc_one(struct mm_struct *mm)
|
||||
{
|
||||
struct page *ptepage;
|
||||
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
int flags = GFP_KERNEL | __GFP_HIGHMEM;
|
||||
#else
|
||||
int flags = GFP_KERNEL;
|
||||
#endif
|
||||
|
||||
ptepage = alloc_pages(flags, 0);
|
||||
if (!ptepage)
|
||||
return NULL;
|
||||
clear_highpage(ptepage);
|
||||
if (!pgtable_page_ctor(ptepage)) {
|
||||
__free_page(ptepage);
|
||||
return NULL;
|
||||
}
|
||||
return ptepage;
|
||||
}
|
||||
|
||||
static inline void pte_free_fast(pte_t *pte)
|
||||
{
|
||||
*(unsigned long **)pte = pte_quicklist;
|
||||
pte_quicklist = (unsigned long *) pte;
|
||||
pgtable_cache_size++;
|
||||
}
|
||||
|
||||
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
|
||||
{
|
||||
free_page((unsigned long)pte);
|
||||
}
|
||||
|
||||
static inline void pte_free_slow(struct page *ptepage)
|
||||
{
|
||||
__free_page(ptepage);
|
||||
}
|
||||
|
||||
static inline void pte_free(struct mm_struct *mm, struct page *ptepage)
|
||||
{
|
||||
pgtable_page_dtor(ptepage);
|
||||
__free_page(ptepage);
|
||||
}
|
||||
|
||||
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
|
||||
|
||||
#define pmd_populate(mm, pmd, pte) \
|
||||
@ -171,10 +67,6 @@ static inline void pte_free(struct mm_struct *mm, struct page *ptepage)
|
||||
#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x)
|
||||
#define pgd_populate(mm, pmd, pte) BUG()
|
||||
|
||||
extern int do_check_pgt_cache(int, int);
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif /* _ASM_MICROBLAZE_PGALLOC_H */
|
||||
|
@ -46,8 +46,6 @@ extern int mem_init_done;
|
||||
|
||||
#define swapper_pg_dir ((pgd_t *) NULL)
|
||||
|
||||
#define pgtable_cache_init() do {} while (0)
|
||||
|
||||
#define arch_enter_lazy_cpu_mode() do {} while (0)
|
||||
|
||||
#define pgprot_noncached_wc(prot) prot
|
||||
@ -526,11 +524,6 @@ extern unsigned long iopa(unsigned long addr);
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
void do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code);
|
||||
|
||||
|
@ -44,10 +44,6 @@ unsigned long ioremap_base;
|
||||
unsigned long ioremap_bot;
|
||||
EXPORT_SYMBOL(ioremap_bot);
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
struct pgtable_cache_struct quicklists;
|
||||
#endif
|
||||
|
||||
static void __iomem *__ioremap(phys_addr_t addr, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
|
@ -5,7 +5,6 @@ config MIPS
|
||||
select ARCH_32BIT_OFF_T if !64BIT
|
||||
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
|
||||
select ARCH_CLOCKSOURCE_DATA
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_HAS_UBSAN_SANITIZE_ALL
|
||||
select ARCH_SUPPORTS_UPROBES
|
||||
@ -13,6 +12,7 @@ config MIPS
|
||||
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select BUILDTIME_EXTABLE_SORT
|
||||
select CLONE_BACKWARDS
|
||||
|
@ -105,8 +105,6 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
|
||||
|
||||
#endif /* __PAGETABLE_PUD_FOLDED */
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
extern void pagetable_init(void);
|
||||
|
||||
#endif /* _ASM_PGALLOC_H */
|
||||
|
@ -661,9 +661,4 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* _ASM_PGTABLE_H */
|
||||
|
@ -29,11 +29,6 @@
|
||||
|
||||
extern unsigned int vced_count, vcei_count;
|
||||
|
||||
/*
|
||||
* MIPS does have an arch_pick_mmap_layout()
|
||||
*/
|
||||
#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
#ifdef CONFIG_KVM_GUEST
|
||||
/* User space process size is limited to 1GB in KVM Guest Mode */
|
||||
|
@ -20,33 +20,6 @@
|
||||
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
|
||||
EXPORT_SYMBOL(shm_align_mask);
|
||||
|
||||
/* gap between mmap and stack */
|
||||
#define MIN_GAP (128*1024*1024UL)
|
||||
#define MAX_GAP ((TASK_SIZE)/6*5)
|
||||
|
||||
static int mmap_is_legacy(struct rlimit *rlim_stack)
|
||||
{
|
||||
if (current->personality & ADDR_COMPAT_LAYOUT)
|
||||
return 1;
|
||||
|
||||
if (rlim_stack->rlim_cur == RLIM_INFINITY)
|
||||
return 1;
|
||||
|
||||
return sysctl_legacy_va_layout;
|
||||
}
|
||||
|
||||
static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long gap = rlim_stack->rlim_cur;
|
||||
|
||||
if (gap < MIN_GAP)
|
||||
gap = MIN_GAP;
|
||||
else if (gap > MAX_GAP)
|
||||
gap = MAX_GAP;
|
||||
|
||||
return PAGE_ALIGN(TASK_SIZE - gap - rnd);
|
||||
}
|
||||
|
||||
#define COLOUR_ALIGN(addr, pgoff) \
|
||||
((((addr) + shm_align_mask) & ~shm_align_mask) + \
|
||||
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
|
||||
@ -144,63 +117,6 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
|
||||
addr0, len, pgoff, flags, DOWN);
|
||||
}
|
||||
|
||||
unsigned long arch_mmap_rnd(void)
|
||||
{
|
||||
unsigned long rnd;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (TASK_IS_32BIT_ADDR)
|
||||
rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
|
||||
else
|
||||
#endif /* CONFIG_COMPAT */
|
||||
rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
|
||||
|
||||
return rnd << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
|
||||
{
|
||||
unsigned long random_factor = 0UL;
|
||||
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
random_factor = arch_mmap_rnd();
|
||||
|
||||
if (mmap_is_legacy(rlim_stack)) {
|
||||
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
|
||||
mm->get_unmapped_area = arch_get_unmapped_area;
|
||||
} else {
|
||||
mm->mmap_base = mmap_base(random_factor, rlim_stack);
|
||||
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned long brk_rnd(void)
|
||||
{
|
||||
unsigned long rnd = get_random_long();
|
||||
|
||||
rnd = rnd << PAGE_SHIFT;
|
||||
/* 8MB for 32bit, 256MB for 64bit */
|
||||
if (TASK_IS_32BIT_ADDR)
|
||||
rnd = rnd & 0x7ffffful;
|
||||
else
|
||||
rnd = rnd & 0xffffffful;
|
||||
|
||||
return rnd;
|
||||
}
|
||||
|
||||
unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||
{
|
||||
unsigned long base = mm->brk;
|
||||
unsigned long ret;
|
||||
|
||||
ret = PAGE_ALIGN(base + brk_rnd());
|
||||
|
||||
if (ret < mm->brk)
|
||||
return mm->brk;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool __virt_addr_valid(const volatile void *kaddr)
|
||||
{
|
||||
unsigned long vaddr = (unsigned long)kaddr;
|
||||
|
@ -23,8 +23,6 @@
|
||||
extern pgd_t *pgd_alloc(struct mm_struct *mm);
|
||||
extern void pgd_free(struct mm_struct *mm, pgd_t * pgd);
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
|
||||
{
|
||||
pgtable_t pte;
|
||||
|
@ -403,8 +403,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
* into virtual address `from'
|
||||
*/
|
||||
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASMNDS32_PGTABLE_H */
|
||||
|
@ -45,6 +45,4 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
tlb_remove_page((tlb), (pte)); \
|
||||
} while (0)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif /* _ASM_NIOS2_PGALLOC_H */
|
||||
|
@ -291,8 +291,6 @@ static inline void pte_clear(struct mm_struct *mm,
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
extern void __init paging_init(void);
|
||||
extern void __init mmu_init(void);
|
||||
|
||||
|
@ -101,6 +101,4 @@ do { \
|
||||
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif
|
||||
|
@ -443,11 +443,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
typedef pte_t *pte_addr_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -124,6 +124,4 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
|
||||
pmd_populate_kernel(mm, pmd, page_address(pte_page))
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif
|
||||
|
@ -132,8 +132,6 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
|
||||
#define PTRS_PER_PTE (1UL << BITS_PER_PTE)
|
||||
|
||||
/* Definitions for 2nd level */
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#define PMD_SHIFT (PLD_SHIFT + BITS_PER_PTE)
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
|
@ -64,8 +64,6 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
|
||||
extern struct kmem_cache *pgtable_cache[];
|
||||
#define PGT_CACHE(shift) pgtable_cache[shift]
|
||||
|
||||
static inline void check_pgt_cache(void) { }
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
#include <asm/book3s/pgalloc.h>
|
||||
#else
|
||||
|
@ -87,7 +87,6 @@ extern unsigned long ioremap_bot;
|
||||
unsigned long vmalloc_to_phys(void *vmalloc_addr);
|
||||
|
||||
void pgtable_cache_add(unsigned int shift);
|
||||
void pgtable_cache_init(void);
|
||||
|
||||
#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_PPC32)
|
||||
void mark_initmem_nx(void);
|
||||
|
@ -1748,7 +1748,7 @@ void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
|
||||
/*
|
||||
* IF we try to do a HUGE PTE update after a withdraw is done.
|
||||
* we will find the below NULL. This happens when we do
|
||||
* split_huge_page_pmd
|
||||
* split_huge_pmd
|
||||
*/
|
||||
if (!hpte_slot_array)
|
||||
return;
|
||||
|
@ -129,11 +129,8 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
|
||||
* Allow to use larger than 64k IOMMU pages. Only do that
|
||||
* if we are backed by hugetlb.
|
||||
*/
|
||||
if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) {
|
||||
struct page *head = compound_head(page);
|
||||
|
||||
pageshift = compound_order(head) + PAGE_SHIFT;
|
||||
}
|
||||
if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page))
|
||||
pageshift = page_shift(compound_head(page));
|
||||
mem->pageshift = min(mem->pageshift, pageshift);
|
||||
/*
|
||||
* We don't need struct page reference any more, switch
|
||||
|
@ -667,7 +667,7 @@ void flush_dcache_icache_hugepage(struct page *page)
|
||||
|
||||
BUG_ON(!PageCompound(page));
|
||||
|
||||
for (i = 0; i < (1UL << compound_order(page)); i++) {
|
||||
for (i = 0; i < compound_nr(page); i++) {
|
||||
if (!PageHighMem(page)) {
|
||||
__flush_dcache_icache(page_address(page+i));
|
||||
} else {
|
||||
|
@ -59,6 +59,18 @@ config RISCV
|
||||
select ARCH_HAS_GIGANTIC_PAGE
|
||||
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
|
||||
select SPARSEMEM_STATIC if 32BIT
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
select HAVE_ARCH_MMAP_RND_BITS
|
||||
|
||||
config ARCH_MMAP_RND_BITS_MIN
|
||||
default 18 if 64BIT
|
||||
default 8
|
||||
|
||||
# max bits determined by the following formula:
|
||||
# VA_BITS - PAGE_SHIFT - 3
|
||||
config ARCH_MMAP_RND_BITS_MAX
|
||||
default 24 if 64BIT # SV39 based
|
||||
default 17
|
||||
|
||||
config MMU
|
||||
def_bool y
|
||||
|
@ -82,8 +82,4 @@ do { \
|
||||
tlb_remove_page((tlb), pte); \
|
||||
} while (0)
|
||||
|
||||
static inline void check_pgt_cache(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* _ASM_RISCV_PGALLOC_H */
|
||||
|
@ -424,11 +424,6 @@ extern void *dtb_early_va;
|
||||
extern void setup_bootmem(void);
|
||||
extern void paging_init(void);
|
||||
|
||||
static inline void pgtable_cache_init(void)
|
||||
{
|
||||
/* No page table caches to initialize */
|
||||
}
|
||||
|
||||
#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
|
||||
#define VMALLOC_END (PAGE_OFFSET - 1)
|
||||
#define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE)
|
||||
|
@ -1682,12 +1682,6 @@ extern void s390_reset_cmma(struct mm_struct *mm);
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
static inline void pgtable_cache_init(void) { }
|
||||
static inline void check_pgt_cache(void) { }
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
#endif /* _S390_PAGE_H */
|
||||
|
@ -2,10 +2,8 @@
|
||||
#ifndef __ASM_SH_PGALLOC_H
|
||||
#define __ASM_SH_PGALLOC_H
|
||||
|
||||
#include <linux/quicklist.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#define QUICK_PT 0 /* Other page table pages that are zero on free */
|
||||
#include <asm-generic/pgalloc.h>
|
||||
|
||||
extern pgd_t *pgd_alloc(struct mm_struct *);
|
||||
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
|
||||
@ -29,41 +27,6 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
|
||||
}
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
/*
|
||||
* Allocate and free page tables.
|
||||
*/
|
||||
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
|
||||
{
|
||||
return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
|
||||
}
|
||||
|
||||
static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
|
||||
{
|
||||
struct page *page;
|
||||
void *pg;
|
||||
|
||||
pg = quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
|
||||
if (!pg)
|
||||
return NULL;
|
||||
page = virt_to_page(pg);
|
||||
if (!pgtable_page_ctor(page)) {
|
||||
quicklist_free(QUICK_PT, NULL, pg);
|
||||
return NULL;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
|
||||
{
|
||||
quicklist_free(QUICK_PT, NULL, pte);
|
||||
}
|
||||
|
||||
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
|
||||
{
|
||||
pgtable_page_dtor(pte);
|
||||
quicklist_free_page(QUICK_PT, NULL, pte);
|
||||
}
|
||||
|
||||
#define __pte_free_tlb(tlb,pte,addr) \
|
||||
do { \
|
||||
pgtable_page_dtor(pte); \
|
||||
@ -79,9 +42,4 @@ do { \
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
static inline void check_pgt_cache(void)
|
||||
{
|
||||
quicklist_trim(QUICK_PT, NULL, 25, 16);
|
||||
}
|
||||
|
||||
#endif /* __ASM_SH_PGALLOC_H */
|
||||
|
@ -123,11 +123,6 @@ typedef pte_t *pte_addr_t;
|
||||
|
||||
#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
|
||||
|
||||
/*
|
||||
* Initialise the page table caches
|
||||
*/
|
||||
extern void pgtable_cache_init(void);
|
||||
|
||||
struct vm_area_struct;
|
||||
struct mm_struct;
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
menu "Memory management options"
|
||||
|
||||
config QUICKLIST
|
||||
def_bool y
|
||||
|
||||
config MMU
|
||||
bool "Support for memory management hardware"
|
||||
depends on !CPU_SH2
|
||||
|
@ -97,7 +97,3 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
|
||||
void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
|
||||
{
|
||||
}
|
||||
|
||||
void pgtable_cache_init(void)
|
||||
{
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ void srmmu_free_nocache(void *addr, int size);
|
||||
|
||||
extern struct resource sparc_iomap;
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
pgd_t *get_pgd_fast(void);
|
||||
static inline void free_pgd_fast(pgd_t *pgd)
|
||||
{
|
||||
|
@ -69,8 +69,6 @@ void pte_free(struct mm_struct *mm, pgtable_t ptepage);
|
||||
#define pmd_populate(MM, PMD, PTE) pmd_set(MM, PMD, PTE)
|
||||
#define pmd_pgtable(PMD) ((pte_t *)__pmd_page(PMD))
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
void pgtable_free(void *table, bool is_page);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -445,9 +445,4 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
|
||||
/* We provide our own get_unmapped_area to cope with VA holes for userland */
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* !(_SPARC_PGTABLE_H) */
|
||||
|
@ -1135,7 +1135,6 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
|
||||
unsigned long);
|
||||
#define HAVE_ARCH_FB_UNMAPPED_AREA
|
||||
|
||||
void pgtable_cache_init(void);
|
||||
void sun4v_register_fault_status(void);
|
||||
void sun4v_ktsb_register(void);
|
||||
void __init cheetah_ecache_flush_init(void);
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/vaddrs.h>
|
||||
#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */
|
||||
#include <asm/setup.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/prom.h>
|
||||
|
@ -43,7 +43,5 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
|
||||
#define __pmd_free_tlb(tlb,x, address) tlb_remove_page((tlb),virt_to_page(x))
|
||||
#endif
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -32,8 +32,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
/* zero page used for uninitialized stuff */
|
||||
extern unsigned long *empty_zero_page;
|
||||
|
||||
#define pgtable_cache_init() do ; while (0)
|
||||
|
||||
/* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||
* current 8MB value just means that there will be a 8MB "hole" after the
|
||||
* physical memory until the kernel virtual memory starts. That means that
|
||||
|
@ -18,8 +18,6 @@
|
||||
#define __HAVE_ARCH_PTE_ALLOC_ONE
|
||||
#include <asm-generic/pgalloc.h>
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
|
||||
#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
|
||||
|
||||
|
@ -285,8 +285,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __UNICORE_PGTABLE_H__ */
|
||||
|
@ -29,8 +29,6 @@ extern pgd_t swapper_pg_dir[1024];
|
||||
extern pgd_t initial_page_table[1024];
|
||||
extern pmd_t initial_pg_pmd[];
|
||||
|
||||
static inline void pgtable_cache_init(void) { }
|
||||
static inline void check_pgt_cache(void) { }
|
||||
void paging_init(void);
|
||||
void sync_initial_page_table(void);
|
||||
|
||||
|
@ -241,9 +241,6 @@ extern void cleanup_highmap(void);
|
||||
#define HAVE_ARCH_UNMAPPED_AREA
|
||||
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
|
||||
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#define PAGE_AGP PAGE_KERNEL_NOCACHE
|
||||
#define HAVE_PAGE_AGP 1
|
||||
|
||||
|
@ -357,7 +357,7 @@ static void pgd_prepopulate_user_pmd(struct mm_struct *mm,
|
||||
|
||||
static struct kmem_cache *pgd_cache;
|
||||
|
||||
void __init pgd_cache_init(void)
|
||||
void __init pgtable_cache_init(void)
|
||||
{
|
||||
/*
|
||||
* When PAE kernel is running as a Xen domain, it does not use
|
||||
@ -402,10 +402,6 @@ static inline void _pgd_free(pgd_t *pgd)
|
||||
}
|
||||
#else
|
||||
|
||||
void __init pgd_cache_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline pgd_t *_pgd_alloc(void)
|
||||
{
|
||||
return (pgd_t *)__get_free_pages(GFP_PGTABLE_USER,
|
||||
|
@ -238,7 +238,6 @@ extern void paging_init(void);
|
||||
# define swapper_pg_dir NULL
|
||||
static inline void paging_init(void) { }
|
||||
#endif
|
||||
static inline void pgtable_cache_init(void) { }
|
||||
|
||||
/*
|
||||
* The pmd contains the kernel virtual address of the pte page.
|
||||
|
@ -160,9 +160,6 @@ static inline void invalidate_dtlb_mapping (unsigned address)
|
||||
invalidate_dtlb_entry(tlb_entry);
|
||||
}
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
|
||||
/*
|
||||
* DO NOT USE THESE FUNCTIONS. These instructions aren't part of the Xtensa
|
||||
* ISA and exist only for test purposes..
|
||||
|
@ -100,26 +100,9 @@ unsigned long __weak memory_block_size_bytes(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(memory_block_size_bytes);
|
||||
|
||||
static unsigned long get_memory_block_size(void)
|
||||
{
|
||||
unsigned long block_sz;
|
||||
|
||||
block_sz = memory_block_size_bytes();
|
||||
|
||||
/* Validate blk_sz is a power of 2 and not less than section size */
|
||||
if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) {
|
||||
WARN_ON(1);
|
||||
block_sz = MIN_MEMORY_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return block_sz;
|
||||
}
|
||||
|
||||
/*
|
||||
* use this as the physical section index that this memsection
|
||||
* uses.
|
||||
* Show the first physical section index (number) of this memory block.
|
||||
*/
|
||||
|
||||
static ssize_t phys_index_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -131,7 +114,10 @@ static ssize_t phys_index_show(struct device *dev,
|
||||
}
|
||||
|
||||
/*
|
||||
* Show whether the section of memory is likely to be hot-removable
|
||||
* Show whether the memory block is likely to be offlineable (or is already
|
||||
* offline). Once offline, the memory block could be removed. The return
|
||||
* value does, however, not indicate that there is a way to remove the
|
||||
* memory block.
|
||||
*/
|
||||
static ssize_t removable_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
@ -455,12 +441,12 @@ static DEVICE_ATTR_RO(phys_device);
|
||||
static DEVICE_ATTR_RO(removable);
|
||||
|
||||
/*
|
||||
* Block size attribute stuff
|
||||
* Show the memory block size (shared by all memory blocks).
|
||||
*/
|
||||
static ssize_t block_size_bytes_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%lx\n", get_memory_block_size());
|
||||
return sprintf(buf, "%lx\n", memory_block_size_bytes());
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(block_size_bytes);
|
||||
@ -670,10 +656,10 @@ static int init_memory_block(struct memory_block **memory,
|
||||
return -ENOMEM;
|
||||
|
||||
mem->start_section_nr = block_id * sections_per_block;
|
||||
mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
|
||||
mem->state = state;
|
||||
start_pfn = section_nr_to_pfn(mem->start_section_nr);
|
||||
mem->phys_device = arch_get_memory_phys_device(start_pfn);
|
||||
mem->nid = NUMA_NO_NODE;
|
||||
|
||||
ret = register_memory(mem);
|
||||
|
||||
@ -810,19 +796,22 @@ static const struct attribute_group *memory_root_attr_groups[] = {
|
||||
/*
|
||||
* Initialize the sysfs support for memory devices...
|
||||
*/
|
||||
int __init memory_dev_init(void)
|
||||
void __init memory_dev_init(void)
|
||||
{
|
||||
int ret;
|
||||
int err;
|
||||
unsigned long block_sz, nr;
|
||||
|
||||
/* Validate the configured memory block size */
|
||||
block_sz = memory_block_size_bytes();
|
||||
if (!is_power_of_2(block_sz) || block_sz < MIN_MEMORY_BLOCK_SIZE)
|
||||
panic("Memory block size not suitable: 0x%lx\n", block_sz);
|
||||
sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
|
||||
|
||||
ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
block_sz = get_memory_block_size();
|
||||
sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
|
||||
|
||||
/*
|
||||
* Create entries for memory sections that were found
|
||||
* during boot and have been initialized
|
||||
@ -838,8 +827,7 @@ int __init memory_dev_init(void)
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
|
||||
return ret;
|
||||
panic("%s() failed: %d\n", __func__, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,6 +427,8 @@ static ssize_t node_read_meminfo(struct device *dev,
|
||||
"Node %d AnonHugePages: %8lu kB\n"
|
||||
"Node %d ShmemHugePages: %8lu kB\n"
|
||||
"Node %d ShmemPmdMapped: %8lu kB\n"
|
||||
"Node %d FileHugePages: %8lu kB\n"
|
||||
"Node %d FilePmdMapped: %8lu kB\n"
|
||||
#endif
|
||||
,
|
||||
nid, K(node_page_state(pgdat, NR_FILE_DIRTY)),
|
||||
@ -452,6 +454,10 @@ static ssize_t node_read_meminfo(struct device *dev,
|
||||
nid, K(node_page_state(pgdat, NR_SHMEM_THPS) *
|
||||
HPAGE_PMD_NR),
|
||||
nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) *
|
||||
HPAGE_PMD_NR),
|
||||
nid, K(node_page_state(pgdat, NR_FILE_THPS) *
|
||||
HPAGE_PMD_NR),
|
||||
nid, K(node_page_state(pgdat, NR_FILE_PMDMAPPED) *
|
||||
HPAGE_PMD_NR)
|
||||
#endif
|
||||
);
|
||||
@ -756,15 +762,13 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
|
||||
static int register_mem_sect_under_node(struct memory_block *mem_blk,
|
||||
void *arg)
|
||||
{
|
||||
unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
|
||||
unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
|
||||
unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
|
||||
int ret, nid = *(int *)arg;
|
||||
unsigned long pfn, sect_start_pfn, sect_end_pfn;
|
||||
unsigned long pfn;
|
||||
|
||||
mem_blk->nid = nid;
|
||||
|
||||
sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
|
||||
sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
|
||||
sect_end_pfn += PAGES_PER_SECTION - 1;
|
||||
for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
|
||||
for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
|
||||
int page_nid;
|
||||
|
||||
/*
|
||||
@ -789,6 +793,13 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk,
|
||||
if (page_nid != nid)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this memory block spans multiple nodes, we only indicate
|
||||
* the last processed node.
|
||||
*/
|
||||
mem_blk->nid = nid;
|
||||
|
||||
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
|
||||
&mem_blk->dev.kobj,
|
||||
kobject_name(&mem_blk->dev.kobj));
|
||||
@ -804,32 +815,18 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk,
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister memory block device under all nodes that it spans.
|
||||
* Has to be called with mem_sysfs_mutex held (due to unlinked_nodes).
|
||||
* Unregister a memory block device under the node it spans. Memory blocks
|
||||
* with multiple nodes cannot be offlined and therefore also never be removed.
|
||||
*/
|
||||
void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
|
||||
{
|
||||
unsigned long pfn, sect_start_pfn, sect_end_pfn;
|
||||
static nodemask_t unlinked_nodes;
|
||||
if (mem_blk->nid == NUMA_NO_NODE)
|
||||
return;
|
||||
|
||||
nodes_clear(unlinked_nodes);
|
||||
sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
|
||||
sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
|
||||
for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
|
||||
int nid;
|
||||
|
||||
nid = get_nid_for_pfn(pfn);
|
||||
if (nid < 0)
|
||||
continue;
|
||||
if (!node_online(nid))
|
||||
continue;
|
||||
if (node_test_and_set(nid, unlinked_nodes))
|
||||
continue;
|
||||
sysfs_remove_link(&node_devices[nid]->dev.kobj,
|
||||
kobject_name(&mem_blk->dev.kobj));
|
||||
sysfs_remove_link(&mem_blk->dev.kobj,
|
||||
kobject_name(&node_devices[nid]->dev.kobj));
|
||||
}
|
||||
sysfs_remove_link(&node_devices[mem_blk->nid]->dev.kobj,
|
||||
kobject_name(&mem_blk->dev.kobj));
|
||||
sysfs_remove_link(&mem_blk->dev.kobj,
|
||||
kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
|
||||
}
|
||||
|
||||
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)
|
||||
|
@ -1078,7 +1078,7 @@ new_buf:
|
||||
bool merge;
|
||||
|
||||
if (page)
|
||||
pg_size <<= compound_order(page);
|
||||
pg_size = page_size(page);
|
||||
if (off < pg_size &&
|
||||
skb_can_coalesce(skb, i, page, off)) {
|
||||
merge = 1;
|
||||
@ -1105,8 +1105,7 @@ new_buf:
|
||||
__GFP_NORETRY,
|
||||
order);
|
||||
if (page)
|
||||
pg_size <<=
|
||||
compound_order(page);
|
||||
pg_size <<= order;
|
||||
}
|
||||
if (!page) {
|
||||
page = alloc_page(gfp);
|
||||
|
@ -174,7 +174,6 @@ via_map_blit_for_device(struct pci_dev *pdev,
|
||||
static void
|
||||
via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
|
||||
{
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
switch (vsg->state) {
|
||||
@ -189,13 +188,8 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
|
||||
kfree(vsg->desc_pages);
|
||||
/* fall through */
|
||||
case dr_via_pages_locked:
|
||||
for (i = 0; i < vsg->num_pages; ++i) {
|
||||
if (NULL != (page = vsg->pages[i])) {
|
||||
if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
|
||||
SetPageDirty(page);
|
||||
put_page(page);
|
||||
}
|
||||
}
|
||||
put_user_pages_dirty_lock(vsg->pages, vsg->num_pages,
|
||||
(vsg->direction == DMA_FROM_DEVICE));
|
||||
/* fall through */
|
||||
case dr_via_pages_alloc:
|
||||
vfree(vsg->pages);
|
||||
|
@ -54,10 +54,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
|
||||
|
||||
for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->sg_nents, 0) {
|
||||
page = sg_page_iter_page(&sg_iter);
|
||||
if (umem->writable && dirty)
|
||||
put_user_pages_dirty_lock(&page, 1);
|
||||
else
|
||||
put_user_page(page);
|
||||
put_user_pages_dirty_lock(&page, 1, umem->writable && dirty);
|
||||
}
|
||||
|
||||
sg_free_table(&umem->sg_head);
|
||||
|
@ -118,10 +118,7 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np
|
||||
void hfi1_release_user_pages(struct mm_struct *mm, struct page **p,
|
||||
size_t npages, bool dirty)
|
||||
{
|
||||
if (dirty)
|
||||
put_user_pages_dirty_lock(p, npages);
|
||||
else
|
||||
put_user_pages(p, npages);
|
||||
put_user_pages_dirty_lock(p, npages, dirty);
|
||||
|
||||
if (mm) { /* during close after signal, mm can be NULL */
|
||||
atomic64_sub(npages, &mm->pinned_vm);
|
||||
|
@ -40,10 +40,7 @@
|
||||
static void __qib_release_user_pages(struct page **p, size_t num_pages,
|
||||
int dirty)
|
||||
{
|
||||
if (dirty)
|
||||
put_user_pages_dirty_lock(p, num_pages);
|
||||
else
|
||||
put_user_pages(p, num_pages);
|
||||
put_user_pages_dirty_lock(p, num_pages, dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,10 +75,7 @@ static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
|
||||
for_each_sg(chunk->page_list, sg, chunk->nents, i) {
|
||||
page = sg_page(sg);
|
||||
pa = sg_phys(sg);
|
||||
if (dirty)
|
||||
put_user_pages_dirty_lock(&page, 1);
|
||||
else
|
||||
put_user_page(page);
|
||||
put_user_pages_dirty_lock(&page, 1, dirty);
|
||||
usnic_dbg("pa: %pa\n", &pa);
|
||||
}
|
||||
kfree(chunk);
|
||||
|
@ -63,15 +63,7 @@ struct siw_mem *siw_mem_id2obj(struct siw_device *sdev, int stag_index)
|
||||
static void siw_free_plist(struct siw_page_chunk *chunk, int num_pages,
|
||||
bool dirty)
|
||||
{
|
||||
struct page **p = chunk->plist;
|
||||
|
||||
while (num_pages--) {
|
||||
if (!PageDirty(*p) && dirty)
|
||||
put_user_pages_dirty_lock(p, 1);
|
||||
else
|
||||
put_user_page(*p);
|
||||
p++;
|
||||
}
|
||||
put_user_pages_dirty_lock(chunk->plist, num_pages, dirty);
|
||||
}
|
||||
|
||||
void siw_umem_release(struct siw_umem *umem, bool dirty)
|
||||
|
@ -120,7 +120,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
|
||||
if (!page)
|
||||
goto free_pages;
|
||||
list_add_tail(&page->lru, &pages);
|
||||
size_remaining -= PAGE_SIZE << compound_order(page);
|
||||
size_remaining -= page_size(page);
|
||||
max_order = compound_order(page);
|
||||
i++;
|
||||
}
|
||||
@ -133,7 +133,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
|
||||
|
||||
sg = table->sgl;
|
||||
list_for_each_entry_safe(page, tmp_page, &pages, lru) {
|
||||
sg_set_page(sg, page, PAGE_SIZE << compound_order(page), 0);
|
||||
sg_set_page(sg, page, page_size(page), 0);
|
||||
sg = sg_next(sg);
|
||||
list_del(&page->lru);
|
||||
}
|
||||
|
@ -136,8 +136,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
|
||||
page, off_in_page, tlen);
|
||||
fr_len(fp) += tlen;
|
||||
fp_skb(fp)->data_len += tlen;
|
||||
fp_skb(fp)->truesize +=
|
||||
PAGE_SIZE << compound_order(page);
|
||||
fp_skb(fp)->truesize += page_size(page);
|
||||
} else {
|
||||
BUG_ON(!page);
|
||||
from = kmap_atomic(page + (mem_off >> PAGE_SHIFT));
|
||||
|
@ -176,13 +176,13 @@ put_exit:
|
||||
}
|
||||
|
||||
static bool tce_page_is_contained(struct mm_struct *mm, unsigned long hpa,
|
||||
unsigned int page_shift)
|
||||
unsigned int it_page_shift)
|
||||
{
|
||||
struct page *page;
|
||||
unsigned long size = 0;
|
||||
|
||||
if (mm_iommu_is_devmem(mm, hpa, page_shift, &size))
|
||||
return size == (1UL << page_shift);
|
||||
if (mm_iommu_is_devmem(mm, hpa, it_page_shift, &size))
|
||||
return size == (1UL << it_page_shift);
|
||||
|
||||
page = pfn_to_page(hpa >> PAGE_SHIFT);
|
||||
/*
|
||||
@ -190,7 +190,7 @@ static bool tce_page_is_contained(struct mm_struct *mm, unsigned long hpa,
|
||||
* a page we just found. Otherwise the hardware can get access to
|
||||
* a bigger memory chunk that it should.
|
||||
*/
|
||||
return (PAGE_SHIFT + compound_order(compound_head(page))) >= page_shift;
|
||||
return page_shift(compound_head(page)) >= it_page_shift;
|
||||
}
|
||||
|
||||
static inline bool tce_groups_attached(struct tce_container *container)
|
||||
|
@ -670,26 +670,6 @@ out:
|
||||
* libraries. There is no binary dependent code anywhere else.
|
||||
*/
|
||||
|
||||
#ifndef STACK_RND_MASK
|
||||
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
|
||||
#endif
|
||||
|
||||
static unsigned long randomize_stack_top(unsigned long stack_top)
|
||||
{
|
||||
unsigned long random_variable = 0;
|
||||
|
||||
if (current->flags & PF_RANDOMIZE) {
|
||||
random_variable = get_random_long();
|
||||
random_variable &= STACK_RND_MASK;
|
||||
random_variable <<= PAGE_SHIFT;
|
||||
}
|
||||
#ifdef CONFIG_STACK_GROWSUP
|
||||
return PAGE_ALIGN(stack_top) + random_variable;
|
||||
#else
|
||||
return PAGE_ALIGN(stack_top) - random_variable;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int load_elf_binary(struct linux_binprm *bprm)
|
||||
{
|
||||
struct file *interpreter = NULL; /* to shut gcc up */
|
||||
|
13
fs/fat/dir.c
13
fs/fat/dir.c
@ -1100,8 +1100,11 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
/* Avoid race with userspace read via bdev */
|
||||
lock_buffer(bhs[n]);
|
||||
memset(bhs[n]->b_data, 0, sb->s_blocksize);
|
||||
set_buffer_uptodate(bhs[n]);
|
||||
unlock_buffer(bhs[n]);
|
||||
mark_buffer_dirty_inode(bhs[n], dir);
|
||||
|
||||
n++;
|
||||
@ -1158,6 +1161,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
|
||||
fat_time_unix2fat(sbi, ts, &time, &date, &time_cs);
|
||||
|
||||
de = (struct msdos_dir_entry *)bhs[0]->b_data;
|
||||
/* Avoid race with userspace read via bdev */
|
||||
lock_buffer(bhs[0]);
|
||||
/* filling the new directory slots ("." and ".." entries) */
|
||||
memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME);
|
||||
memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME);
|
||||
@ -1180,6 +1185,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
|
||||
de[0].size = de[1].size = 0;
|
||||
memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
|
||||
set_buffer_uptodate(bhs[0]);
|
||||
unlock_buffer(bhs[0]);
|
||||
mark_buffer_dirty_inode(bhs[0], dir);
|
||||
|
||||
err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
|
||||
@ -1237,11 +1243,14 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
|
||||
|
||||
/* fill the directory entry */
|
||||
copy = min(size, sb->s_blocksize);
|
||||
/* Avoid race with userspace read via bdev */
|
||||
lock_buffer(bhs[n]);
|
||||
memcpy(bhs[n]->b_data, slots, copy);
|
||||
set_buffer_uptodate(bhs[n]);
|
||||
unlock_buffer(bhs[n]);
|
||||
mark_buffer_dirty_inode(bhs[n], dir);
|
||||
slots += copy;
|
||||
size -= copy;
|
||||
set_buffer_uptodate(bhs[n]);
|
||||
mark_buffer_dirty_inode(bhs[n], dir);
|
||||
if (!size)
|
||||
break;
|
||||
n++;
|
||||
|
@ -388,8 +388,11 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
/* Avoid race with userspace read via bdev */
|
||||
lock_buffer(c_bh);
|
||||
memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
|
||||
set_buffer_uptodate(c_bh);
|
||||
unlock_buffer(c_bh);
|
||||
mark_buffer_dirty_inode(c_bh, sbi->fat_inode);
|
||||
if (sb->s_flags & SB_SYNCHRONOUS)
|
||||
err = sync_dirty_buffer(c_bh);
|
||||
|
@ -181,6 +181,9 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
|
||||
mapping->flags = 0;
|
||||
mapping->wb_err = 0;
|
||||
atomic_set(&mapping->i_mmap_writable, 0);
|
||||
#ifdef CONFIG_READ_ONLY_THP_FOR_FS
|
||||
atomic_set(&mapping->nr_thps, 0);
|
||||
#endif
|
||||
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE);
|
||||
mapping->private_data = NULL;
|
||||
mapping->writeback_index = 0;
|
||||
|
@ -3319,7 +3319,7 @@ static int io_uring_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
}
|
||||
|
||||
page = virt_to_head_page(ptr);
|
||||
if (sz > (PAGE_SIZE << compound_order(page)))
|
||||
if (sz > page_size(page))
|
||||
return -EINVAL;
|
||||
|
||||
pfn = virt_to_phys(ptr) >> PAGE_SHIFT;
|
||||
|
@ -89,8 +89,6 @@ EXPORT_SYMBOL(jbd2_journal_blocks_per_page);
|
||||
EXPORT_SYMBOL(jbd2_journal_invalidatepage);
|
||||
EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
|
||||
EXPORT_SYMBOL(jbd2_journal_force_commit);
|
||||
EXPORT_SYMBOL(jbd2_journal_inode_add_write);
|
||||
EXPORT_SYMBOL(jbd2_journal_inode_add_wait);
|
||||
EXPORT_SYMBOL(jbd2_journal_inode_ranged_write);
|
||||
EXPORT_SYMBOL(jbd2_journal_inode_ranged_wait);
|
||||
EXPORT_SYMBOL(jbd2_journal_init_jbd_inode);
|
||||
|
@ -2622,18 +2622,6 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jbd2_journal_inode_add_write(handle_t *handle, struct jbd2_inode *jinode)
|
||||
{
|
||||
return jbd2_journal_file_inode(handle, jinode,
|
||||
JI_WRITE_DATA | JI_WAIT_DATA, 0, LLONG_MAX);
|
||||
}
|
||||
|
||||
int jbd2_journal_inode_add_wait(handle_t *handle, struct jbd2_inode *jinode)
|
||||
{
|
||||
return jbd2_journal_file_inode(handle, jinode, JI_WAIT_DATA, 0,
|
||||
LLONG_MAX);
|
||||
}
|
||||
|
||||
int jbd2_journal_inode_ranged_write(handle_t *handle,
|
||||
struct jbd2_inode *jinode, loff_t start_byte, loff_t length)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user