Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 320817
b: refs/heads/master
c: 702d1a6
h: refs/heads/master
i:
  320815: f32dc24
v: v3
  • Loading branch information
Minchan Kim authored and Linus Torvalds committed Aug 1, 2012
1 parent c9b9c45 commit 2eefb2c
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2cfed0752808625d30aca7fc9f383af386fd8a13
refs/heads/master: 702d1a6e0766d45642c934444fd41f658d251305
8 changes: 8 additions & 0 deletions trunk/include/linux/mmzone.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,14 @@ struct zone {
* rarely used fields:
*/
const char *name;
#ifdef CONFIG_MEMORY_ISOLATION
/*
* the number of MIGRATE_ISOLATE *pageblock*.
* We need this for free page counting. Look at zone_watermark_ok_safe.
* It's protected by zone->lock
*/
int nr_pageblock_isolate;
#endif
} ____cacheline_internodealigned_in_smp;

typedef enum {
Expand Down
30 changes: 30 additions & 0 deletions trunk/mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ EXPORT_SYMBOL(nr_online_nodes);

int page_group_by_mobility_disabled __read_mostly;

/*
* NOTE:
* Don't use set_pageblock_migratetype(page, MIGRATE_ISOLATE) directly.
* Instead, use {un}set_pageblock_isolate.
*/
void set_pageblock_migratetype(struct page *page, int migratetype)
{

Expand Down Expand Up @@ -1619,6 +1624,20 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
return true;
}

#ifdef CONFIG_MEMORY_ISOLATION
static inline unsigned long nr_zone_isolate_freepages(struct zone *zone)
{
if (unlikely(zone->nr_pageblock_isolate))
return zone->nr_pageblock_isolate * pageblock_nr_pages;
return 0;
}
#else
static inline unsigned long nr_zone_isolate_freepages(struct zone *zone)
{
return 0;
}
#endif

bool zone_watermark_ok(struct zone *z, int order, unsigned long mark,
int classzone_idx, int alloc_flags)
{
Expand All @@ -1634,6 +1653,14 @@ bool zone_watermark_ok_safe(struct zone *z, int order, unsigned long mark,
if (z->percpu_drift_mark && free_pages < z->percpu_drift_mark)
free_pages = zone_page_state_snapshot(z, NR_FREE_PAGES);

/*
* If the zone has MIGRATE_ISOLATE type free pages, we should consider
* it. nr_zone_isolate_freepages is never accurate so kswapd might not
* sleep although it could do so. But this is more desirable for memory
* hotplug than sleeping which can cause a livelock in the direct
* reclaim path.
*/
free_pages -= nr_zone_isolate_freepages(z);
return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
free_pages);
}
Expand Down Expand Up @@ -4398,6 +4425,9 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
lruvec_init(&zone->lruvec, zone);
zap_zone_vm_stats(zone);
zone->flags = 0;
#ifdef CONFIG_MEMORY_ISOLATION
zone->nr_pageblock_isolate = 0;
#endif
if (!size)
continue;

Expand Down
26 changes: 24 additions & 2 deletions trunk/mm/page_isolation.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@
#include <linux/memory.h>
#include "internal.h"

/* called while holding zone->lock */
static void set_pageblock_isolate(struct page *page)
{
if (get_pageblock_migratetype(page) == MIGRATE_ISOLATE)
return;

set_pageblock_migratetype(page, MIGRATE_ISOLATE);
page_zone(page)->nr_pageblock_isolate++;
}

/* called while holding zone->lock */
static void restore_pageblock_isolate(struct page *page, int migratetype)
{
struct zone *zone = page_zone(page);
if (WARN_ON(get_pageblock_migratetype(page) != MIGRATE_ISOLATE))
return;

BUG_ON(zone->nr_pageblock_isolate <= 0);
set_pageblock_migratetype(page, migratetype);
zone->nr_pageblock_isolate--;
}

int set_migratetype_isolate(struct page *page)
{
struct zone *zone;
Expand Down Expand Up @@ -54,7 +76,7 @@ int set_migratetype_isolate(struct page *page)

out:
if (!ret) {
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
set_pageblock_isolate(page);
move_freepages_block(zone, page, MIGRATE_ISOLATE);
}

Expand All @@ -72,8 +94,8 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
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);
restore_pageblock_isolate(page, migratetype);
out:
spin_unlock_irqrestore(&zone->lock, flags);
}
Expand Down

0 comments on commit 2eefb2c

Please sign in to comment.