|
@@ -51,7 +51,6 @@
|
|
|
#include <linux/page_cgroup.h>
|
|
|
#include <linux/debugobjects.h>
|
|
|
#include <linux/kmemleak.h>
|
|
|
-#include <linux/memory.h>
|
|
|
#include <linux/compaction.h>
|
|
|
#include <trace/events/kmem.h>
|
|
|
#include <linux/ftrace_event.h>
|
|
@@ -219,7 +218,7 @@ EXPORT_SYMBOL(nr_online_nodes);
|
|
|
|
|
|
int page_group_by_mobility_disabled __read_mostly;
|
|
|
|
|
|
-static void set_pageblock_migratetype(struct page *page, int migratetype)
|
|
|
+void set_pageblock_migratetype(struct page *page, int migratetype)
|
|
|
{
|
|
|
|
|
|
if (unlikely(page_group_by_mobility_disabled))
|
|
@@ -954,7 +953,7 @@ static int move_freepages(struct zone *zone,
|
|
|
return pages_moved;
|
|
|
}
|
|
|
|
|
|
-static int move_freepages_block(struct zone *zone, struct page *page,
|
|
|
+int move_freepages_block(struct zone *zone, struct page *page,
|
|
|
int migratetype)
|
|
|
{
|
|
|
unsigned long start_pfn, end_pfn;
|
|
@@ -5463,8 +5462,7 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
|
|
|
* MIGRATE_MOVABLE block might include unmovable pages. It means you can't
|
|
|
* expect this function should be exact.
|
|
|
*/
|
|
|
-static bool
|
|
|
-__has_unmovable_pages(struct zone *zone, struct page *page, int count)
|
|
|
+bool has_unmovable_pages(struct zone *zone, struct page *page, int count)
|
|
|
{
|
|
|
unsigned long pfn, iter, found;
|
|
|
int mt;
|
|
@@ -5541,77 +5539,7 @@ bool is_pageblock_removable_nolock(struct page *page)
|
|
|
zone->zone_start_pfn + zone->spanned_pages <= pfn)
|
|
|
return false;
|
|
|
|
|
|
- return !__has_unmovable_pages(zone, page, 0);
|
|
|
-}
|
|
|
-
|
|
|
-int set_migratetype_isolate(struct page *page)
|
|
|
-{
|
|
|
- struct zone *zone;
|
|
|
- unsigned long flags, pfn;
|
|
|
- struct memory_isolate_notify arg;
|
|
|
- int notifier_ret;
|
|
|
- int ret = -EBUSY;
|
|
|
-
|
|
|
- zone = page_zone(page);
|
|
|
-
|
|
|
- spin_lock_irqsave(&zone->lock, flags);
|
|
|
-
|
|
|
- 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)
|
|
|
- goto out;
|
|
|
- /*
|
|
|
- * FIXME: Now, memory hotplug doesn't call shrink_slab() by itself.
|
|
|
- * We just check MOVABLE pages.
|
|
|
- */
|
|
|
- if (!__has_unmovable_pages(zone, page, arg.pages_found))
|
|
|
- ret = 0;
|
|
|
- /*
|
|
|
- * Unmovable means "not-on-lru" pages. If Unmovable pages are
|
|
|
- * larger than removable-by-driver pages reported by notifier,
|
|
|
- * we'll fail.
|
|
|
- */
|
|
|
-
|
|
|
-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();
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-void unset_migratetype_isolate(struct page *page, unsigned migratetype)
|
|
|
-{
|
|
|
- struct zone *zone;
|
|
|
- unsigned long flags;
|
|
|
- zone = page_zone(page);
|
|
|
- spin_lock_irqsave(&zone->lock, flags);
|
|
|
- if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
|
|
|
- goto out;
|
|
|
- set_pageblock_migratetype(page, migratetype);
|
|
|
- move_freepages_block(zone, page, migratetype);
|
|
|
-out:
|
|
|
- spin_unlock_irqrestore(&zone->lock, flags);
|
|
|
+ return !has_unmovable_pages(zone, page, 0);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_CMA
|