mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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
This commit is contained in:
commit
9c8e30d12d
13
MAINTAINERS
13
MAINTAINERS
@ -1186,7 +1186,7 @@ M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
|||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: arch/arm/mach-mvebu/
|
F: arch/arm/mach-mvebu/
|
||||||
F: drivers/rtc/armada38x-rtc
|
F: drivers/rtc/rtc-armada38x.c
|
||||||
|
|
||||||
ARM/Marvell Berlin SoC support
|
ARM/Marvell Berlin SoC support
|
||||||
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||||
@ -1675,8 +1675,8 @@ F: drivers/misc/eeprom/at24.c
|
|||||||
F: include/linux/platform_data/at24.h
|
F: include/linux/platform_data/at24.h
|
||||||
|
|
||||||
ATA OVER ETHERNET (AOE) DRIVER
|
ATA OVER ETHERNET (AOE) DRIVER
|
||||||
M: "Ed L. Cashin" <ecashin@coraid.com>
|
M: "Ed L. Cashin" <ed.cashin@acm.org>
|
||||||
W: http://support.coraid.com/support/linux
|
W: http://www.openaoe.org/
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/aoe/
|
F: Documentation/aoe/
|
||||||
F: drivers/block/aoe/
|
F: drivers/block/aoe/
|
||||||
@ -3252,6 +3252,13 @@ S: Maintained
|
|||||||
F: Documentation/hwmon/dme1737
|
F: Documentation/hwmon/dme1737
|
||||||
F: drivers/hwmon/dme1737.c
|
F: drivers/hwmon/dme1737.c
|
||||||
|
|
||||||
|
DMI/SMBIOS SUPPORT
|
||||||
|
M: Jean Delvare <jdelvare@suse.de>
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/firmware/dmi-id.c
|
||||||
|
F: drivers/firmware/dmi_scan.c
|
||||||
|
F: include/linux/dmi.h
|
||||||
|
|
||||||
DOCKING STATION DRIVER
|
DOCKING STATION DRIVER
|
||||||
M: Shaohua Li <shaohua.li@intel.com>
|
M: Shaohua Li <shaohua.li@intel.com>
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
|
@ -413,8 +413,8 @@ static void rtc_mrst_do_remove(struct device *dev)
|
|||||||
mrst->dev = NULL;
|
mrst->dev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int mrst_suspend(struct device *dev, pm_message_t mesg)
|
static int mrst_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct mrst_rtc *mrst = dev_get_drvdata(dev);
|
struct mrst_rtc *mrst = dev_get_drvdata(dev);
|
||||||
unsigned char tmp;
|
unsigned char tmp;
|
||||||
@ -453,7 +453,7 @@ static int mrst_suspend(struct device *dev, pm_message_t mesg)
|
|||||||
*/
|
*/
|
||||||
static inline int mrst_poweroff(struct device *dev)
|
static inline int mrst_poweroff(struct device *dev)
|
||||||
{
|
{
|
||||||
return mrst_suspend(dev, PMSG_HIBERNATE);
|
return mrst_suspend(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mrst_resume(struct device *dev)
|
static int mrst_resume(struct device *dev)
|
||||||
@ -490,9 +490,11 @@ static int mrst_resume(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(mrst_pm_ops, mrst_suspend, mrst_resume);
|
||||||
|
#define MRST_PM_OPS (&mrst_pm_ops)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define mrst_suspend NULL
|
#define MRST_PM_OPS NULL
|
||||||
#define mrst_resume NULL
|
|
||||||
|
|
||||||
static inline int mrst_poweroff(struct device *dev)
|
static inline int mrst_poweroff(struct device *dev)
|
||||||
{
|
{
|
||||||
@ -529,9 +531,8 @@ static struct platform_driver vrtc_mrst_platform_driver = {
|
|||||||
.remove = vrtc_mrst_platform_remove,
|
.remove = vrtc_mrst_platform_remove,
|
||||||
.shutdown = vrtc_mrst_platform_shutdown,
|
.shutdown = vrtc_mrst_platform_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = (char *) driver_name,
|
.name = driver_name,
|
||||||
.suspend = mrst_suspend,
|
.pm = MRST_PM_OPS,
|
||||||
.resume = mrst_resume,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -699,8 +699,10 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
|||||||
boff = tmp % bsize;
|
boff = tmp % bsize;
|
||||||
if (boff) {
|
if (boff) {
|
||||||
bh = affs_bread_ino(inode, bidx, 0);
|
bh = affs_bread_ino(inode, bidx, 0);
|
||||||
if (IS_ERR(bh))
|
if (IS_ERR(bh)) {
|
||||||
return PTR_ERR(bh);
|
written = PTR_ERR(bh);
|
||||||
|
goto err_first_bh;
|
||||||
|
}
|
||||||
tmp = min(bsize - boff, to - from);
|
tmp = min(bsize - boff, to - from);
|
||||||
BUG_ON(boff + tmp > bsize || tmp > bsize);
|
BUG_ON(boff + tmp > bsize || tmp > bsize);
|
||||||
memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
|
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,
|
|||||||
bidx++;
|
bidx++;
|
||||||
} else if (bidx) {
|
} else if (bidx) {
|
||||||
bh = affs_bread_ino(inode, bidx - 1, 0);
|
bh = affs_bread_ino(inode, bidx - 1, 0);
|
||||||
if (IS_ERR(bh))
|
if (IS_ERR(bh)) {
|
||||||
return PTR_ERR(bh);
|
written = PTR_ERR(bh);
|
||||||
|
goto err_first_bh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (from + bsize <= to) {
|
while (from + bsize <= to) {
|
||||||
prev_bh = bh;
|
prev_bh = bh;
|
||||||
bh = affs_getemptyblk_ino(inode, bidx);
|
bh = affs_getemptyblk_ino(inode, bidx);
|
||||||
if (IS_ERR(bh))
|
if (IS_ERR(bh))
|
||||||
goto out;
|
goto err_bh;
|
||||||
memcpy(AFFS_DATA(bh), data + from, bsize);
|
memcpy(AFFS_DATA(bh), data + from, bsize);
|
||||||
if (buffer_new(bh)) {
|
if (buffer_new(bh)) {
|
||||||
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
|
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,
|
|||||||
prev_bh = bh;
|
prev_bh = bh;
|
||||||
bh = affs_bread_ino(inode, bidx, 1);
|
bh = affs_bread_ino(inode, bidx, 1);
|
||||||
if (IS_ERR(bh))
|
if (IS_ERR(bh))
|
||||||
goto out;
|
goto err_bh;
|
||||||
tmp = min(bsize, to - from);
|
tmp = min(bsize, to - from);
|
||||||
BUG_ON(tmp > bsize);
|
BUG_ON(tmp > bsize);
|
||||||
memcpy(AFFS_DATA(bh), data + from, tmp);
|
memcpy(AFFS_DATA(bh), data + from, tmp);
|
||||||
@ -790,12 +794,13 @@ done:
|
|||||||
if (tmp > inode->i_size)
|
if (tmp > inode->i_size)
|
||||||
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
|
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
|
||||||
|
|
||||||
|
err_first_bh:
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
|
|
||||||
out:
|
err_bh:
|
||||||
bh = prev_bh;
|
bh = prev_bh;
|
||||||
if (!written)
|
if (!written)
|
||||||
written = PTR_ERR(bh);
|
written = PTR_ERR(bh);
|
||||||
|
@ -131,13 +131,16 @@ skip:
|
|||||||
hfs_bnode_write(node, entry, data_off + key_len, entry_len);
|
hfs_bnode_write(node, entry, data_off + key_len, entry_len);
|
||||||
hfs_bnode_dump(node);
|
hfs_bnode_dump(node);
|
||||||
|
|
||||||
if (new_node) {
|
/*
|
||||||
/* update parent key if we inserted a key
|
* update parent key if we inserted a key
|
||||||
* at the start of the first node
|
* at the start of the node and it is not the new node
|
||||||
*/
|
*/
|
||||||
if (!rec && new_node != node)
|
if (!rec && new_node != node) {
|
||||||
hfs_brec_update_parent(fd);
|
hfs_bnode_read_key(node, fd->search_key, data_off + size);
|
||||||
|
hfs_brec_update_parent(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_node) {
|
||||||
hfs_bnode_put(fd->bnode);
|
hfs_bnode_put(fd->bnode);
|
||||||
if (!new_node->parent) {
|
if (!new_node->parent) {
|
||||||
hfs_btree_inc_height(tree);
|
hfs_btree_inc_height(tree);
|
||||||
@ -168,9 +171,6 @@ skip:
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rec)
|
|
||||||
hfs_brec_update_parent(fd);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +370,8 @@ again:
|
|||||||
if (IS_ERR(parent))
|
if (IS_ERR(parent))
|
||||||
return PTR_ERR(parent);
|
return PTR_ERR(parent);
|
||||||
__hfs_brec_find(parent, fd, hfs_find_rec_by_key);
|
__hfs_brec_find(parent, fd, hfs_find_rec_by_key);
|
||||||
|
if (fd->record < 0)
|
||||||
|
return -ENOENT;
|
||||||
hfs_bnode_dump(parent);
|
hfs_bnode_dump(parent);
|
||||||
rec = fd->record;
|
rec = fd->record;
|
||||||
|
|
||||||
|
@ -1625,11 +1625,11 @@ struct task_struct {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* numa_faults_locality tracks if faults recorded during the last
|
* numa_faults_locality tracks if faults recorded during the last
|
||||||
* scan window were remote/local. The task scan period is adapted
|
* scan window were remote/local or failed to migrate. The task scan
|
||||||
* based on the locality of the faults with different weights
|
* period is adapted based on the locality of the faults with different
|
||||||
* depending on whether they were shared or private faults
|
* weights depending on whether they were shared or private faults
|
||||||
*/
|
*/
|
||||||
unsigned long numa_faults_locality[2];
|
unsigned long numa_faults_locality[3];
|
||||||
|
|
||||||
unsigned long numa_pages_migrated;
|
unsigned long numa_pages_migrated;
|
||||||
#endif /* CONFIG_NUMA_BALANCING */
|
#endif /* CONFIG_NUMA_BALANCING */
|
||||||
@ -1719,6 +1719,7 @@ struct task_struct {
|
|||||||
#define TNF_NO_GROUP 0x02
|
#define TNF_NO_GROUP 0x02
|
||||||
#define TNF_SHARED 0x04
|
#define TNF_SHARED 0x04
|
||||||
#define TNF_FAULT_LOCAL 0x08
|
#define TNF_FAULT_LOCAL 0x08
|
||||||
|
#define TNF_MIGRATE_FAIL 0x10
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA_BALANCING
|
#ifdef CONFIG_NUMA_BALANCING
|
||||||
extern void task_numa_fault(int last_node, int node, int pages, int flags);
|
extern void task_numa_fault(int last_node, int node, int pages, int flags);
|
||||||
|
@ -1609,9 +1609,11 @@ static void update_task_scan_period(struct task_struct *p,
|
|||||||
/*
|
/*
|
||||||
* If there were no record hinting faults then either the task is
|
* If there were no record hinting faults then either the task is
|
||||||
* completely idle or all activity is areas that are not of interest
|
* completely idle or all activity is areas that are not of interest
|
||||||
* to automatic numa balancing. Scan slower
|
* to automatic numa balancing. Related to that, if there were failed
|
||||||
|
* migration then it implies we are migrating too quickly or the local
|
||||||
|
* node is overloaded. In either case, scan slower
|
||||||
*/
|
*/
|
||||||
if (local + shared == 0) {
|
if (local + shared == 0 || p->numa_faults_locality[2]) {
|
||||||
p->numa_scan_period = min(p->numa_scan_period_max,
|
p->numa_scan_period = min(p->numa_scan_period_max,
|
||||||
p->numa_scan_period << 1);
|
p->numa_scan_period << 1);
|
||||||
|
|
||||||
@ -2080,6 +2082,8 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags)
|
|||||||
|
|
||||||
if (migrated)
|
if (migrated)
|
||||||
p->numa_pages_migrated += pages;
|
p->numa_pages_migrated += pages;
|
||||||
|
if (flags & TNF_MIGRATE_FAIL)
|
||||||
|
p->numa_faults_locality[2] += pages;
|
||||||
|
|
||||||
p->numa_faults[task_faults_idx(NUMA_MEMBUF, mem_node, priv)] += pages;
|
p->numa_faults[task_faults_idx(NUMA_MEMBUF, mem_node, priv)] += pages;
|
||||||
p->numa_faults[task_faults_idx(NUMA_CPUBUF, cpu_node, priv)] += pages;
|
p->numa_faults[task_faults_idx(NUMA_CPUBUF, cpu_node, priv)] += pages;
|
||||||
|
@ -1260,6 +1260,7 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
int target_nid, last_cpupid = -1;
|
int target_nid, last_cpupid = -1;
|
||||||
bool page_locked;
|
bool page_locked;
|
||||||
bool migrated = false;
|
bool migrated = false;
|
||||||
|
bool was_writable;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
/* A PROT_NONE fault should not end up here */
|
/* 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,
|
|||||||
flags |= TNF_FAULT_LOCAL;
|
flags |= TNF_FAULT_LOCAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* See similar comment in do_numa_page for explanation */
|
||||||
* Avoid grouping on DSO/COW pages in specific and RO pages
|
if (!(vma->vm_flags & VM_WRITE))
|
||||||
* in general, RO pages shouldn't hurt as much anyway since
|
|
||||||
* they can be in shared cache state.
|
|
||||||
*
|
|
||||||
* FIXME! This checks "pmd_dirty()" as an approximation of
|
|
||||||
* "is this a read-only page", since checking "pmd_write()"
|
|
||||||
* is even more broken. We haven't actually turned this into
|
|
||||||
* a writable page, so pmd_write() will always be false.
|
|
||||||
*/
|
|
||||||
if (!pmd_dirty(pmd))
|
|
||||||
flags |= TNF_NO_GROUP;
|
flags |= TNF_NO_GROUP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1358,12 +1350,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
if (migrated) {
|
if (migrated) {
|
||||||
flags |= TNF_MIGRATED;
|
flags |= TNF_MIGRATED;
|
||||||
page_nid = target_nid;
|
page_nid = target_nid;
|
||||||
}
|
} else
|
||||||
|
flags |= TNF_MIGRATE_FAIL;
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
clear_pmdnuma:
|
clear_pmdnuma:
|
||||||
BUG_ON(!PageLocked(page));
|
BUG_ON(!PageLocked(page));
|
||||||
|
was_writable = pmd_write(pmd);
|
||||||
pmd = pmd_modify(pmd, vma->vm_page_prot);
|
pmd = pmd_modify(pmd, vma->vm_page_prot);
|
||||||
|
pmd = pmd_mkyoung(pmd);
|
||||||
|
if (was_writable)
|
||||||
|
pmd = pmd_mkwrite(pmd);
|
||||||
set_pmd_at(mm, haddr, pmdp, pmd);
|
set_pmd_at(mm, haddr, pmdp, pmd);
|
||||||
update_mmu_cache_pmd(vma, addr, pmdp);
|
update_mmu_cache_pmd(vma, addr, pmdp);
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
@ -1487,6 +1484,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
|
|||||||
|
|
||||||
if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
|
if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
|
||||||
pmd_t entry;
|
pmd_t entry;
|
||||||
|
bool preserve_write = prot_numa && pmd_write(*pmd);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1502,9 +1500,11 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
|
|||||||
if (!prot_numa || !pmd_protnone(*pmd)) {
|
if (!prot_numa || !pmd_protnone(*pmd)) {
|
||||||
entry = pmdp_get_and_clear_notify(mm, addr, pmd);
|
entry = pmdp_get_and_clear_notify(mm, addr, pmd);
|
||||||
entry = pmd_modify(entry, newprot);
|
entry = pmd_modify(entry, newprot);
|
||||||
|
if (preserve_write)
|
||||||
|
entry = pmd_mkwrite(entry);
|
||||||
ret = HPAGE_PMD_NR;
|
ret = HPAGE_PMD_NR;
|
||||||
set_pmd_at(mm, addr, pmd, entry);
|
set_pmd_at(mm, addr, pmd, entry);
|
||||||
BUG_ON(pmd_write(entry));
|
BUG_ON(!preserve_write && pmd_write(entry));
|
||||||
}
|
}
|
||||||
spin_unlock(ptl);
|
spin_unlock(ptl);
|
||||||
}
|
}
|
||||||
|
22
mm/memory.c
22
mm/memory.c
@ -3035,6 +3035,7 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
int last_cpupid;
|
int last_cpupid;
|
||||||
int target_nid;
|
int target_nid;
|
||||||
bool migrated = false;
|
bool migrated = false;
|
||||||
|
bool was_writable = pte_write(pte);
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
/* A PROT_NONE fault should not end up here */
|
/* 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,
|
|||||||
/* Make it present again */
|
/* Make it present again */
|
||||||
pte = pte_modify(pte, vma->vm_page_prot);
|
pte = pte_modify(pte, vma->vm_page_prot);
|
||||||
pte = pte_mkyoung(pte);
|
pte = pte_mkyoung(pte);
|
||||||
|
if (was_writable)
|
||||||
|
pte = pte_mkwrite(pte);
|
||||||
set_pte_at(mm, addr, ptep, pte);
|
set_pte_at(mm, addr, ptep, pte);
|
||||||
update_mmu_cache(vma, addr, ptep);
|
update_mmu_cache(vma, addr, ptep);
|
||||||
|
|
||||||
@ -3069,16 +3072,14 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid grouping on DSO/COW pages in specific and RO pages
|
* Avoid grouping on RO pages in general. RO pages shouldn't hurt as
|
||||||
* in general, RO pages shouldn't hurt as much anyway since
|
* much anyway since they can be in shared cache state. This misses
|
||||||
* they can be in shared cache state.
|
* the case where a mapping is writable but the process never writes
|
||||||
*
|
* to it but pte_write gets cleared during protection updates and
|
||||||
* FIXME! This checks "pmd_dirty()" as an approximation of
|
* pte_dirty has unpredictable behaviour between PTE scan updates,
|
||||||
* "is this a read-only page", since checking "pmd_write()"
|
* background writeback, dirty balancing and application behaviour.
|
||||||
* is even more broken. We haven't actually turned this into
|
|
||||||
* a writable page, so pmd_write() will always be false.
|
|
||||||
*/
|
*/
|
||||||
if (!pte_dirty(pte))
|
if (!(vma->vm_flags & VM_WRITE))
|
||||||
flags |= TNF_NO_GROUP;
|
flags |= TNF_NO_GROUP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3102,7 +3103,8 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
if (migrated) {
|
if (migrated) {
|
||||||
page_nid = target_nid;
|
page_nid = target_nid;
|
||||||
flags |= TNF_MIGRATED;
|
flags |= TNF_MIGRATED;
|
||||||
}
|
} else
|
||||||
|
flags |= TNF_MIGRATE_FAIL;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (page_nid != -1)
|
if (page_nid != -1)
|
||||||
|
@ -1092,6 +1092,10 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
arch_refresh_nodedata(nid, pgdat);
|
arch_refresh_nodedata(nid, pgdat);
|
||||||
|
} else {
|
||||||
|
/* Reset the nr_zones and classzone_idx to 0 before reuse */
|
||||||
|
pgdat->nr_zones = 0;
|
||||||
|
pgdat->classzone_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can use NODE_DATA(nid) from here */
|
/* we can use NODE_DATA(nid) from here */
|
||||||
@ -1977,15 +1981,6 @@ void try_offline_node(int nid)
|
|||||||
if (is_vmalloc_addr(zone->wait_table))
|
if (is_vmalloc_addr(zone->wait_table))
|
||||||
vfree(zone->wait_table);
|
vfree(zone->wait_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Since there is no way to guarentee the address of pgdat/zone is not
|
|
||||||
* on stack of any kernel threads or used by other kernel objects
|
|
||||||
* without reference counting or other symchronizing method, do not
|
|
||||||
* reset node_data and free pgdat here. Just reset it to 0 and reuse
|
|
||||||
* the memory when the node is online again.
|
|
||||||
*/
|
|
||||||
memset(pgdat, 0, sizeof(*pgdat));
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(try_offline_node);
|
EXPORT_SYMBOL(try_offline_node);
|
||||||
|
|
||||||
|
@ -774,10 +774,8 @@ again: remove_next = 1 + (end > next->vm_end);
|
|||||||
|
|
||||||
importer->anon_vma = exporter->anon_vma;
|
importer->anon_vma = exporter->anon_vma;
|
||||||
error = anon_vma_clone(importer, exporter);
|
error = anon_vma_clone(importer, exporter);
|
||||||
if (error) {
|
if (error)
|
||||||
importer->anon_vma = NULL;
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
|
|||||||
oldpte = *pte;
|
oldpte = *pte;
|
||||||
if (pte_present(oldpte)) {
|
if (pte_present(oldpte)) {
|
||||||
pte_t ptent;
|
pte_t ptent;
|
||||||
|
bool preserve_write = prot_numa && pte_write(oldpte);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid trapping faults against the zero or KSM
|
* Avoid trapping faults against the zero or KSM
|
||||||
@ -94,6 +95,8 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
|
|||||||
|
|
||||||
ptent = ptep_modify_prot_start(mm, addr, pte);
|
ptent = ptep_modify_prot_start(mm, addr, pte);
|
||||||
ptent = pte_modify(ptent, newprot);
|
ptent = pte_modify(ptent, newprot);
|
||||||
|
if (preserve_write)
|
||||||
|
ptent = pte_mkwrite(ptent);
|
||||||
|
|
||||||
/* Avoid taking write faults for known dirty pages */
|
/* Avoid taking write faults for known dirty pages */
|
||||||
if (dirty_accountable && pte_dirty(ptent) &&
|
if (dirty_accountable && pte_dirty(ptent) &&
|
||||||
|
@ -103,6 +103,7 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
|
|||||||
|
|
||||||
if (!is_migrate_isolate_page(buddy)) {
|
if (!is_migrate_isolate_page(buddy)) {
|
||||||
__isolate_free_page(page, order);
|
__isolate_free_page(page, order);
|
||||||
|
kernel_map_pages(page, (1 << order), 1);
|
||||||
set_page_refcounted(page);
|
set_page_refcounted(page);
|
||||||
isolated_page = page;
|
isolated_page = page;
|
||||||
}
|
}
|
||||||
|
@ -265,8 +265,15 @@ int walk_page_range(unsigned long start, unsigned long end,
|
|||||||
vma = vma->vm_next;
|
vma = vma->vm_next;
|
||||||
|
|
||||||
err = walk_page_test(start, next, walk);
|
err = walk_page_test(start, next, walk);
|
||||||
if (err > 0)
|
if (err > 0) {
|
||||||
|
/*
|
||||||
|
* positive return values are purely for
|
||||||
|
* controlling the pagewalk, so should never
|
||||||
|
* be passed to the callers.
|
||||||
|
*/
|
||||||
|
err = 0;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -287,6 +287,13 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
enomem_failure:
|
enomem_failure:
|
||||||
|
/*
|
||||||
|
* dst->anon_vma is dropped here otherwise its degree can be incorrectly
|
||||||
|
* decremented in unlink_anon_vmas().
|
||||||
|
* We can safely do this because callers of anon_vma_clone() don't care
|
||||||
|
* about dst->anon_vma if anon_vma_clone() failed.
|
||||||
|
*/
|
||||||
|
dst->anon_vma = NULL;
|
||||||
unlink_anon_vmas(dst);
|
unlink_anon_vmas(dst);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -2449,7 +2449,8 @@ redo:
|
|||||||
do {
|
do {
|
||||||
tid = this_cpu_read(s->cpu_slab->tid);
|
tid = this_cpu_read(s->cpu_slab->tid);
|
||||||
c = raw_cpu_ptr(s->cpu_slab);
|
c = raw_cpu_ptr(s->cpu_slab);
|
||||||
} while (IS_ENABLED(CONFIG_PREEMPT) && unlikely(tid != c->tid));
|
} while (IS_ENABLED(CONFIG_PREEMPT) &&
|
||||||
|
unlikely(tid != READ_ONCE(c->tid)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Irqless object alloc/free algorithm used here depends on sequence
|
* Irqless object alloc/free algorithm used here depends on sequence
|
||||||
@ -2718,7 +2719,8 @@ redo:
|
|||||||
do {
|
do {
|
||||||
tid = this_cpu_read(s->cpu_slab->tid);
|
tid = this_cpu_read(s->cpu_slab->tid);
|
||||||
c = raw_cpu_ptr(s->cpu_slab);
|
c = raw_cpu_ptr(s->cpu_slab);
|
||||||
} while (IS_ENABLED(CONFIG_PREEMPT) && unlikely(tid != c->tid));
|
} while (IS_ENABLED(CONFIG_PREEMPT) &&
|
||||||
|
unlikely(tid != READ_ONCE(c->tid)));
|
||||||
|
|
||||||
/* Same with comment on barrier() in slab_alloc_node() */
|
/* Same with comment on barrier() in slab_alloc_node() */
|
||||||
barrier();
|
barrier();
|
||||||
|
Loading…
Reference in New Issue
Block a user