Skip to content

Commit

Permalink
mm, page_owner: don't grab zone->lock for init_pages_in_zone()
Browse files Browse the repository at this point in the history
init_pages_in_zone() is run under zone->lock, which means a long lock
time and disabled interrupts on large machines.  This is currently not
an issue since it runs early in boot, but a later patch will change
that.

However, like other pfn scanners, we don't actually need zone->lock even
when other cpus are running.  The only potentially dangerous operation
here is reading bogus buddy page owner due to race, and we already know
how to handle that.  The worst that can happen is that we skip some
early allocated pages, which should not affect the debugging power of
page_owner noticeably.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Vlastimil Babka <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Yang Shi <[email protected]>
Cc: Laura Abbott <[email protected]>
Cc: Vinayak Menon <[email protected]>
Cc: zhong jiang <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
tehcaster authored and torvalds committed Sep 7, 2017
1 parent 0fc542b commit 1090302
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions mm/page_owner.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,11 +562,17 @@ static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone)
continue;

/*
* We are safe to check buddy flag and order, because
* this is init stage and only single thread runs.
* To avoid having to grab zone->lock, be a little
* careful when reading buddy page order. The only
* danger is that we skip too much and potentially miss
* some early allocated pages, which is better than
* heavy lock contention.
*/
if (PageBuddy(page)) {
pfn += (1UL << page_order(page)) - 1;
unsigned long order = page_order_unsafe(page);

if (order > 0 && order < MAX_ORDER)
pfn += (1UL << order) - 1;
continue;
}

Expand All @@ -585,6 +591,7 @@ static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone)
__set_page_owner_handle(page_ext, early_handle, 0, 0);
count++;
}
cond_resched();
}

pr_info("Node %d, zone %8s: page owner found early allocated %lu pages\n",
Expand All @@ -595,15 +602,12 @@ static void init_zones_in_node(pg_data_t *pgdat)
{
struct zone *zone;
struct zone *node_zones = pgdat->node_zones;
unsigned long flags;

for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
if (!populated_zone(zone))
continue;

spin_lock_irqsave(&zone->lock, flags);
init_pages_in_zone(pgdat, zone);
spin_unlock_irqrestore(&zone->lock, flags);
}
}

Expand Down

0 comments on commit 1090302

Please sign in to comment.