Skip to content

Commit 998d755

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "Rather a lot of fixes, almost all affecting mm/" * emailed patches from Andrew Morton <[email protected]>: (26 commits) scripts/gdb: fix debugging modules on s390 kernel/events/uprobes.c: only do FOLL_SPLIT_PMD for uprobe register mm/thp: allow dropping THP from page cache mm/vmscan.c: support removing arbitrary sized pages from mapping mm/thp: fix node page state in split_huge_page_to_list() proc/meminfo: fix output alignment mm/init-mm.c: include <linux/mman.h> for vm_committed_as_batch mm/filemap.c: include <linux/ramfs.h> for generic_file_vm_ops definition mm: include <linux/huge_mm.h> for is_vma_temporary_stack zram: fix race between backing_dev_show and backing_dev_store mm/memcontrol: update lruvec counters in mem_cgroup_move_account ocfs2: fix panic due to ocfs2_wq is null hugetlbfs: don't access uninitialized memmaps in pfn_range_valid_gigantic() mm: memblock: do not enforce current limit for memblock_phys* family mm: memcg: get number of pages on the LRU list in memcgroup base on lru_zone_size mm/gup: fix a misnamed "write" argument, and a related bug mm/gup_benchmark: add a missing "w" to getopt string ocfs2: fix error handling in ocfs2_setattr() mm: memcg/slab: fix panic in __free_slab() caused by premature memcg pointer release mm/memunmap: don't access uninitialized memmap in memunmap_pages() ...
2 parents d418d07 + 585d730 commit 998d755

File tree

27 files changed

+165
-139
lines changed

27 files changed

+165
-139
lines changed

drivers/base/memory.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ static ssize_t soft_offline_page_store(struct device *dev,
540540
pfn >>= PAGE_SHIFT;
541541
if (!pfn_valid(pfn))
542542
return -ENXIO;
543+
/* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */
544+
if (!pfn_to_online_page(pfn))
545+
return -EIO;
543546
ret = soft_offline_page(pfn_to_page(pfn), 0);
544547
return ret == 0 ? count : ret;
545548
}

