Merge branch 'akpm' (patches from Andrew)
Merge misc updates from Andrew Morton: - large KASAN update to use arm's "software tag-based mode" - a few misc things - sh updates - ocfs2 updates - just about all of MM * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (167 commits) kernel/fork.c: mark 'stack_vm_area' with __maybe_unused memcg, oom: notify on oom killer invocation from the charge path mm, swap: fix swapoff with KSM pages include/linux/gfp.h: fix typo mm/hmm: fix memremap.h, move dev_page_fault_t callback to hmm hugetlbfs: Use i_mmap_rwsem to fix page fault/truncate race hugetlbfs: use i_mmap_rwsem for more pmd sharing synchronization memory_hotplug: add missing newlines to debugging output mm: remove __hugepage_set_anon_rmap() include/linux/vmstat.h: remove unused page state adjustment macro mm/page_alloc.c: allow error injection mm: migrate: drop unused argument of migrate_page_move_mapping() blkdev: avoid migration stalls for blkdev pages mm: migrate: provide buffer_migrate_page_norefs() mm: migrate: move migrate_page_lock_buffers() mm: migrate: lock buffers before migrate_page_move_mapping() mm: migration: factor out code to compute expected number of page references mm, page_alloc: enable pcpu_drain with zone capability kmemleak: add config to select auto scan mm/page_alloc.c: don't call kasan_free_pages() at deferred mem init ...
This commit is contained in:
@@ -2666,9 +2666,9 @@ void cpuset_print_current_mems_allowed(void)
|
||||
rcu_read_lock();
|
||||
|
||||
cgrp = task_cs(current)->css.cgroup;
|
||||
pr_info("%s cpuset=", current->comm);
|
||||
pr_cont(",cpuset=");
|
||||
pr_cont_cgroup_name(cgrp);
|
||||
pr_cont(" mems_allowed=%*pbl\n",
|
||||
pr_cont(",mems_allowed=%*pbl",
|
||||
nodemask_pr_args(¤t->mems_allowed));
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -171,11 +171,11 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
||||
.address = addr,
|
||||
};
|
||||
int err;
|
||||
/* For mmu_notifiers */
|
||||
const unsigned long mmun_start = addr;
|
||||
const unsigned long mmun_end = addr + PAGE_SIZE;
|
||||
struct mmu_notifier_range range;
|
||||
struct mem_cgroup *memcg;
|
||||
|
||||
mmu_notifier_range_init(&range, mm, addr, addr + PAGE_SIZE);
|
||||
|
||||
VM_BUG_ON_PAGE(PageTransHuge(old_page), old_page);
|
||||
|
||||
err = mem_cgroup_try_charge(new_page, vma->vm_mm, GFP_KERNEL, &memcg,
|
||||
@@ -186,7 +186,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
||||
/* For try_to_free_swap() and munlock_vma_page() below */
|
||||
lock_page(old_page);
|
||||
|
||||
mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
|
||||
mmu_notifier_invalidate_range_start(&range);
|
||||
err = -EAGAIN;
|
||||
if (!page_vma_mapped_walk(&pvmw)) {
|
||||
mem_cgroup_cancel_charge(new_page, memcg, false);
|
||||
@@ -220,7 +220,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
|
||||
|
||||
err = 0;
|
||||
unlock:
|
||||
mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
|
||||
mmu_notifier_invalidate_range_end(&range);
|
||||
unlock_page(old_page);
|
||||
return err;
|
||||
}
|
||||
|
||||
+4
-3
@@ -744,15 +744,16 @@ void __init __weak arch_task_cache_init(void) { }
|
||||
static void set_max_threads(unsigned int max_threads_suggested)
|
||||
{
|
||||
u64 threads;
|
||||
unsigned long nr_pages = totalram_pages();
|
||||
|
||||
/*
|
||||
* The number of threads shall be limited such that the thread
|
||||
* structures may only consume a small part of the available memory.
|
||||
*/
|
||||
if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64)
|
||||
if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64)
|
||||
threads = MAX_THREADS;
|
||||
else
|
||||
threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
|
||||
threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE,
|
||||
(u64) THREAD_SIZE * 8UL);
|
||||
|
||||
if (threads > max_threads_suggested)
|
||||
@@ -840,7 +841,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
unsigned long *stack;
|
||||
struct vm_struct *stack_vm_area;
|
||||
struct vm_struct *stack_vm_area __maybe_unused;
|
||||
int err;
|
||||
|
||||
if (node == NUMA_NO_NODE)
|
||||
|
||||
+3
-2
@@ -152,6 +152,7 @@ int sanity_check_segment_list(struct kimage *image)
|
||||
int i;
|
||||
unsigned long nr_segments = image->nr_segments;
|
||||
unsigned long total_pages = 0;
|
||||
unsigned long nr_pages = totalram_pages();
|
||||
|
||||
/*
|
||||
* Verify we have good destination addresses. The caller is
|
||||
@@ -217,13 +218,13 @@ int sanity_check_segment_list(struct kimage *image)
|
||||
* wasted allocating pages, which can cause a soft lockup.
|
||||
*/
|
||||
for (i = 0; i < nr_segments; i++) {
|
||||
if (PAGE_COUNT(image->segment[i].memsz) > totalram_pages / 2)
|
||||
if (PAGE_COUNT(image->segment[i].memsz) > nr_pages / 2)
|
||||
return -EINVAL;
|
||||
|
||||
total_pages += PAGE_COUNT(image->segment[i].memsz);
|
||||
}
|
||||
|
||||
if (total_pages > totalram_pages / 2)
|
||||
if (total_pages > nr_pages / 2)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
||||
+67
-36
@@ -11,6 +11,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/wait_bit.h>
|
||||
#include <linux/xarray.h>
|
||||
#include <linux/hmm.h>
|
||||
|
||||
static DEFINE_XARRAY(pgmap_array);
|
||||
#define SECTION_MASK ~((1UL << PA_SECTION_SHIFT) - 1)
|
||||
@@ -24,6 +25,9 @@ vm_fault_t device_private_entry_fault(struct vm_area_struct *vma,
|
||||
pmd_t *pmdp)
|
||||
{
|
||||
struct page *page = device_private_entry_to_page(entry);
|
||||
struct hmm_devmem *devmem;
|
||||
|
||||
devmem = container_of(page->pgmap, typeof(*devmem), pagemap);
|
||||
|
||||
/*
|
||||
* The page_fault() callback must migrate page back to system memory
|
||||
@@ -39,7 +43,7 @@ vm_fault_t device_private_entry_fault(struct vm_area_struct *vma,
|
||||
* There is a more in-depth description of what that callback can and
|
||||
* cannot do, in include/linux/memremap.h
|
||||
*/
|
||||
return page->pgmap->page_fault(vma, addr, page, flags, pmdp);
|
||||
return devmem->page_fault(vma, addr, page, flags, pmdp);
|
||||
}
|
||||
EXPORT_SYMBOL(device_private_entry_fault);
|
||||
#endif /* CONFIG_DEVICE_PRIVATE */
|
||||
@@ -87,24 +91,29 @@ static void devm_memremap_pages_release(void *data)
|
||||
struct resource *res = &pgmap->res;
|
||||
resource_size_t align_start, align_size;
|
||||
unsigned long pfn;
|
||||
int nid;
|
||||
|
||||
pgmap->kill(pgmap->ref);
|
||||
for_each_device_pfn(pfn, pgmap)
|
||||
put_page(pfn_to_page(pfn));
|
||||
|
||||
if (percpu_ref_tryget_live(pgmap->ref)) {
|
||||
dev_WARN(dev, "%s: page mapping is still live!\n", __func__);
|
||||
percpu_ref_put(pgmap->ref);
|
||||
}
|
||||
|
||||
/* pages are dead and unused, undo the arch mapping */
|
||||
align_start = res->start & ~(SECTION_SIZE - 1);
|
||||
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
|
||||
- align_start;
|
||||
|
||||
nid = page_to_nid(pfn_to_page(align_start >> PAGE_SHIFT));
|
||||
|
||||
mem_hotplug_begin();
|
||||
arch_remove_memory(align_start, align_size, pgmap->altmap_valid ?
|
||||
&pgmap->altmap : NULL);
|
||||
kasan_remove_zero_shadow(__va(align_start), align_size);
|
||||
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
|
||||
pfn = align_start >> PAGE_SHIFT;
|
||||
__remove_pages(page_zone(pfn_to_page(pfn)), pfn,
|
||||
align_size >> PAGE_SHIFT, NULL);
|
||||
} else {
|
||||
arch_remove_memory(nid, align_start, align_size,
|
||||
pgmap->altmap_valid ? &pgmap->altmap : NULL);
|
||||
kasan_remove_zero_shadow(__va(align_start), align_size);
|
||||
}
|
||||
mem_hotplug_done();
|
||||
|
||||
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
|
||||
@@ -116,7 +125,7 @@ static void devm_memremap_pages_release(void *data)
|
||||
/**
|
||||
* devm_memremap_pages - remap and provide memmap backing for the given resource
|
||||
* @dev: hosting device for @res
|
||||
* @pgmap: pointer to a struct dev_pgmap
|
||||
* @pgmap: pointer to a struct dev_pagemap
|
||||
*
|
||||
* Notes:
|
||||
* 1/ At a minimum the res, ref and type members of @pgmap must be initialized
|
||||
@@ -125,11 +134,8 @@ static void devm_memremap_pages_release(void *data)
|
||||
* 2/ The altmap field may optionally be initialized, in which case altmap_valid
|
||||
* must be set to true
|
||||
*
|
||||
* 3/ pgmap.ref must be 'live' on entry and 'dead' before devm_memunmap_pages()
|
||||
* time (or devm release event). The expected order of events is that ref has
|
||||
* been through percpu_ref_kill() before devm_memremap_pages_release(). The
|
||||
* wait for the completion of all references being dropped and
|
||||
* percpu_ref_exit() must occur after devm_memremap_pages_release().
|
||||
* 3/ pgmap->ref must be 'live' on entry and will be killed at
|
||||
* devm_memremap_pages_release() time, or if this routine fails.
|
||||
*
|
||||
* 4/ res is expected to be a host memory range that could feasibly be
|
||||
* treated as a "System RAM" range, i.e. not a device mmio range, but
|
||||
@@ -145,6 +151,9 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||
pgprot_t pgprot = PAGE_KERNEL;
|
||||
int error, nid, is_ram;
|
||||
|
||||
if (!pgmap->ref || !pgmap->kill)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
align_start = res->start & ~(SECTION_SIZE - 1);
|
||||
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
|
||||
- align_start;
|
||||
@@ -167,18 +176,13 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||
is_ram = region_intersects(align_start, align_size,
|
||||
IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
|
||||
|
||||
if (is_ram == REGION_MIXED) {
|
||||
WARN_ONCE(1, "%s attempted on mixed region %pr\n",
|
||||
__func__, res);
|
||||
return ERR_PTR(-ENXIO);
|
||||
if (is_ram != REGION_DISJOINT) {
|
||||
WARN_ONCE(1, "%s attempted on %s region %pr\n", __func__,
|
||||
is_ram == REGION_MIXED ? "mixed" : "ram", res);
|
||||
error = -ENXIO;
|
||||
goto err_array;
|
||||
}
|
||||
|
||||
if (is_ram == REGION_INTERSECTS)
|
||||
return __va(res->start);
|
||||
|
||||
if (!pgmap->ref)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pgmap->dev = dev;
|
||||
|
||||
error = xa_err(xa_store_range(&pgmap_array, PHYS_PFN(res->start),
|
||||
@@ -196,17 +200,40 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||
goto err_pfn_remap;
|
||||
|
||||
mem_hotplug_begin();
|
||||
error = kasan_add_zero_shadow(__va(align_start), align_size);
|
||||
if (error) {
|
||||
mem_hotplug_done();
|
||||
goto err_kasan;
|
||||
|
||||
/*
|
||||
* For device private memory we call add_pages() as we only need to
|
||||
* allocate and initialize struct page for the device memory. More-
|
||||
* over the device memory is un-accessible thus we do not want to
|
||||
* create a linear mapping for the memory like arch_add_memory()
|
||||
* would do.
|
||||
*
|
||||
* For all other device memory types, which are accessible by
|
||||
* the CPU, we do want the linear mapping and thus use
|
||||
* arch_add_memory().
|
||||
*/
|
||||
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
|
||||
error = add_pages(nid, align_start >> PAGE_SHIFT,
|
||||
align_size >> PAGE_SHIFT, NULL, false);
|
||||
} else {
|
||||
error = kasan_add_zero_shadow(__va(align_start), align_size);
|
||||
if (error) {
|
||||
mem_hotplug_done();
|
||||
goto err_kasan;
|
||||
}
|
||||
|
||||
error = arch_add_memory(nid, align_start, align_size, altmap,
|
||||
false);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
struct zone *zone;
|
||||
|
||||
zone = &NODE_DATA(nid)->node_zones[ZONE_DEVICE];
|
||||
move_pfn_range_to_zone(zone, align_start >> PAGE_SHIFT,
|
||||
align_size >> PAGE_SHIFT, altmap);
|
||||
}
|
||||
|
||||
error = arch_add_memory(nid, align_start, align_size, altmap, false);
|
||||
if (!error)
|
||||
move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
|
||||
align_start >> PAGE_SHIFT,
|
||||
align_size >> PAGE_SHIFT, altmap);
|
||||
mem_hotplug_done();
|
||||
if (error)
|
||||
goto err_add_memory;
|
||||
@@ -220,7 +247,10 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||
align_size >> PAGE_SHIFT, pgmap);
|
||||
percpu_ref_get_many(pgmap->ref, pfn_end(pgmap) - pfn_first(pgmap));
|
||||
|
||||
devm_add_action(dev, devm_memremap_pages_release, pgmap);
|
||||
error = devm_add_action_or_reset(dev, devm_memremap_pages_release,
|
||||
pgmap);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
|
||||
return __va(res->start);
|
||||
|
||||
@@ -231,9 +261,10 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
||||
err_pfn_remap:
|
||||
pgmap_array_delete(res);
|
||||
err_array:
|
||||
pgmap->kill(pgmap->ref);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
EXPORT_SYMBOL(devm_memremap_pages);
|
||||
EXPORT_SYMBOL_GPL(devm_memremap_pages);
|
||||
|
||||
unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
|
||||
{
|
||||
|
||||
@@ -105,7 +105,7 @@ unsigned long image_size;
|
||||
|
||||
void __init hibernate_image_size_init(void)
|
||||
{
|
||||
image_size = ((totalram_pages * 2) / 5) * PAGE_SIZE;
|
||||
image_size = ((totalram_pages() * 2) / 5) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1256,6 +1256,21 @@ int release_mem_region_adjustable(struct resource *parent,
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* All memory regions added from memory-hotplug path have the
|
||||
* flag IORESOURCE_SYSTEM_RAM. If the resource does not have
|
||||
* this flag, we know that we are dealing with a resource coming
|
||||
* from HMM/devm. HMM/devm use another mechanism to add/release
|
||||
* a resource. This goes via devm_request_mem_region and
|
||||
* devm_release_mem_region.
|
||||
* HMM/devm take care to release their resources when they want,
|
||||
* so if we are dealing with them, let us just back off here.
|
||||
*/
|
||||
if (!(res->flags & IORESOURCE_SYSRAM)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(res->flags & IORESOURCE_MEM))
|
||||
break;
|
||||
|
||||
|
||||
@@ -1462,6 +1462,14 @@ static struct ctl_table vm_table[] = {
|
||||
.proc_handler = min_free_kbytes_sysctl_handler,
|
||||
.extra1 = &zero,
|
||||
},
|
||||
{
|
||||
.procname = "watermark_boost_factor",
|
||||
.data = &watermark_boost_factor,
|
||||
.maxlen = sizeof(watermark_boost_factor),
|
||||
.mode = 0644,
|
||||
.proc_handler = watermark_boost_factor_sysctl_handler,
|
||||
.extra1 = &zero,
|
||||
},
|
||||
{
|
||||
.procname = "watermark_scale_factor",
|
||||
.data = &watermark_scale_factor,
|
||||
|
||||
Reference in New Issue
Block a user