summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2018-06-01 19:53:16 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2018-06-01 19:53:16 +1000
commit8924e611277fbbfd3376e6d794c226b3856e296f (patch)
treedeb8a2c0c0da1684df61657ad917629bd3b46a50
parent8a7cb75e61d8d47e5c3f696d47de049a90923cbf (diff)
parent00105f98ec0f3e1d93c29460602427c650f6984c (diff)
Merge branch 'akpm/master'
-rw-r--r--arch/arm64/mm/init.c6
-rw-r--r--arch/hexagon/include/asm/pgtable.h1
-rw-r--r--arch/hexagon/kernel/setup.c2
-rw-r--r--arch/hexagon/mm/init.c3
-rw-r--r--arch/mips/kernel/setup.c4
-rw-r--r--arch/powerpc/mm/mem.c2
-rw-r--r--arch/sparc/lib/NG4memset.S26
-rw-r--r--arch/sparc/mm/init_64.c2
-rw-r--r--arch/x86/mm/init_32.c2
-rw-r--r--arch/x86/mm/init_64.c2
-rw-r--r--drivers/firmware/efi/arm-init.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-ipc.c4
-rw-r--r--drivers/remoteproc/qcom_q6v5_pil.c2
-rw-r--r--drivers/soc/qcom/mdt_loader.c4
-rw-r--r--include/linux/ioport.h3
-rw-r--r--include/linux/memcontrol.h26
-rw-r--r--kernel/kexec_file.c2
-rw-r--r--kernel/resource.c63
-rw-r--r--mm/cleancache.c10
-rw-r--r--mm/cma_debug.c25
-rw-r--r--mm/compaction.c2
-rw-r--r--mm/dmapool.c2
-rw-r--r--mm/failslab.c2
-rw-r--r--mm/frontswap.c11
-rw-r--r--mm/memblock.c9
-rw-r--r--mm/memcontrol.c35
-rw-r--r--mm/oom_kill.c2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/page_idle.c2
-rw-r--r--mm/page_owner.c4
-rw-r--r--mm/shmem.c9
-rw-r--r--mm/slab_common.c4
-rw-r--r--mm/vmalloc.c4
-rw-r--r--mm/zsmalloc.c5
-rw-r--r--mm/zswap.c38
-rw-r--r--tools/testing/selftests/cgroup/test_memcontrol.c115
36 files changed, 322 insertions, 115 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1b18b4722420..325cfb3b858a 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -310,7 +310,7 @@ static void __init arm64_memory_present(void)
}
#endif
-static phys_addr_t memory_limit = (phys_addr_t)ULLONG_MAX;
+static phys_addr_t memory_limit = PHYS_ADDR_MAX;
/*
* Limit the memory size that was specified via FDT.
@@ -401,7 +401,7 @@ void __init arm64_memblock_init(void)
* high up in memory, add back the kernel region that must be accessible
* via the linear mapping.
*/
- if (memory_limit != (phys_addr_t)ULLONG_MAX) {
+ if (memory_limit != PHYS_ADDR_MAX) {
memblock_mem_limit_remove_map(memory_limit);
memblock_add(__pa_symbol(_text), (u64)(_end - _text));
}
@@ -666,7 +666,7 @@ __setup("keepinitrd", keepinitrd_setup);
*/
static int dump_mem_limit(struct notifier_block *self, unsigned long v, void *p)
{
- if (memory_limit != (phys_addr_t)ULLONG_MAX) {
+ if (memory_limit != PHYS_ADDR_MAX) {
pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20);
} else {
pr_emerg("Memory Limit: none\n");
diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h
index aef02f7ca8aa..65125d0b02dd 100644
--- a/arch/hexagon/include/asm/pgtable.h
+++ b/arch/hexagon/include/asm/pgtable.h
@@ -30,7 +30,6 @@
/* A handy thing to have if one has the RAM. Declared in head.S */
extern unsigned long empty_zero_page;
-extern unsigned long zero_page_mask;
/*
* The PTE model described here is that of the Hexagon Virtual Machine,
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 6981949f5df3..dc8c7e75b5d1 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -66,7 +66,7 @@ void __init setup_arch(char **cmdline_p)
*/
__vmsetvec(_K_VM_event_vector);
- printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET);
+ printk(KERN_INFO "PHYS_OFFSET=0x%08lx\n", PHYS_OFFSET);
/*
* Simulator has a few differences from the hardware.
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index 192584d5ac2f..1495d45e472d 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -39,9 +39,6 @@ unsigned long __phys_offset; /* physical kernel offset >> 12 */
/* Set as variable to limit PMD copies */
int max_kernel_seg = 0x303;
-/* think this should be (page_size-1) the way it's used...*/
-unsigned long zero_page_mask;
-
/* indicate pfn's of high memory */
unsigned long highstart_pfn, highend_pfn;
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 563188ac6fa2..2c96c0c68116 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -93,7 +93,7 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
* If the region reaches the top of the physical address space, adjust
* the size slightly so that (start + size) doesn't overflow
*/
- if (start + size - 1 == (phys_addr_t)ULLONG_MAX)
+ if (start + size - 1 == PHYS_ADDR_MAX)
--size;
/* Sanity check */
@@ -376,7 +376,7 @@ static void __init bootmem_init(void)
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
- phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX;
+ phys_addr_t ramstart = PHYS_ADDR_MAX;
bool bootmap_valid = false;
int i;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c3c39b02b2ba..404fb6cba3ff 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -215,7 +215,7 @@ void __init mem_topology_setup(void)
/* Place all memblock_regions in the same node and merge contiguous
* memblock_regions
*/
- memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
}
void __init initmem_init(void)
diff --git a/arch/sparc/lib/NG4memset.S b/arch/sparc/lib/NG4memset.S
index f81ee5419e2c..d0c4d195fd40 100644
--- a/arch/sparc/lib/NG4memset.S
+++ b/arch/sparc/lib/NG4memset.S
@@ -14,14 +14,14 @@
.globl NG4memset
NG4memset:
andcc %o1, 0xff, %o4
- be,pt %icc, 1f
+ be,pt %xcc, 1f
mov %o2, %o1
sllx %o4, 8, %g1
or %g1, %o4, %o2
sllx %o2, 16, %g1
or %g1, %o2, %o2
sllx %o2, 32, %g1
- ba,pt %icc, 1f
+ ba,pt %xcc, 1f
or %g1, %o2, %o4
.size NG4memset,.-NG4memset
@@ -30,7 +30,7 @@ NG4memset:
NG4bzero:
clr %o4
1: cmp %o1, 16
- ble %icc, .Ltiny
+ ble %xcc, .Ltiny
mov %o0, %o3
sub %g0, %o0, %g1
and %g1, 0x7, %g1
@@ -38,7 +38,7 @@ NG4bzero:
sub %o1, %g1, %o1
1: stb %o4, [%o0 + 0x00]
subcc %g1, 1, %g1
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 1, %o0
.Laligned8:
cmp %o1, 64 + (64 - 8)
@@ -49,7 +49,7 @@ NG4bzero:
sub %o1, %g1, %o1
1: stx %o4, [%o0 + 0x00]
subcc %g1, 8, %g1
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 0x8, %o0
.Laligned64:
andn %o1, 64 - 1, %g1
@@ -59,30 +59,30 @@ NG4bzero:
1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
subcc %g1, 0x40, %g1
stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 0x40, %o0
.Lpostloop:
cmp %o1, 8
- bl,pn %icc, .Ltiny
+ bl,pn %xcc, .Ltiny
membar #StoreStore|#StoreLoad
.Lmedium:
andn %o1, 0x7, %g1
sub %o1, %g1, %o1
1: stx %o4, [%o0 + 0x00]
subcc %g1, 0x8, %g1
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 0x08, %o0
andcc %o1, 0x4, %g1
- be,pt %icc, .Ltiny
+ be,pt %xcc, .Ltiny
sub %o1, %g1, %o1
stw %o4, [%o0 + 0x00]
add %o0, 0x4, %o0
.Ltiny:
cmp %o1, 0
- be,pn %icc, .Lexit
+ be,pn %xcc, .Lexit
1: subcc %o1, 1, %o1
stb %o4, [%o0 + 0x00]
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 1, %o0
.Lexit:
retl
@@ -100,8 +100,8 @@ NG4bzero:
stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
- bne,pt %icc, 1b
+ bne,pt %xcc, 1b
add %o0, 0x30, %o0
- ba,a,pt %icc, .Lpostloop
+ ba,a,pt %xcc, .Lpostloop
nop
.size NG4bzero,.-NG4bzero
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 8aeb1aabe76e..f396048a0d68 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1620,7 +1620,7 @@ static void __init bootmem_init_nonnuma(void)
(top_of_ram - total_ram) >> 20);
init_node_masks_nonnuma();
- memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
allocate_node_data(0);
node_set_online(0);
}
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index c893c6a3d707..979e0a02cbe1 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -692,7 +692,7 @@ void __init initmem_init(void)
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
#endif
- memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
sparse_memory_present_with_active_regions(0);
#ifdef CONFIG_FLATMEM
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 0a400606dea0..765a50fb6364 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -742,7 +742,7 @@ kernel_physical_mapping_init(unsigned long paddr_start,
#ifndef CONFIG_NUMA
void __init initmem_init(void)
{
- memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
}
#endif
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 80d1a885def5..b5214c143fee 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -193,7 +193,7 @@ static __init void reserve_regions(void)
* uses its own memory map instead.
*/
memblock_dump_all();
- memblock_remove(0, (phys_addr_t)ULLONG_MAX);
+ memblock_remove(0, PHYS_ADDR_MAX);
for_each_efi_memory_desc(md) {
paddr = md->phys_addr;
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c
index a4603d573c34..bd1bbbeedec3 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.c
+++ b/drivers/media/platform/sti/delta/delta-ipc.c
@@ -175,8 +175,8 @@ int delta_ipc_open(struct delta_ctx *pctx, const char *name,
msg.ipc_buf_size = ipc_buf_size;
msg.ipc_buf_paddr = ctx->ipc_buf->paddr;
- memcpy(msg.name, name, sizeof(msg.name));
- msg.name[sizeof(msg.name) - 1] = 0;
+ memset(msg.name, 0, sizeof(msg.name));
+ strcpy(msg.name, name);
msg.param_size = param->size;
memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 2190debf3d35..2bf8e7c49f2a 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -686,7 +686,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
struct elf32_hdr *ehdr;
phys_addr_t mpss_reloc;
phys_addr_t boot_addr;
- phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
+ phys_addr_t min_addr = PHYS_ADDR_MAX;
phys_addr_t max_addr = 0;
bool relocate = false;
char seg_name[10];
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index 17b314d9a148..dc09d7ac905f 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -50,7 +50,7 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
const struct elf32_hdr *ehdr;
- phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
+ phys_addr_t min_addr = PHYS_ADDR_MAX;
phys_addr_t max_addr = 0;
int i;
@@ -97,7 +97,7 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const struct elf32_hdr *ehdr;
const struct firmware *seg_fw;
phys_addr_t mem_reloc;
- phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
+ phys_addr_t min_addr = PHYS_ADDR_MAX;
phys_addr_t max_addr = 0;
size_t fw_name_len;
ssize_t offset;
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..f12d95fe038b 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -277,6 +277,9 @@ extern int
walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *));
+extern int
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
void *arg, int (*func)(struct resource *, void *));
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 808cdb7056ef..7292de2d361b 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -54,6 +54,7 @@ enum memcg_memory_event {
MEMCG_HIGH,
MEMCG_MAX,
MEMCG_OOM,
+ MEMCG_OOM_KILL,
MEMCG_SWAP_MAX,
MEMCG_SWAP_FAIL,
MEMCG_NR_MEMORY_EVENTS,
@@ -731,11 +732,8 @@ static inline void count_memcg_event_mm(struct mm_struct *mm,
rcu_read_lock();
memcg = rcu_dereference(mm->memcg);
- if (likely(memcg)) {
+ if (likely(memcg))
count_memcg_events(memcg, idx, 1);
- if (idx == OOM_KILL)
- cgroup_file_notify(&memcg->events_file);
- }
rcu_read_unlock();
}
@@ -746,6 +744,21 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg,
cgroup_file_notify(&memcg->events_file);
}
+static inline void memcg_memory_event_mm(struct mm_struct *mm,
+ enum memcg_memory_event event)
+{
+ struct mem_cgroup *memcg;
+
+ if (mem_cgroup_disabled())
+ return;
+
+ rcu_read_lock();
+ memcg = rcu_dereference(mm->memcg);
+ if (likely(memcg))
+ memcg_memory_event(memcg, event);
+ rcu_read_unlock();
+}
+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
void mem_cgroup_split_huge_fixup(struct page *head);
#endif
@@ -767,6 +780,11 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg,
{
}
+static inline void memcg_memory_event_mm(struct mm_struct *mm,
+ enum memcg_memory_event event)
+{
+}
+
static inline enum mem_cgroup_protection mem_cgroup_protected(
struct mem_cgroup *root, struct mem_cgroup *memcg)
{
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 75d8e7cf040e..7a66d9d5a534 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -518,6 +518,8 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
crashk_res.start, crashk_res.end,
kbuf, func);
+ else if (kbuf->top_down)
+ return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func);
else
return walk_system_ram_res(0, ULONG_MAX, kbuf, func);
}
diff --git a/kernel/resource.c b/kernel/resource.c
index b589dda910b3..b3c2613559d4 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,6 +23,8 @@
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/resource_ext.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -437,6 +439,67 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
}
/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *))
+{
+ struct resource res, *rams;
+ int rams_size = 16, i;
+ int ret = -1;
+
+ /* create a list */
+ rams = vmalloc(sizeof(struct resource) * rams_size);
+ if (!rams)
+ return ret;
+
+ res.start = start;
+ res.end = end;
+ res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+ i = 0;
+ while ((res.start < res.end) &&
+ (!find_next_iomem_res(&res, IORES_DESC_NONE, true))) {
+ if (i >= rams_size) {
+ /* re-alloc */
+ struct resource *rams_new;
+ int rams_new_size;
+
+ rams_new_size = rams_size + 16;
+ rams_new = vmalloc(sizeof(struct resource)
+ * rams_new_size);
+ if (!rams_new)
+ goto out;
+
+ memcpy(rams_new, rams,
+ sizeof(struct resource) * rams_size);
+ vfree(rams);
+ rams = rams_new;
+ rams_size = rams_new_size;
+ }
+
+ rams[i].start = res.start;
+ rams[i++].end = res.end;
+
+ res.start = res.end + 1;
+ res.end = end;
+ }
+
+ /* go reverse */
+ for (i--; i >= 0; i--) {
+ ret = (*func)(&rams[i], arg);
+ if (ret)
+ break;
+ }
+
+out:
+ vfree(rams);
+ return ret;
+}
+
+/*
* This function calls the @func callback against all memory ranges, which
* are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
*/
diff --git a/mm/cleancache.c b/mm/cleancache.c
index 126548b5a292..2bf12da9baa0 100644
--- a/mm/cleancache.c
+++ b/mm/cleancache.c
@@ -307,12 +307,10 @@ static int __init init_cleancache(void)
struct dentry *root = debugfs_create_dir("cleancache", NULL);
if (root == NULL)
return -ENXIO;
- debugfs_create_u64("succ_gets", S_IRUGO, root, &cleancache_succ_gets);
- debugfs_create_u64("failed_gets", S_IRUGO,
- root, &cleancache_failed_gets);
- debugfs_create_u64("puts", S_IRUGO, root, &cleancache_puts);
- debugfs_create_u64("invalidates", S_IRUGO,
- root, &cleancache_invalidates);
+ debugfs_create_u64("succ_gets", 0444, root, &cleancache_succ_gets);
+ debugfs_create_u64("failed_gets", 0444, root, &cleancache_failed_gets);
+ debugfs_create_u64("puts", 0444, root, &cleancache_puts);
+ debugfs_create_u64("invalidates", 0444, root, &cleancache_invalidates);
#endif
return 0;
}
diff --git a/mm/cma_debug.c b/mm/cma_debug.c
index 275df8b5b22e..f23467291cfb 100644
--- a/mm/cma_debug.c
+++ b/mm/cma_debug.c
@@ -172,23 +172,18 @@ static void cma_debugfs_add_one(struct cma *cma, int idx)
tmp = debugfs_create_dir(name, cma_debugfs_root);
- debugfs_create_file("alloc", S_IWUSR, tmp, cma,
- &cma_alloc_fops);
-
- debugfs_create_file("free", S_IWUSR, tmp, cma,
- &cma_free_fops);
-
- debugfs_create_file("base_pfn", S_IRUGO, tmp,
- &cma->base_pfn, &cma_debugfs_fops);
- debugfs_create_file("count", S_IRUGO, tmp,
- &cma->count, &cma_debugfs_fops);
- debugfs_create_file("order_per_bit", S_IRUGO, tmp,
- &cma->order_per_bit, &cma_debugfs_fops);
- debugfs_create_file("used", S_IRUGO, tmp, cma, &cma_used_fops);
- debugfs_create_file("maxchunk", S_IRUGO, tmp, cma, &cma_maxchunk_fops);
+ debugfs_create_file("alloc", 0200, tmp, cma, &cma_alloc_fops);
+ debugfs_create_file("free", 0200, tmp, cma, &cma_free_fops);
+ debugfs_create_file("base_pfn", 0444, tmp,
+ &cma->base_pfn, &cma_debugfs_fops);
+ debugfs_create_file("count", 0444, tmp, &cma->count, &cma_debugfs_fops);
+ debugfs_create_file("order_per_bit", 0444, tmp,
+ &cma->order_per_bit, &cma_debugfs_fops);
+ debugfs_create_file("used", 0444, tmp, cma, &cma_used_fops);
+ debugfs_create_file("maxchunk", 0444, tmp, cma, &cma_maxchunk_fops);
u32s = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32));
- debugfs_create_u32_array("bitmap", S_IRUGO, tmp, (u32*)cma->bitmap, u32s);
+ debugfs_create_u32_array("bitmap", 0444, tmp, (u32 *)cma->bitmap, u32s);
}
static int __init cma_debugfs_init(void)
diff --git a/mm/compaction.c b/mm/compaction.c
index 29bd1df18b98..faca45ebe62d 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1899,7 +1899,7 @@ static ssize_t sysfs_compact_node(struct device *dev,
return count;
}
-static DEVICE_ATTR(compact, S_IWUSR, NULL, sysfs_compact_node);
+static DEVICE_ATTR(compact, 0200, NULL, sysfs_compact_node);
int compaction_register_node(struct node *node)
{
diff --git a/mm/dmapool.c b/mm/dmapool.c
index 4d90a64b2fdc..6d4b97e7e9e9 100644
--- a/mm/dmapool.c
+++ b/mm/dmapool.c
@@ -105,7 +105,7 @@ show_pools(struct device *dev, struct device_attribute *attr, char *buf)
return PAGE_SIZE - size;
}
-static DEVICE_ATTR(pools, S_IRUGO, show_pools, NULL);
+static DEVICE_ATTR(pools, 0444, show_pools, NULL);
/**
* dma_pool_create - Creates a pool of consistent memory blocks, for dma.
diff --git a/mm/failslab.c b/mm/failslab.c
index 1f2f248e3601..b135ebb88b6f 100644
--- a/mm/failslab.c
+++ b/mm/failslab.c
@@ -42,7 +42,7 @@ __setup("failslab=", setup_failslab);
static int __init failslab_debugfs_init(void)
{
struct dentry *dir;
- umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+ umode_t mode = S_IFREG | 0600;
dir = fault_create_debugfs_attr("failslab", NULL, &failslab.attr);
if (IS_ERR(dir))
diff --git a/mm/frontswap.c b/mm/frontswap.c
index 4f5476a0f955..157e5bf63504 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -486,12 +486,11 @@ static int __init init_frontswap(void)
struct dentry *root = debugfs_create_dir("frontswap", NULL);
if (root == NULL)
return -ENXIO;
- debugfs_create_u64("loads", S_IRUGO, root, &frontswap_loads);
- debugfs_create_u64("succ_stores", S_IRUGO, root, &frontswap_succ_stores);
- debugfs_create_u64("failed_stores", S_IRUGO, root,
- &frontswap_failed_stores);
- debugfs_create_u64("invalidates", S_IRUGO,
- root, &frontswap_invalidates);
+ debugfs_create_u64("loads", 0444, root, &frontswap_loads);
+ debugfs_create_u64("succ_stores", 0444, root, &frontswap_succ_stores);
+ debugfs_create_u64("failed_stores", 0444, root,
+ &frontswap_failed_stores);
+ debugfs_create_u64("invalidates", 0444, root, &frontswap_invalidates);
#endif
return 0;
}
diff --git a/mm/memblock.c b/mm/memblock.c
index 93ad42bc8a73..03d48d8835ba 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1808,10 +1808,13 @@ static int __init memblock_init_debugfs(void)
struct dentry *root = debugfs_create_dir("memblock", NULL);
if (!root)
return -ENXIO;
- debugfs_create_file("memory", S_IRUGO, root, &memblock.memory, &memblock_debug_fops);
- debugfs_create_file("reserved", S_IRUGO, root, &memblock.reserved, &memblock_debug_fops);
+ debugfs_create_file("memory", 0444, root,
+ &memblock.memory, &memblock_debug_fops);
+ debugfs_create_file("reserved", 0444, root,
+ &memblock.reserved, &memblock_debug_fops);
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
- debugfs_create_file("physmem", S_IRUGO, root, &memblock.physmem, &memblock_debug_fops);
+ debugfs_create_file("physmem", 0444, root,
+ &memblock.physmem, &memblock_debug_fops);
#endif
return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 537ab73caf72..79e5d8733c90 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3802,7 +3802,8 @@ static int mem_cgroup_oom_control_read(struct seq_file *sf, void *v)
seq_printf(sf, "oom_kill_disable %d\n", memcg->oom_kill_disable);
seq_printf(sf, "under_oom %d\n", (bool)memcg->under_oom);
- seq_printf(sf, "oom_kill %lu\n", memcg_sum_events(memcg, OOM_KILL));
+ seq_printf(sf, "oom_kill %lu\n",
+ atomic_long_read(&memcg->memory_events[MEMCG_OOM_KILL]));
return 0;
}
@@ -5396,7 +5397,7 @@ static int memory_min_show(struct seq_file *m, void *v)
static ssize_t memory_min_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{
- struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+ struct mem_cgroup *iter, *memcg = mem_cgroup_from_css(of_css(of));
unsigned long min;
int err;
@@ -5407,6 +5408,11 @@ static ssize_t memory_min_write(struct kernfs_open_file *of,
page_counter_set_min(&memcg->memory, min);
+ rcu_read_lock();
+ for_each_mem_cgroup_tree(iter, memcg)
+ mem_cgroup_protected(NULL, iter);
+ rcu_read_unlock();
+
return nbytes;
}
@@ -5426,7 +5432,7 @@ static int memory_low_show(struct seq_file *m, void *v)
static ssize_t memory_low_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{
- struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+ struct mem_cgroup *iter, *memcg = mem_cgroup_from_css(of_css(of));
unsigned long low;
int err;
@@ -5437,6 +5443,11 @@ static ssize_t memory_low_write(struct kernfs_open_file *of,
page_counter_set_low(&memcg->memory, low);
+ rcu_read_lock();
+ for_each_mem_cgroup_tree(iter, memcg)
+ mem_cgroup_protected(NULL, iter);
+ rcu_read_unlock();
+
return nbytes;
}
@@ -5584,7 +5595,8 @@ static int memory_events_show(struct seq_file *m, void *v)
atomic_long_read(&memcg->memory_events[MEMCG_MAX]));
seq_printf(m, "oom %lu\n",
atomic_long_read(&memcg->memory_events[MEMCG_OOM]));
- seq_printf(m, "oom_kill %lu\n", memcg_sum_events(memcg, OOM_KILL));
+ seq_printf(m, "oom_kill %lu\n",
+ atomic_long_read(&memcg->memory_events[MEMCG_OOM_KILL]));
return 0;
}
@@ -5820,20 +5832,15 @@ enum mem_cgroup_protection mem_cgroup_protected(struct mem_cgroup *root,
if (mem_cgroup_disabled())
return MEMCG_PROT_NONE;
- if (!root)
- root = root_mem_cgroup;
- if (memcg == root)
+ if (memcg == root_mem_cgroup)
return MEMCG_PROT_NONE;
usage = page_counter_read(&memcg->memory);
- if (!usage)
- return MEMCG_PROT_NONE;
-
emin = memcg->memory.min;
elow = memcg->memory.low;
parent = parent_mem_cgroup(memcg);
- if (parent == root)
+ if (parent == root_mem_cgroup)
goto exit;
parent_emin = READ_ONCE(parent->memory.emin);
@@ -5868,6 +5875,12 @@ exit:
memcg->memory.emin = emin;
memcg->memory.elow = elow;
+ if (root && memcg == root)
+ return MEMCG_PROT_NONE;
+
+ if (!usage)
+ return MEMCG_PROT_NONE;
+
if (usage <= emin)
return MEMCG_PROT_MIN;
else if (usage <= elow)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 310babe45e93..565e7da55318 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -888,7 +888,7 @@ static void __oom_kill_process(struct task_struct *victim)
/* Raise event before sending signal: task reaper must see this */
count_vm_event(OOM_KILL);
- count_memcg_event_mm(mm, OOM_KILL);
+ memcg_memory_event_mm(mm, MEMCG_OOM_KILL);
/*
* We should send SIGKILL before granting access to memory reserves
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ccf80e97181a..1772513358e9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3061,7 +3061,7 @@ static bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
static int __init fail_page_alloc_debugfs(void)
{
- umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+ umode_t mode = S_IFREG | 0600;
struct dentry *dir;
dir = fault_create_debugfs_attr("fail_page_alloc", NULL,
diff --git a/mm/page_idle.c b/mm/page_idle.c
index e412a63b2b74..6302bc62c27d 100644
--- a/mm/page_idle.c
+++ b/mm/page_idle.c
@@ -201,7 +201,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
}
static struct bin_attribute page_idle_bitmap_attr =
- __BIN_ATTR(bitmap, S_IRUSR | S_IWUSR,
+ __BIN_ATTR(bitmap, 0600,
page_idle_bitmap_read, page_idle_bitmap_write, 0);
static struct bin_attribute *page_idle_bin_attrs[] = {
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 77d9e791ae8a..c2494f034d02 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -631,8 +631,8 @@ static int __init pageowner_init(void)
return 0;
}
- dentry = debugfs_create_file("page_owner", S_IRUSR, NULL,
- NULL, &proc_page_owner_operations);
+ dentry = debugfs_create_file("page_owner", 0400, NULL,
+ NULL, &proc_page_owner_operations);
return PTR_ERR_OR_ZERO(dentry);
}
diff --git a/mm/shmem.c b/mm/shmem.c
index 2b686e3f53ad..9a27f1cddeae 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3014,7 +3014,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
if (len > PAGE_SIZE)
return -ENAMETOOLONG;
- inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE);
+ inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK | 0777, 0,
+ VM_NORESERVE);
if (!inode)
return -ENOSPC;
@@ -3446,7 +3447,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root)
sbinfo->max_blocks << (PAGE_SHIFT - 10));
if (sbinfo->max_inodes != shmem_default_max_inodes())
seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
- if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
+ if (sbinfo->mode != (0777 | S_ISVTX))
seq_printf(seq, ",mode=%03ho", sbinfo->mode);
if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
seq_printf(seq, ",uid=%u",
@@ -3487,7 +3488,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
if (!sbinfo)
return -ENOMEM;
- sbinfo->mode = S_IRWXUGO | S_ISVTX;
+ sbinfo->mode = 0777 | S_ISVTX;
sbinfo->uid = current_fsuid();
sbinfo->gid = current_fsgid();
sb->s_fs_info = sbinfo;
@@ -3930,7 +3931,7 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, l
d_set_d_op(path.dentry, &anon_ops);
res = ERR_PTR(-ENOSPC);
- inode = shmem_get_inode(sb, NULL, S_IFREG | S_IRWXUGO, 0, flags);
+ inode = shmem_get_inode(sb, NULL, S_IFREG | 0777, 0, flags);
if (!inode)
goto put_memory;
diff --git a/mm/slab_common.c b/mm/slab_common.c
index b383149e04ec..ebe28ad516e3 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -1294,9 +1294,9 @@ void cache_random_seq_destroy(struct kmem_cache *cachep)
#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB_DEBUG)
#ifdef CONFIG_SLAB
-#define SLABINFO_RIGHTS (S_IWUSR | S_IRUSR)
+#define SLABINFO_RIGHTS (0600)
#else
-#define SLABINFO_RIGHTS S_IRUSR
+#define SLABINFO_RIGHTS (0400)
#endif
static void print_slabinfo_header(struct seq_file *m)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 89efac3a020e..cfea25be7754 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2741,11 +2741,11 @@ static const struct seq_operations vmalloc_op = {
static int __init proc_vmalloc_init(void)
{
if (IS_ENABLED(CONFIG_NUMA))
- proc_create_seq_private("vmallocinfo", S_IRUSR, NULL,
+ proc_create_seq_private("vmallocinfo", 0400, NULL,
&vmalloc_op,
nr_node_ids * sizeof(unsigned int), NULL);
else
- proc_create_seq("vmallocinfo", S_IRUSR, NULL, &vmalloc_op);
+ proc_create_seq("vmallocinfo", 0400, NULL, &vmalloc_op);
return 0;
}
module_init(proc_vmalloc_init);
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 61cb05dc950c..8d87e973a4f5 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -661,8 +661,9 @@ static void zs_pool_stat_create(struct zs_pool *pool, const char *name)
}
pool->stat_dentry = entry;
- entry = debugfs_create_file("classes", S_IFREG | S_IRUGO,
- pool->stat_dentry, pool, &zs_stats_size_fops);
+ entry = debugfs_create_file("classes", S_IFREG | 0444,
+ pool->stat_dentry, pool,
+ &zs_stats_size_fops);
if (!entry) {
pr_warn("%s: debugfs file entry <%s> creation failed\n",
name, "classes");
diff --git a/mm/zswap.c b/mm/zswap.c
index 61a5c41972db..7d34e69507e3 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1256,26 +1256,26 @@ static int __init zswap_debugfs_init(void)
if (!zswap_debugfs_root)
return -ENOMEM;
- debugfs_create_u64("pool_limit_hit", S_IRUGO,
- zswap_debugfs_root, &zswap_pool_limit_hit);
- debugfs_create_u64("reject_reclaim_fail", S_IRUGO,
- zswap_debugfs_root, &zswap_reject_reclaim_fail);
- debugfs_create_u64("reject_alloc_fail", S_IRUGO,
- zswap_debugfs_root, &zswap_reject_alloc_fail);
- debugfs_create_u64("reject_kmemcache_fail", S_IRUGO,
- zswap_debugfs_root, &zswap_reject_kmemcache_fail);
- debugfs_create_u64("reject_compress_poor", S_IRUGO,
- zswap_debugfs_root, &zswap_reject_compress_poor);
- debugfs_create_u64("written_back_pages", S_IRUGO,
- zswap_debugfs_root, &zswap_written_back_pages);
- debugfs_create_u64("duplicate_entry", S_IRUGO,
- zswap_debugfs_root, &zswap_duplicate_entry);
- debugfs_create_u64("pool_total_size", S_IRUGO,
- zswap_debugfs_root, &zswap_pool_total_size);
- debugfs_create_atomic_t("stored_pages", S_IRUGO,
- zswap_debugfs_root, &zswap_stored_pages);
+ debugfs_create_u64("pool_limit_hit", 0444,
+ zswap_debugfs_root, &zswap_pool_limit_hit);
+ debugfs_create_u64("reject_reclaim_fail", 0444,
+ zswap_debugfs_root, &zswap_reject_reclaim_fail);
+ debugfs_create_u64("reject_alloc_fail", 0444,
+ zswap_debugfs_root, &zswap_reject_alloc_fail);
+ debugfs_create_u64("reject_kmemcache_fail", 0444,
+ zswap_debugfs_root, &zswap_reject_kmemcache_fail);
+ debugfs_create_u64("reject_compress_poor", 0444,
+ zswap_debugfs_root, &zswap_reject_compress_poor);
+ debugfs_create_u64("written_back_pages", 0444,
+ zswap_debugfs_root, &zswap_written_back_pages);
+ debugfs_create_u64("duplicate_entry", 0444,
+ zswap_debugfs_root, &zswap_duplicate_entry);
+ debugfs_create_u64("pool_total_size", 0444,
+ zswap_debugfs_root, &zswap_pool_total_size);
+ debugfs_create_atomic_t("stored_pages", 0444,
+ zswap_debugfs_root, &zswap_stored_pages);
debugfs_create_atomic_t("same_filled_pages", 0444,
- zswap_debugfs_root, &zswap_same_filled_pages);
+ zswap_debugfs_root, &zswap_same_filled_pages);
return 0;
}
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index cf0bddc9d271..d82ed04c5ffa 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -518,6 +518,120 @@ cleanup:
return ret;
}
+static int alloc_pagecache_500M(const char *cgroup, void *arg)
+{
+ int fd = (long)arg;
+
+ return alloc_pagecache(fd, MB(500));
+}
+
+/*
+ * The test creates 10 nested memory cgroups with memory.min set to 50M,
+ * with 50M of pagecache charget to the leaf cgroup.
+ * Then it sets memory.max and memory.swap.max to 200M on the 3rd level,
+ * and creates memory pressure on 5th level.
+ * First it checks that memory.low actually works:
+ * expected usage on 9th level is 50M.
+ * Then it set memory.low on 2nd level to 0 and checks
+ * that memory.low stopped working:
+ * expected usage on 9th level is < 20M.
+ */
+static int test_memcg_low_nested(const char *root)
+{
+ int ret = KSFT_FAIL;
+ char *cgroup[10] = {NULL};
+ char *cgroup2;
+ long usage;
+ int i, fd;
+
+ fd = get_temp_fd();
+ if (fd < 0)
+ goto cleanup;
+
+ for (i = 0; i < ARRAY_SIZE(cgroup); i++) {
+ cgroup[i] = cg_name_indexed(i ? cgroup[i - 1] : root, "cg", i);
+ if (!cgroup[i])
+ goto cleanup;
+
+ if (cg_create(cgroup[i]))
+ goto cleanup;
+
+ if (i < ARRAY_SIZE(cgroup) - 1)
+ if (cg_write(cgroup[i], "cgroup.subtree_control",
+ "+memory"))
+ goto cleanup;
+
+ if (i == 3) {
+ if (cg_write(cgroup[i], "memory.max", "200M"))
+ goto cleanup;
+
+ if (cg_write(cgroup[i], "memory.swap.max", "0"))
+ goto cleanup;
+ }
+
+ if (cg_write(cgroup[i], "memory.low", "50M"))
+ goto cleanup;
+ }
+
+ cgroup2 = cg_name(cgroup[5], "memcg_pressure");
+ if (!cgroup2)
+ goto cleanup;
+
+ if (cg_create(cgroup2))
+ goto cleanup;
+
+ /* Part 1 */
+ if (cg_run(cgroup[ARRAY_SIZE(cgroup) - 1], alloc_pagecache_50M,
+ (void *)(long)fd))
+ goto cleanup;
+
+ if (cg_run(cgroup2, alloc_pagecache_500M, (void *)(long)fd))
+ goto cleanup;
+
+ if (!values_close(cg_read_long(cgroup[ARRAY_SIZE(cgroup) - 1],
+ "memory.current"), MB(50), 3))
+ goto cleanup;
+
+ close(fd);
+ fd = get_temp_fd();
+ if (fd < 0)
+ goto cleanup;
+
+ /* Part 2 */
+ if (cg_write(cgroup[2], "memory.low", "0"))
+ goto cleanup;
+
+ if (cg_run(cgroup[ARRAY_SIZE(cgroup) - 1], alloc_pagecache_50M,
+ (void *)(long)fd))
+ goto cleanup;
+
+ if (cg_run(cgroup2, alloc_pagecache_500M, (void *)(long)fd))
+ goto cleanup;
+
+ usage = cg_read_long(cgroup[ARRAY_SIZE(cgroup) - 1], "memory.current");
+ if (usage > MB(20))
+ goto cleanup;
+
+ ret = KSFT_PASS;
+
+cleanup:
+ if (cgroup2) {
+ cg_destroy(cgroup2);
+ free(cgroup2);
+ }
+
+ for (i = ARRAY_SIZE(cgroup) - 1; i >= 0; i--) {
+ if (!cgroup[i])
+ continue;
+
+ cg_destroy(cgroup[i]);
+ free(cgroup[i]);
+ }
+
+ close(fd);
+ return ret;
+}
+
static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
{
size_t size = MB(50);
@@ -973,6 +1087,7 @@ struct memcg_test {
T(test_memcg_current),
T(test_memcg_min),
T(test_memcg_low),
+ T(test_memcg_low_nested),
T(test_memcg_high),
T(test_memcg_max),
T(test_memcg_oom_events),