Skip to content

Commit

Permalink
mm/page_alloc.c: memory hotplug: free pages as higher order
Browse files Browse the repository at this point in the history
When freeing pages are done with higher order, time spent on coalescing
pages by buddy allocator can be reduced.  With section size of 256MB,
hot add latency of a single section shows improvement from 50-60 ms to
less than 1 ms, hence improving the hot add latency by 60 times.  Modify
external providers of online callback to align with the change.

[[email protected]: v11]
  Link: http://lkml.kernel.org/r/[email protected]
[[email protected]: remove unused local, per Arun]
[[email protected]: avoid return of void-returning __free_pages_core(), per Oscar]
[[email protected]: fix it for mm-convert-totalram_pages-and-totalhigh_pages-variables-to-atomic.patch]
[[email protected]: v8]
  Link: http://lkml.kernel.org/r/[email protected]
[[email protected]: v9]
  Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arun KS <[email protected]>
Reviewed-by: Andrew Morton <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Reviewed-by: Oscar Salvador <[email protected]>
Reviewed-by: Alexander Duyck <[email protected]>
Cc: K. Y. Srinivasan <[email protected]>
Cc: Haiyang Zhang <[email protected]>
Cc: Stephen Hemminger <[email protected]>
Cc: Boris Ostrovsky <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Mathieu Malaterre <[email protected]>
Cc: "Kirill A. Shutemov" <[email protected]>
Cc: Souptick Joarder <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Aaron Lu <[email protected]>
Cc: Srivatsa Vaddagiri <[email protected]>
Cc: Vinayak Menon <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Arun KS authored and torvalds committed Mar 6, 2019
1 parent 278d775 commit a9cd410
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 25 deletions.
7 changes: 4 additions & 3 deletions drivers/hv/hv_balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
}
}

static void hv_online_page(struct page *pg)
static void hv_online_page(struct page *pg, unsigned int order)
{
struct hv_hotadd_state *has;
unsigned long flags;
Expand All @@ -780,10 +780,11 @@ static void hv_online_page(struct page *pg)
spin_lock_irqsave(&dm_device.ha_lock, flags);
list_for_each_entry(has, &dm_device.ha_region_list, list) {
/* The page belongs to a different HAS. */
if ((pfn < has->start_pfn) || (pfn >= has->end_pfn))
if ((pfn < has->start_pfn) ||
(pfn + (1UL << order) > has->end_pfn))
continue;

hv_page_online_one(has, pg);
hv_bring_pgs_online(has, pfn, 1UL << order);
break;
}
spin_unlock_irqrestore(&dm_device.ha_lock, flags);
Expand Down
15 changes: 10 additions & 5 deletions drivers/xen/balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,14 +369,19 @@ static enum bp_state reserve_additional_memory(void)
return BP_ECANCELED;
}

static void xen_online_page(struct page *page)
static void xen_online_page(struct page *page, unsigned int order)
{
__online_page_set_limits(page);
unsigned long i, size = (1 << order);
unsigned long start_pfn = page_to_pfn(page);
struct page *p;

pr_debug("Online %lu pages starting at pfn 0x%lx\n", size, start_pfn);
mutex_lock(&balloon_mutex);

__balloon_append(page);

for (i = 0; i < size; i++) {
p = pfn_to_page(start_pfn + i);
__online_page_set_limits(p);
__balloon_append(p);
}
mutex_unlock(&balloon_mutex);
}

Expand Down
2 changes: 1 addition & 1 deletion include/linux/memory_hotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
unsigned long *valid_start, unsigned long *valid_end);
extern void __offline_isolated_pages(unsigned long, unsigned long);

typedef void (*online_page_callback_t)(struct page *page);
typedef void (*online_page_callback_t)(struct page *page, unsigned int order);

extern int set_online_page_callback(online_page_callback_t callback);
extern int restore_online_page_callback(online_page_callback_t callback);
Expand Down
1 change: 1 addition & 0 deletions mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static inline struct page *pageblock_pfn_to_page(unsigned long start_pfn,
extern int __isolate_free_page(struct page *page, unsigned int order);
extern void memblock_free_pages(struct page *page, unsigned long pfn,
unsigned int order);
extern void __free_pages_core(struct page *page, unsigned int order);
extern void prep_compound_page(struct page *page, unsigned int order);
extern void post_alloc_hook(struct page *page, unsigned int order,
gfp_t gfp_flags);
Expand Down
37 changes: 25 additions & 12 deletions mm/memory_hotplug.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* and restore_online_page_callback() for generic callback restore.
*/

static void generic_online_page(struct page *page);
static void generic_online_page(struct page *page, unsigned int order);

static online_page_callback_t online_page_callback = generic_online_page;
static DEFINE_MUTEX(online_page_callback_lock);
Expand Down Expand Up @@ -656,26 +656,39 @@ void __online_page_free(struct page *page)
}
EXPORT_SYMBOL_GPL(__online_page_free);

static void generic_online_page(struct page *page)
static void generic_online_page(struct page *page, unsigned int order)
{
__online_page_set_limits(page);
__online_page_increment_counters(page);
__online_page_free(page);
__free_pages_core(page, order);
totalram_pages_add(1UL << order);
#ifdef CONFIG_HIGHMEM
if (PageHighMem(page))
totalhigh_pages_add(1UL << order);
#endif
}

static int online_pages_blocks(unsigned long start, unsigned long nr_pages)
{
unsigned long end = start + nr_pages;
int order, onlined_pages = 0;

while (start < end) {
order = min(MAX_ORDER - 1,
get_order(PFN_PHYS(end) - PFN_PHYS(start)));
(*online_page_callback)(pfn_to_page(start), order);

onlined_pages += (1UL << order);
start += (1UL << order);
}
return onlined_pages;
}

static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
void *arg)
{
unsigned long i;
unsigned long onlined_pages = *(unsigned long *)arg;
struct page *page;

if (PageReserved(pfn_to_page(start_pfn)))
for (i = 0; i < nr_pages; i++) {
page = pfn_to_page(start_pfn + i);
(*online_page_callback)(page);
onlined_pages++;
}
onlined_pages += online_pages_blocks(start_pfn, nr_pages);

online_mem_sections(start_pfn, start_pfn + nr_pages);

Expand Down
8 changes: 4 additions & 4 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
local_irq_restore(flags);
}

static void __init __free_pages_boot_core(struct page *page, unsigned int order)
void __free_pages_core(struct page *page, unsigned int order)
{
unsigned int nr_pages = 1 << order;
struct page *p = page;
Expand Down Expand Up @@ -1382,7 +1382,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
{
if (early_page_uninitialised(pfn))
return;
return __free_pages_boot_core(page, order);
__free_pages_core(page, order);
}

/*
Expand Down Expand Up @@ -1472,14 +1472,14 @@ static void __init deferred_free_range(unsigned long pfn,
if (nr_pages == pageblock_nr_pages &&
(pfn & (pageblock_nr_pages - 1)) == 0) {
set_pageblock_migratetype(page, MIGRATE_MOVABLE);
__free_pages_boot_core(page, pageblock_order);
__free_pages_core(page, pageblock_order);
return;
}

for (i = 0; i < nr_pages; i++, page++, pfn++) {
if ((pfn & (pageblock_nr_pages - 1)) == 0)
set_pageblock_migratetype(page, MIGRATE_MOVABLE);
__free_pages_boot_core(page, 0);
__free_pages_core(page, 0);
}
}

Expand Down

0 comments on commit a9cd410

Please sign in to comment.