Skip to content

Commit 9c8e30d

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "15 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: mm: numa: mark huge PTEs young when clearing NUMA hinting faults mm: numa: slow PTE scan rate if migration failures occur mm: numa: preserve PTE write permissions across a NUMA hinting fault mm: numa: group related processes based on VMA flags instead of page table flags hfsplus: fix B-tree corruption after insertion at position 0 MAINTAINERS: add Jan as DMI/SMBIOS support maintainer fs/affs/file.c: unlock/release page on error mm/page_alloc.c: call kernel_map_pages in unset_migrateype_isolate mm/slub: fix lockups on PREEMPT && !SMP kernels mm/memory hotplug: postpone the reset of obsolete pgdat MAINTAINERS: correct rtc armada38x pattern entry mm/pagewalk.c: prevent positive return value of walk_page_test() from being passed to callers mm: fix anon_vma->degree underflow in anon_vma endless growing prevention drivers/rtc/rtc-mrst: fix suspend/resume aoe: update aoe maintainer information
2 parents b8517e9 + b7b0400 commit 9c8e30d

File tree

15 files changed

+106
-71
lines changed

15 files changed

+106
-71
lines changed

MAINTAINERS

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
11861186
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
11871187
S: Maintained
11881188
F: arch/arm/mach-mvebu/
1189-
F: drivers/rtc/armada38x-rtc
1189+
F: drivers/rtc/rtc-armada38x.c
11901190

11911191
ARM/Marvell Berlin SoC support
11921192
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
@@ -1675,8 +1675,8 @@ F: drivers/misc/eeprom/at24.c
16751675
F: include/linux/platform_data/at24.h
16761676

16771677
ATA OVER ETHERNET (AOE) DRIVER
1678-
M: "Ed L. Cashin" <ecashin@coraid.com>
1679-
W: http://support.coraid.com/support/linux
1678+
M: "Ed L. Cashin" <ed.cashin@acm.org>
1679+
W: http://www.openaoe.org/
16801680
S: Supported
16811681
F: Documentation/aoe/
16821682
F: drivers/block/aoe/
@@ -3252,6 +3252,13 @@ S: Maintained
32523252
F: Documentation/hwmon/dme1737
32533253
F: drivers/hwmon/dme1737.c
32543254

3255+
DMI/SMBIOS SUPPORT
3256+
M: Jean Delvare <jdelvare@suse.de>
3257+
S: Maintained
3258+
F: drivers/firmware/dmi-id.c
3259+
F: drivers/firmware/dmi_scan.c
3260+
F: include/linux/dmi.h
3261+
32553262
DOCKING STATION DRIVER
32563263
M: Shaohua Li <shaohua.li@intel.com>
32573264
L: linux-acpi@vger.kernel.org

drivers/rtc/rtc-mrst.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,8 @@ static void rtc_mrst_do_remove(struct device *dev)
413413
mrst->dev = NULL;
414414
}
415415

416-
#ifdef CONFIG_PM
417-
static int mrst_suspend(struct device *dev, pm_message_t mesg)
416+
#ifdef CONFIG_PM_SLEEP
417+
static int mrst_suspend(struct device *dev)
418418
{
419419
struct mrst_rtc *mrst = dev_get_drvdata(dev);
420420
unsigned char tmp;
@@ -453,7 +453,7 @@ static int mrst_suspend(struct device *dev, pm_message_t mesg)
453453
*/
454454
static inline int mrst_poweroff(struct device *dev)
455455
{
456-
return mrst_suspend(dev, PMSG_HIBERNATE);
456+
return mrst_suspend(dev);
457457
}
458458

459459
static int mrst_resume(struct device *dev)
@@ -490,9 +490,11 @@ static int mrst_resume(struct device *dev)
490490
return 0;
491491
}
492492

493+
static SIMPLE_DEV_PM_OPS(mrst_pm_ops, mrst_suspend, mrst_resume);
494+
#define MRST_PM_OPS (&mrst_pm_ops)
495+
493496
#else
494-
#define mrst_suspend NULL
495-
#define mrst_resume NULL
497+
#define MRST_PM_OPS NULL
496498

