Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (36 commits) powerpc/gc/wii: Remove get_irq_desc() powerpc/gc/wii: hlwd-pic: convert irq_desc.lock to raw_spinlock powerpc/gamecube/wii: Fix off-by-one error in ugecon/usbgecko_udbg powerpc/mpic: Fix problem that affinity is not updated powerpc/mm: Fix stupid bug in subpge protection handling powerpc/iseries: use DECLARE_COMPLETION_ONSTACK for non-constant completion powerpc: Fix MSI support on U4 bridge PCIe slot powerpc: Handle VSX alignment faults correctly in little-endian mode powerpc/mm: Fix typo of cpumask_clear_cpu() powerpc/mm: Fix hash_utils_64.c compile errors with DEBUG enabled. powerpc: Convert BUG() to use unreachable() powerpc/pseries: Make declarations of cpu_hotplug_driver_lock() ANSI compatible. powerpc/pseries: Don't panic when H_PROD fails during cpu-online. powerpc/mm: Fix a WARN_ON() with CONFIG_DEBUG_PAGEALLOC and CONFIG_DEBUG_VM powerpc/defconfigs: Set HZ=100 on pseries and ppc64 defconfigs powerpc/defconfigs: Disable token ring in powerpc defconfigs powerpc/defconfigs: Reduce 64bit vmlinux by making acenic and cramfs modules powerpc/pseries: Select XICS and PCI_MSI PSERIES powerpc/85xx: Wrong variable returned on error powerpc/iseries: Convert to proc_fops ...
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include <linux/page_cgroup.h>
|
||||
#include <linux/debugobjects.h>
|
||||
#include <linux/kmemleak.h>
|
||||
#include <linux/memory.h>
|
||||
#include <trace/events/kmem.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
@@ -5008,23 +5009,65 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
|
||||
int set_migratetype_isolate(struct page *page)
|
||||
{
|
||||
struct zone *zone;
|
||||
unsigned long flags;
|
||||
struct page *curr_page;
|
||||
unsigned long flags, pfn, iter;
|
||||
unsigned long immobile = 0;
|
||||
struct memory_isolate_notify arg;
|
||||
int notifier_ret;
|
||||
int ret = -EBUSY;
|
||||
int zone_idx;
|
||||
|
||||
zone = page_zone(page);
|
||||
zone_idx = zone_idx(zone);
|
||||
|
||||
spin_lock_irqsave(&zone->lock, flags);
|
||||
/*
|
||||
* In future, more migrate types will be able to be isolation target.
|
||||
*/
|
||||
if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE &&
|
||||
zone_idx != ZONE_MOVABLE)
|
||||
if (get_pageblock_migratetype(page) == MIGRATE_MOVABLE ||
|
||||
zone_idx == ZONE_MOVABLE) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
|
||||
move_freepages_block(zone, page, MIGRATE_ISOLATE);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
pfn = page_to_pfn(page);
|
||||
arg.start_pfn = pfn;
|
||||
arg.nr_pages = pageblock_nr_pages;
|
||||
arg.pages_found = 0;
|
||||
|
||||
/*
|
||||
* It may be possible to isolate a pageblock even if the
|
||||
* migratetype is not MIGRATE_MOVABLE. The memory isolation
|
||||
* notifier chain is used by balloon drivers to return the
|
||||
* number of pages in a range that are held by the balloon
|
||||
* driver to shrink memory. If all the pages are accounted for
|
||||
* by balloons, are free, or on the LRU, isolation can continue.
|
||||
* Later, for example, when memory hotplug notifier runs, these
|
||||
* pages reported as "can be isolated" should be isolated(freed)
|
||||
* by the balloon driver through the memory notifier chain.
|
||||
*/
|
||||
notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg);
|
||||
notifier_ret = notifier_to_errno(notifier_ret);
|
||||
if (notifier_ret || !arg.pages_found)
|
||||
goto out;
|
||||
|
||||
for (iter = pfn; iter < (pfn + pageblock_nr_pages); iter++) {
|
||||
if (!pfn_valid_within(pfn))
|
||||
continue;
|
||||
|
||||
curr_page = pfn_to_page(iter);
|
||||
if (!page_count(curr_page) || PageLRU(curr_page))
|
||||
continue;
|
||||
|
||||
immobile++;
|
||||
}
|
||||
|
||||
if (arg.pages_found == immobile)
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (!ret) {
|
||||
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
|
||||
move_freepages_block(zone, page, MIGRATE_ISOLATE);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&zone->lock, flags);
|
||||
if (!ret)
|
||||
drain_all_pages();
|
||||
|
Reference in New Issue
Block a user