drivers/block/zram/zram_drv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,14 @@ static void reset_bdev(struct zram *zram)
413413
static ssize_t backing_dev_show(struct device *dev,
414414
struct device_attribute *attr, char *buf)
415415
{
416+
struct file *file;
416417
struct zram *zram = dev_to_zram(dev);
417-
struct file *file = zram->backing_dev;
418418
char *p;
419419
ssize_t ret;
420420

421421
down_read(&zram->init_lock);
422-
if (!zram->backing_dev) {
422+
file = zram->backing_dev;
423+
if (!file) {
423424
memcpy(buf, "none\n", 5);
424425
up_read(&zram->init_lock);
425426
return 5;

fs/ocfs2/file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
12301230
transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
12311231
if (IS_ERR(transfer_to[USRQUOTA])) {
12321232
status = PTR_ERR(transfer_to[USRQUOTA]);
1233+
transfer_to[USRQUOTA] = NULL;
12331234
goto bail_unlock;
12341235
}
12351236
}
@@ -1239,6 +1240,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
12391240
transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
12401241
if (IS_ERR(transfer_to[GRPQUOTA])) {
12411242
status = PTR_ERR(transfer_to[GRPQUOTA]);
1243+
transfer_to[GRPQUOTA] = NULL;
12421244
goto bail_unlock;
12431245
}
12441246
}

fs/ocfs2/journal.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ void ocfs2_recovery_exit(struct ocfs2_super *osb)
217217
/* At this point, we know that no more recovery threads can be
218218
* launched, so wait for any recovery completion work to
219219
* complete. */
220-
flush_workqueue(osb->ocfs2_wq);
220+
if (osb->ocfs2_wq)
221+
flush_workqueue(osb->ocfs2_wq);
221222

222223
/*
223224
* Now that recovery is shut down, and the osb is about to be

fs/ocfs2/localalloc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
377377
struct ocfs2_dinode *alloc = NULL;
378378

379379
cancel_delayed_work(&osb->la_enable_wq);
380-
flush_workqueue(osb->ocfs2_wq);
380+
if (osb->ocfs2_wq)
381+
flush_workqueue(osb->ocfs2_wq);
381382

382383
if (osb->local_alloc_state == OCFS2_LA_UNUSED)
383384
goto out;

fs/proc/meminfo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
132132
global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR);
133133
show_val_kb(m, "ShmemPmdMapped: ",
134134
global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR);
135-
show_val_kb(m, "FileHugePages: ",
135+
show_val_kb(m, "FileHugePages: ",
136136
global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR);
137-
show_val_kb(m, "FilePmdMapped: ",
137+
show_val_kb(m, "FilePmdMapped: ",
138138
global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR);
139139
#endif
140140

fs/proc/page.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
4242
return -EINVAL;
4343

4444
while (count > 0) {
45-
if (pfn_valid(pfn))
46-
ppage = pfn_to_page(pfn);
47-
else
48-
ppage = NULL;
45+
/*
46+
* TODO: ZONE_DEVICE support requires to identify
47+
* memmaps that were actually initialized.
48+
*/
49+
ppage = pfn_to_online_page(pfn);
50+
4951
if (!ppage || PageSlab(ppage) || page_has_type(ppage))
5052
pcount = 0;
5153
else
@@ -216,10 +218,11 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
216218
return -EINVAL;
217219

218220
while (count > 0) {
219-
if (pfn_valid(pfn))
220-
ppage = pfn_to_page(pfn);
221-
else
222-
ppage = NULL;
221+
/*
222+
* TODO: ZONE_DEVICE support requires to identify
223+
* memmaps that were actually initialized.
224+
*/
225+
ppage = pfn_to_online_page(pfn);
223226

224227
if (put_user(stable_page_flags(ppage), out)) {
225228
ret = -EFAULT;
@@ -261,10 +264,11 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
261264
return -EINVAL;
262265

263266
while (count > 0) {
264-
if (pfn_valid(pfn))
265-
ppage = pfn_to_page(pfn);
266-
else
267-
ppage = NULL;
267+
/*
268+
* TODO: ZONE_DEVICE support requires to identify
269+
* memmaps that were actually initialized.
270+
*/
271+
ppage = pfn_to_online_page(pfn);
268272

269273
if (ppage)
270274
ino = page_cgroup_ino(ppage);

kernel/events/uprobes.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,21 +474,30 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
474474
struct vm_area_struct *vma;
475475
int ret, is_register, ref_ctr_updated = 0;
476476
bool orig_page_huge = false;
477+
unsigned int gup_flags = FOLL_FORCE;
477478

478479
is_register = is_swbp_insn(&opcode);
479480
uprobe = container_of(auprobe, struct uprobe, arch);
480481

481482
retry:
483+
if (is_register)
484+
gup_flags |= FOLL_SPLIT_PMD;
482485
/* Read the page with vaddr into memory */
483-
ret = get_user_pages_remote(NULL, mm, vaddr, 1,
484-
FOLL_FORCE | FOLL_SPLIT_PMD, &old_page, &vma, NULL);
486+
ret = get_user_pages_remote(NULL, mm, vaddr, 1, gup_flags,
487+
&old_page, &vma, NULL);
485488
if (ret <= 0)
486489
return ret;
487490

488491
ret = verify_opcode(old_page, vaddr, &opcode);
489492
if (ret <= 0)
490493
goto put_old;
491494

495+
if (WARN(!is_register && PageCompound(old_page),
496+
"uprobe unregister should never work on compound page\n")) {
497+
ret = -EINVAL;
498+
goto put_old;
499+
}
500+
492501
/* We are going to replace instruction, update ref_ctr. */
493502
if (!ref_ctr_updated && uprobe->ref_ctr_offset) {
494503
ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1);

mm/filemap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <linux/rmap.h>
4141
#include <linux/delayacct.h>
4242
#include <linux/psi.h>
43+
#include <linux/ramfs.h>
4344
#include "internal.h"
4445

4546
#define CREATE_TRACE_POINTS

mm/gup.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,7 +1973,8 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
19731973
}
19741974

19751975
static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
1976-
unsigned long end, int write, struct page **pages, int *nr)
1976+
unsigned long end, unsigned int flags,
1977+
struct page **pages, int *nr)
19771978
{
19781979
unsigned long pte_end;
19791980
struct page *head, *page;
@@ -1986,7 +1987,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
19861987

19871988
pte = READ_ONCE(*ptep);
19881989

1989-
if (!pte_access_permitted(pte, write))
1990+
if (!pte_access_permitted(pte, flags & FOLL_WRITE))
19901991
return 0;
19911992

19921993
/* hugepages are never "special" */
@@ -2023,7 +2024,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
20232024
}
20242025

20252026
static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
2026-
unsigned int pdshift, unsigned long end, int write,
2027+
unsigned int pdshift, unsigned long end, unsigned int flags,
20272028
struct page **pages, int *nr)
20282029
{
20292030
pte_t *ptep;
@@ -2033,23 +2034,24 @@ static int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
20332034
ptep = hugepte_offset(hugepd, addr, pdshift);
20342035
do {
20352036
next = hugepte_addr_end(addr, end, sz);
2036-
if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
2037+
if (!gup_hugepte(ptep, sz, addr, end, flags, pages, nr))
20372038
return 0;
20382039
} while (ptep++, addr = next, addr != end);
20392040

20402041
return 1;
20412042
}
20422043
#else
20432044
static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
2044-
unsigned pdshift, unsigned long end, int write,
2045+
unsigned int pdshift, unsigned long end, unsigned int flags,
20452046
struct page **pages, int *nr)
20462047
{
20472048
return 0;
20482049
}
20492050
#endif /* CONFIG_ARCH_HAS_HUGEPD */
20502051