497499
static inline int mrst_poweroff(struct device *dev)
498500
{
@@ -529,9 +531,8 @@ static struct platform_driver vrtc_mrst_platform_driver = {
529531
.remove = vrtc_mrst_platform_remove,
530532
.shutdown = vrtc_mrst_platform_shutdown,
531533
.driver = {
532-
.name = (char *) driver_name,
533-
.suspend = mrst_suspend,
534-
.resume = mrst_resume,
534+
.name = driver_name,
535+
.pm = MRST_PM_OPS,
535536
}
536537
};
537538

fs/affs/file.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,10 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
699699
boff = tmp % bsize;
700700
if (boff) {
701701
bh = affs_bread_ino(inode, bidx, 0);
702-
if (IS_ERR(bh))
703-
return PTR_ERR(bh);
702+
if (IS_ERR(bh)) {
703+
written = PTR_ERR(bh);
704+
goto err_first_bh;
705+
}
704706
tmp = min(bsize - boff, to - from);
705707
BUG_ON(boff + tmp > bsize || tmp > bsize);
706708
memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
@@ -712,14 +714,16 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
712714
bidx++;
713715
} else if (bidx) {
714716
bh = affs_bread_ino(inode, bidx - 1, 0);
715-
if (IS_ERR(bh))
716-
return PTR_ERR(bh);
717+
if (IS_ERR(bh)) {
718+
written = PTR_ERR(bh);
719+
goto err_first_bh;
720+
}
717721
}
718722
while (from + bsize <= to) {
719723
prev_bh = bh;
720724
bh = affs_getemptyblk_ino(inode, bidx);
721725
if (IS_ERR(bh))
722-
goto out;
726+
goto err_bh;
723727
memcpy(AFFS_DATA(bh), data + from, bsize);
724728
if (buffer_new(bh)) {
725729
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
@@ -751,7 +755,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
751755
prev_bh = bh;
752756
bh = affs_bread_ino(inode, bidx, 1);
753757
if (IS_ERR(bh))
754-
goto out;
758+
goto err_bh;
755759
tmp = min(bsize, to - from);
756760
BUG_ON(tmp > bsize);
757761
memcpy(AFFS_DATA(bh), data + from, tmp);
@@ -790,12 +794,13 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
790794
if (tmp > inode->i_size)
791795
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
792796

797+
err_first_bh:
793798
unlock_page(page);
794799
page_cache_release(page);
795800

796801
return written;
797802

798-
out:
803+
err_bh:
799804
bh = prev_bh;
800805
if (!written)
801806
written = PTR_ERR(bh);

fs/hfsplus/brec.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,16 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
131131
hfs_bnode_write(node, entry, data_off + key_len, entry_len);
132132
hfs_bnode_dump(node);
133133

134-
if (new_node) {
135-
/* update parent key if we inserted a key
136-
* at the start of the first node
137-
*/
138-
if (!rec && new_node != node)
139-
hfs_brec_update_parent(fd);
134+
/*
135+
* update parent key if we inserted a key
136+
* at the start of the node and it is not the new node
137+
*/
138+
if (!rec && new_node != node) {
139+
hfs_bnode_read_key(node, fd->search_key, data_off + size);
140+
hfs_brec_update_parent(fd);
141+
}
140142

143+
if (new_node) {
141144
hfs_bnode_put(fd->bnode);
142145
if (!new_node->parent) {
143146
hfs_btree_inc_height(tree);
@@ -168,9 +171,6 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
168171
goto again;
169172
}
170173

171-
if (!rec)
172-
hfs_brec_update_parent(fd);
173-
174174
return 0;
175175
}
176176

@@ -370,6 +370,8 @@ static int hfs_brec_update_parent(struct hfs_find_data *fd)
370370
if (IS_ERR(parent))
371371
return PTR_ERR(parent);
372372
__hfs_brec_find(parent, fd, hfs_find_rec_by_key);
373+
if (fd->record < 0)
374+
return -ENOENT;
373375
hfs_bnode_dump(parent);
374376
rec = fd->record;
375377

include/linux/sched.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,11 +1625,11 @@ struct task_struct {
16251625

16261626
/*
16271627
* numa_faults_locality tracks if faults recorded during the last
1628-
* scan window were remote/local. The task scan period is adapted
1629-
* based on the locality of the faults with different weights
1630-
* depending on whether they were shared or private faults
1628+
* scan window were remote/local or failed to migrate. The task scan
1629+
* period is adapted based on the locality of the faults with different
1630+
* weights depending on whether they were shared or private faults
16311631
*/
1632-
unsigned long numa_faults_locality[2];
1632+
unsigned long numa_faults_locality[3];
16331633

16341634
unsigned long numa_pages_migrated;
16351635
#endif /* CONFIG_NUMA_BALANCING */
@@ -1719,6 +1719,7 @@ struct task_struct {
17191719
#define TNF_NO_GROUP 0x02
17201720
#define TNF_SHARED 0x04
17211721
#define TNF_FAULT_LOCAL 0x08
1722+
#define TNF_MIGRATE_FAIL 0x10
17221723

17231724
#ifdef CONFIG_NUMA_BALANCING
17241725
extern void task_numa_fault(int last_node, int node, int pages, int flags);

kernel/sched/fair.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,9 +1609,11 @@ static void update_task_scan_period(struct task_struct *p,
16091609
/*
16101610
* If there were no record hinting faults then either the task is
16111611
* completely idle or all activity is areas that are not of interest
1612-
* to automatic numa balancing. Scan slower
1612+
* to automatic numa balancing. Related to that, if there were failed
1613+
* migration then it implies we are migrating too quickly or the local
1614+
* node is overloaded. In either case, scan slower
16131615
*/
1614-
if (local + shared == 0) {
1616+
if (local + shared == 0 || p->numa_faults_locality[2]) {
16151617
p->numa_scan_period = min(p->numa_scan_period_max,
16161618
p->numa_scan_period << 1);
16171619

@@ -2080,6 +2082,8 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags)
20802082

20812083
if (migrated)
20822084
p->numa_pages_migrated += pages;
2085+
if (flags & TNF_MIGRATE_FAIL)
2086+
p->numa_faults_locality[2] += pages;
20832087

20842088
p->numa_faults[task_faults_idx(NUMA_MEMBUF, mem_node, priv)] += pages;
20852089
p->numa_faults[task_faults_idx(NUMA_CPUBUF, cpu_node, priv)] += pages;

mm/huge_memory.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
12601260
int target_nid, last_cpupid = -1;
12611261
bool page_locked;
12621262
bool migrated = false;
1263+
bool was_writable;
12631264
int flags = 0;
12641265

12651266
/* A PROT_NONE fault should not end up here */
@@ -1291,17 +1292,8 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
12911292
flags |= TNF_FAULT_LOCAL;
12921293
}
12931294

1294-
/*
1295-
* Avoid grouping on DSO/COW pages in specific and RO pages
1296-
* in general, RO pages shouldn't hurt as much anyway since
1297-
* they can be in shared cache state.
1298-
*
1299-
* FIXME! This checks "pmd_dirty()" as an approximation of
1300-
* "is this a read-only page", since checking "pmd_write()"
1301-
* is even more broken. We haven't actually turned this into
1302-
* a writable page, so pmd_write() will always be false.
1303-
*/
1304-
if (!pmd_dirty(pmd))
1295+
/* See similar comment in do_numa_page for explanation */
1296+
if (!(vma->vm_flags & VM_WRITE))
13051297
flags |= TNF_NO_GROUP;
13061298

13071299
/*
@@ -1358,12 +1350,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
13581350
if (migrated) {
13591351
flags |= TNF_MIGRATED;
13601352
page_nid = target_nid;
1361-
}
1353+
} else
1354+
flags |= TNF_MIGRATE_FAIL;
13621355

13631356
goto out;
13641357
clear_pmdnuma:
13651358
BUG_ON(!PageLocked(page));
1359+
was_writable = pmd_write(pmd);
13661360
pmd = pmd_modify(pmd, vma->vm_page_prot);
1361+
pmd = pmd_mkyoung(pmd);
1362+
if (was_writable)
1363+
pmd = pmd_mkwrite(pmd);
13671364
set_pmd_at(mm, haddr, pmdp, pmd);
13681365
update_mmu_cache_pmd(vma, addr, pmdp);
13691366
unlock_page(page);
@@ -1487,6 +1484,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
14871484

14881485
if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
14891486
pmd_t entry;
1487+
bool preserve_write = prot_numa && pmd_write(*pmd);
14901488
ret = 1;
14911489

14921490
/*
@@ -1502,9 +1500,11 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
15021500
if (!prot_numa || !pmd_protnone(*pmd)) {
15031501
entry = pmdp_get_and_clear_notify(mm, addr, pmd);
15041502
entry = pmd_modify(entry, newprot);
1503+
if (preserve_write)
1504+
entry = pmd_mkwrite(entry);
15051505
ret = HPAGE_PMD_NR;
15061506
set_pmd_at(mm, addr, pmd, entry);
1507-
BUG_ON(pmd_write(entry));
1507+
BUG_ON(!preserve_write && pmd_write(entry));
15081508
}
15091509
spin_unlock(ptl);
15101510
}

mm/memory.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3035,6 +3035,7 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
30353035
int last_cpupid;
30363036
int target_nid;
30373037
bool migrated = false;
3038+
bool was_writable = pte_write(pte);
30383039
int flags = 0;
30393040

30403041
/* A PROT_NONE fault should not end up here */
@@ -3059,6 +3060,8 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
30593060
/* Make it present again */
30603061
pte = pte_modify(pte, vma->vm_page_prot);
30613062
pte = pte_mkyoung(pte);
3063+
if (was_writable)
3064+
pte = pte_mkwrite(pte);
30623065
set_pte_at(mm, addr, ptep, pte);
30633066
update_mmu_cache(vma, addr, ptep);
30643067

@@ -3069,16 +3072,14 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
30693072
}
30703073

30713074
/*
3072-
* Avoid grouping on DSO/COW pages in specific and RO pages
3073-
* in general, RO pages shouldn't hurt as much anyway since
3074-
* they can be in shared cache state.
3075-
*
3076-
* FIXME! This checks "pmd_dirty()" as an approximation of
3077-
* "is this a read-only page", since checking "pmd_write()"
3078-
* is even more broken. We haven't actually turned this into
3079-
* a writable page, so pmd_write() will always be false.
3075+
* Avoid grouping on RO pages in general. RO pages shouldn't hurt as
3076+
* much anyway since they can be in shared cache state. This misses
3077+
* the case where a mapping is writable but the process never writes
3078+
* to it but pte_write gets cleared during protection updates and
3079+
* pte_dirty has unpredictable behaviour between PTE scan updates,
3080+
* background writeback, dirty balancing and application behaviour.
30803081
*/
3081-
if (!pte_dirty(pte))
3082+
if (!(vma->vm_flags & VM_WRITE))
30823083
flags |= TNF_NO_GROUP;
30833084

30843085
/*
@@ -3102,7 +3103,8 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
31023103
if (migrated) {
31033104
page_nid = target_nid;
31043105
flags |= TNF_MIGRATED;
3105-
}
3106+
} else
3107+
flags |= TNF_MIGRATE_FAIL;
31063108

31073109
out:
31083110
if (page_nid != -1)

mm/memory_hotplug.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,10 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
10921092
return NULL;
10931093

10941094
arch_refresh_nodedata(nid, pgdat);
1095+
} else {
1096+
/* Reset the nr_zones and classzone_idx to 0 before reuse */
1097+
pgdat->nr_zones = 0;
1098+
pgdat->classzone_idx = 0;
10951099
}
10961100

10971101
/* we can use NODE_DATA(nid) from here */
@@ -1977,15 +1981,6 @@ void try_offline_node(int nid)
19771981
if (is_vmalloc_addr(zone->wait_table))
19781982
vfree(zone->wait_table);
19791983
}
1980-
1981-
/*
1982-
* Since there is no way to guarentee the address of pgdat/zone is not
1983-
* on stack of any kernel threads or used by other kernel objects
1984-
* without reference counting or other symchronizing method, do not
1985-
* reset node_data and free pgdat here. Just reset it to 0 and reuse
1986-
* the memory when the node is online again.
1987-
*/
1988-
memset(pgdat, 0, sizeof(*pgdat));
19891984
}
19901985
EXPORT_SYMBOL(try_offline_node);
19911986

mm/mmap.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,10 +774,8 @@ again: remove_next = 1 + (end > next->vm_end);
774774

775775
importer->anon_vma = exporter->anon_vma;
776776
error = anon_vma_clone(importer, exporter);
777-
if (error) {
778-
importer->anon_vma = NULL;
777+
if (error)
779778
return error;
780-
}
781779
}
782780
}
783781

0 commit comments

Comments
 (0)