Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "19 patches. Subsystems affected by this patch series: MAINTAINERS, ipc, fork, checkpatch, lib, and mm (memcg, slub, pagemap, madvise, migration, hugetlb)" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: include/linux/log2.h: add missing () around n in roundup_pow_of_two() mm/khugepaged.c: fix khugepaged's request size in collapse_file mm/hugetlb: fix a race between hugetlb sysctl handlers mm/hugetlb: try preferred node first when alloc gigantic page from cma mm/migrate: preserve soft dirty in remove_migration_pte() mm/migrate: remove unnecessary is_zone_device_page() check mm/rmap: fixup copying of soft dirty and uffd ptes mm/migrate: fixup setting UFFD_WP flag mm: madvise: fix vma user-after-free checkpatch: fix the usage of capture group ( ... ) fork: adjust sysctl_max_threads definition to match prototype ipc: adjust proc_ipc_sem_dointvec definition to match prototype mm: track page table modifications in __apply_to_page_range() MAINTAINERS: IA64: mark Status as Odd Fixes only MAINTAINERS: add LLVM maintainers MAINTAINERS: update Cavium/Marvell entries mm: slub: fix conversion of freelist_corrupted() mm: memcg: fix memcg reclaim soft lockup memcg: fix use-after-free in uncharge_batch
This commit is contained in:
37
mm/memory.c
37
mm/memory.c
@@ -73,6 +73,7 @@
|
||||
#include <linux/numa.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <trace/events/kmem.h>
|
||||
|
||||
@@ -83,6 +84,7 @@
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#include "pgalloc-track.h"
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) && !defined(CONFIG_COMPILE_TEST)
|
||||
@@ -2206,7 +2208,8 @@ EXPORT_SYMBOL(vm_iomap_memory);
|
||||
|
||||
static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
|
||||
unsigned long addr, unsigned long end,
|
||||
pte_fn_t fn, void *data, bool create)
|
||||
pte_fn_t fn, void *data, bool create,
|
||||
pgtbl_mod_mask *mask)
|
||||
{
|
||||
pte_t *pte;
|
||||
int err = 0;
|
||||
@@ -2214,7 +2217,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
|
||||
|
||||
if (create) {
|
||||
pte = (mm == &init_mm) ?
|
||||
pte_alloc_kernel(pmd, addr) :
|
||||
pte_alloc_kernel_track(pmd, addr, mask) :
|
||||
pte_alloc_map_lock(mm, pmd, addr, &ptl);
|
||||
if (!pte)
|
||||
return -ENOMEM;
|
||||
@@ -2235,6 +2238,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
|
||||
break;
|
||||
}
|
||||
} while (addr += PAGE_SIZE, addr != end);
|
||||
*mask |= PGTBL_PTE_MODIFIED;
|
||||
|
||||
arch_leave_lazy_mmu_mode();
|
||||
|
||||
@@ -2245,7 +2249,8 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
|
||||
|
||||
static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
|
||||
unsigned long addr, unsigned long end,
|
||||
pte_fn_t fn, void *data, bool create)
|
||||
pte_fn_t fn, void *data, bool create,
|
||||
pgtbl_mod_mask *mask)
|
||||
{
|
||||
pmd_t *pmd;
|
||||
unsigned long next;
|
||||
@@ -2254,7 +2259,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
|
||||
BUG_ON(pud_huge(*pud));
|
||||
|
||||
if (create) {
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
pmd = pmd_alloc_track(mm, pud, addr, mask);
|
||||
if (!pmd)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
@@ -2264,7 +2269,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
|
||||
next = pmd_addr_end(addr, end);
|
||||
if (create || !pmd_none_or_clear_bad(pmd)) {
|
||||
err = apply_to_pte_range(mm, pmd, addr, next, fn, data,
|
||||
create);
|
||||
create, mask);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -2274,14 +2279,15 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
|
||||
|
||||
static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
|
||||
unsigned long addr, unsigned long end,
|
||||
pte_fn_t fn, void *data, bool create)
|
||||
pte_fn_t fn, void *data, bool create,
|
||||
pgtbl_mod_mask *mask)
|
||||
{
|
||||
pud_t *pud;
|
||||
unsigned long next;
|
||||
int err = 0;
|
||||
|
||||
if (create) {
|
||||
pud = pud_alloc(mm, p4d, addr);
|
||||
pud = pud_alloc_track(mm, p4d, addr, mask);
|
||||
if (!pud)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
@@ -2291,7 +2297,7 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
|
||||
next = pud_addr_end(addr, end);
|
||||
if (create || !pud_none_or_clear_bad(pud)) {
|
||||
err = apply_to_pmd_range(mm, pud, addr, next, fn, data,
|
||||
create);
|
||||
create, mask);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -2301,14 +2307,15 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
|
||||
|
||||
static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd,
|
||||
unsigned long addr, unsigned long end,
|
||||
pte_fn_t fn, void *data, bool create)
|
||||
pte_fn_t fn, void *data, bool create,
|
||||
pgtbl_mod_mask *mask)
|
||||
{
|
||||
p4d_t *p4d;
|
||||
unsigned long next;
|
||||
int err = 0;
|
||||
|
||||
if (create) {
|
||||
p4d = p4d_alloc(mm, pgd, addr);
|
||||
p4d = p4d_alloc_track(mm, pgd, addr, mask);
|
||||
if (!p4d)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
@@ -2318,7 +2325,7 @@ static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd,
|
||||
next = p4d_addr_end(addr, end);
|
||||
if (create || !p4d_none_or_clear_bad(p4d)) {
|
||||
err = apply_to_pud_range(mm, p4d, addr, next, fn, data,
|
||||
create);
|
||||
create, mask);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -2331,8 +2338,9 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
|
||||
void *data, bool create)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
unsigned long next;
|
||||
unsigned long start = addr, next;
|
||||
unsigned long end = addr + size;
|
||||
pgtbl_mod_mask mask = 0;
|
||||
int err = 0;
|
||||
|
||||
if (WARN_ON(addr >= end))
|
||||
@@ -2343,11 +2351,14 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
|
||||
next = pgd_addr_end(addr, end);
|
||||
if (!create && pgd_none_or_clear_bad(pgd))
|
||||
continue;
|
||||
err = apply_to_p4d_range(mm, pgd, addr, next, fn, data, create);
|
||||
err = apply_to_p4d_range(mm, pgd, addr, next, fn, data, create, &mask);
|
||||
if (err)
|
||||
break;
|
||||
} while (pgd++, addr = next, addr != end);
|
||||
|
||||
if (mask & ARCH_PAGE_TABLE_SYNC_MASK)
|
||||
arch_sync_kernel_mappings(start, start + size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user