20512052
static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
2052-
unsigned long end, unsigned int flags, struct page **pages, int *nr)
2053+
unsigned long end, unsigned int flags,
2054+
struct page **pages, int *nr)
20532055
{
20542056
struct page *head, *page;
20552057
int refs;

mm/huge_memory.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,8 +2789,13 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
27892789
ds_queue->split_queue_len--;
27902790
list_del(page_deferred_list(head));
27912791
}
2792-
if (mapping)
2793-
__dec_node_page_state(page, NR_SHMEM_THPS);
2792+
if (mapping) {
2793+
if (PageSwapBacked(page))
2794+
__dec_node_page_state(page, NR_SHMEM_THPS);
2795+
else
2796+
__dec_node_page_state(page, NR_FILE_THPS);
2797+
}
2798+
27942799
spin_unlock(&ds_queue->split_queue_lock);
27952800
__split_huge_page(page, list, end, flags);
27962801
if (PageSwapCache(head)) {

mm/hugetlb.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,11 +1084,10 @@ static bool pfn_range_valid_gigantic(struct zone *z,
10841084
struct page *page;
10851085

10861086
for (i = start_pfn; i < end_pfn; i++) {
1087-
if (!pfn_valid(i))
1087+
page = pfn_to_online_page(i);
1088+
if (!page)
10881089
return false;
10891090

1090-
page = pfn_to_page(i);
1091-
10921091
if (page_zone(page) != z)
10931092
return false;
10941093

mm/init-mm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/spinlock.h>
66
#include <linux/list.h>
77
#include <linux/cpumask.h>
8+
#include <linux/mman.h>
89

910
#include <linux/atomic.h>
1011
#include <linux/user_namespace.h>

mm/memblock.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,9 +1356,6 @@ static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
13561356
align = SMP_CACHE_BYTES;
13571357
}
13581358

1359-
if (end > memblock.current_limit)
1360-
end = memblock.current_limit;
1361-
13621359
again:
13631360
found = memblock_find_in_range_node(size, align, start, end, nid,
13641361
flags);
@@ -1469,6 +1466,9 @@ static void * __init memblock_alloc_internal(
14691466
if (WARN_ON_ONCE(slab_is_available()))
14701467
return kzalloc_node(size, GFP_NOWAIT, nid);
14711468

1469+
if (max_addr > memblock.current_limit)
1470+
max_addr = memblock.current_limit;
1471+
14721472
alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid);
14731473

14741474
/* retry allocation without lower limit */

mm/memcontrol.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5420,6 +5420,8 @@ static int mem_cgroup_move_account(struct page *page,
54205420
struct mem_cgroup *from,
54215421
struct mem_cgroup *to)
54225422
{
5423+
struct lruvec *from_vec, *to_vec;
5424+
struct pglist_data *pgdat;
54235425
unsigned long flags;
54245426
unsigned int nr_pages = compound ? hpage_nr_pages(page) : 1;
54255427
int ret;
@@ -5443,11 +5445,15 @@ static int mem_cgroup_move_account(struct page *page,
54435445

54445446
anon = PageAnon(page);
54455447

5448+
pgdat = page_pgdat(page);
5449+
from_vec = mem_cgroup_lruvec(pgdat, from);
5450+
to_vec = mem_cgroup_lruvec(pgdat, to);
5451+
54465452
spin_lock_irqsave(&from->move_lock, flags);
54475453

54485454
if (!anon && page_mapped(page)) {
5449-
__mod_memcg_state(from, NR_FILE_MAPPED, -nr_pages);
5450-
__mod_memcg_state(to, NR_FILE_MAPPED, nr_pages);
5455+
__mod_lruvec_state(from_vec, NR_FILE_MAPPED, -nr_pages);
5456+
__mod_lruvec_state(to_vec, NR_FILE_MAPPED, nr_pages);
54515457
}
54525458

54535459
/*
@@ -5459,14 +5465,14 @@ static int mem_cgroup_move_account(struct page *page,
54595465
struct address_space *mapping = page_mapping(page);
54605466

54615467
if (mapping_cap_account_dirty(mapping)) {
5462-
__mod_memcg_state(from, NR_FILE_DIRTY, -nr_pages);
5463-
__mod_memcg_state(to, NR_FILE_DIRTY, nr_pages);
5468+
__mod_lruvec_state(from_vec, NR_FILE_DIRTY, -nr_pages);
5469+
__mod_lruvec_state(to_vec, NR_FILE_DIRTY, nr_pages);
54645470
}
54655471
}
54665472

54675473
if (PageWriteback(page)) {
5468-
__mod_memcg_state(from, NR_WRITEBACK, -nr_pages);
5469-
__mod_memcg_state(to, NR_WRITEBACK, nr_pages);
5474+
__mod_lruvec_state(from_vec, NR_WRITEBACK, -nr_pages);
5475+
__mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages);
54705476
}
54715477

54725478
#ifdef CONFIG_TRANSPARENT_HUGEPAGE

mm/memory-failure.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,17 +1257,19 @@ int memory_failure(unsigned long pfn, int flags)
12571257
if (!sysctl_memory_failure_recovery)
12581258
panic("Memory failure on page %lx", pfn);
12591259

1260-
if (!pfn_valid(pfn)) {
1260+
p = pfn_to_online_page(pfn);
1261+
if (!p) {
1262+
if (pfn_valid(pfn)) {
1263+
pgmap = get_dev_pagemap(pfn, NULL);
1264+
if (pgmap)
1265+
return memory_failure_dev_pagemap(pfn, flags,
1266+
pgmap);
1267+
}
12611268
pr_err("Memory failure: %#lx: memory outside kernel control\n",
12621269
pfn);
12631270
return -ENXIO;
12641271
}
12651272

1266-
pgmap = get_dev_pagemap(pfn, NULL);
1267-
if (pgmap)
1268-
return memory_failure_dev_pagemap(pfn, flags, pgmap);
1269-
1270-
p = pfn_to_page(pfn);
12711273
if (PageHuge(p))
12721274
return memory_failure_hugetlb(pfn, flags);
12731275
if (TestSetPageHWPoison(p)) {

0 commit comments

Comments
 (0)