diff options
author | Alex Shi <alex.shi@linaro.org> | 2017-07-12 04:05:30 (GMT) |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2017-07-12 04:05:30 (GMT) |
commit | e3ab478de140512b21b8b081fb20874478b9599d (patch) | |
tree | 97267fbae2d7a4bf7493246b2b81020e8675fc55 /mm | |
parent | 78278fb152735c686cb13e1ae3bcee78fc2cd154 (diff) | |
parent | 9f86f302ec0e37e84617481c587e11c47a397e3f (diff) | |
download | linux-e3ab478de140512b21b8b081fb20874478b9599d.tar.xz |
Merge tag 'v4.9.36' into linux-linaro-lsk-v4.9
This is the 4.9.36 stable release
Diffstat (limited to 'mm')
-rw-r--r-- | mm/huge_memory.c | 6 | ||||
-rw-r--r-- | mm/swap_cgroup.c | 2 | ||||
-rw-r--r-- | mm/vmalloc.c | 14 |
3 files changed, 20 insertions, 2 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index d5b2b75..e7d5db9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1227,8 +1227,11 @@ int do_huge_pmd_numa_page(struct fault_env *fe, pmd_t pmd) */ if (unlikely(pmd_trans_migrating(*fe->pmd))) { page = pmd_page(*fe->pmd); + if (!get_page_unless_zero(page)) + goto out_unlock; spin_unlock(fe->ptl); wait_on_page_locked(page); + put_page(page); goto out; } @@ -1260,8 +1263,11 @@ int do_huge_pmd_numa_page(struct fault_env *fe, pmd_t pmd) /* Migration could have started since the pmd_trans_migrating check */ if (!page_locked) { + if (!get_page_unless_zero(page)) + goto out_unlock; spin_unlock(fe->ptl); wait_on_page_locked(page); + put_page(page); page_nid = -1; goto out; } diff --git a/mm/swap_cgroup.c b/mm/swap_cgroup.c index 454d6d7..3405b4e 100644 --- a/mm/swap_cgroup.c +++ b/mm/swap_cgroup.c @@ -204,6 +204,8 @@ void swap_cgroup_swapoff(int type) struct page *page = map[i]; if (page) __free_page(page); + if (!(i % SWAP_CLUSTER_MAX)) + cond_resched(); } vfree(map); } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index f2481cb..195de42 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -244,11 +244,21 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) */ VIRTUAL_BUG_ON(!is_vmalloc_or_module_addr(vmalloc_addr)); + /* + * Don't dereference bad PUD or PMD (below) entries. This will also + * identify huge mappings, which we may encounter on architectures + * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be + * identified as vmalloc addresses by is_vmalloc_addr(), but are + * not [unambiguously] associated with a struct page, so there is + * no correct value to return for them. + */ if (!pgd_none(*pgd)) { pud_t *pud = pud_offset(pgd, addr); - if (!pud_none(*pud)) { + WARN_ON_ONCE(pud_bad(*pud)); + if (!pud_none(*pud) && !pud_bad(*pud)) { pmd_t *pmd = pmd_offset(pud, addr); - if (!pmd_none(*pmd)) { + WARN_ON_ONCE(pmd_bad(*pmd)); + if (!pmd_none(*pmd) && !pmd_bad(*pmd)) { pte_t *ptep, pte; ptep = pte_offset_map(pmd, addr); |