Skip to content

Commit

Permalink
mm: Fix extra_latent_entropy
Browse files Browse the repository at this point in the history
Commit a9cd410 ("mm/page_alloc.c: memory hotplug: free pages as
higher order") changed `static void __init __free_pages_boot_core()`
into `void __free_pages_core()`, causing the following section mismatch
warning at compile time:

    WARNING: vmlinux.o(.text+0x180fe4): Section mismatch in reference from the function __free_pages_core() to the variable .meminit.data:extra_latent_entropy
    The function __free_pages_core() references the variable __meminitdata extra_latent_entropy.
    This is often because __free_pages_core lacks a __meminitdata annotation or the annotation of extra_latent_entropy is wrong.

This commit is an attempt at fixing this issue. I'm not sure it's OK as
we are accessing pages that are still managed by the bootmem allocator.
The prefetching part is not an issue as it only affects struct pages.

Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
  • Loading branch information
tsautereau-anssi authored and anthraxx committed Apr 4, 2020
1 parent d0862c5 commit c98a122
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1437,21 +1437,9 @@ static void __free_pages_ok(struct page *page, unsigned int order)
local_irq_restore(flags);
}

void __free_pages_core(struct page *page, unsigned int order)
static void __init __gather_extra_latent_entropy(struct page *page,
unsigned int nr_pages)
{
unsigned int nr_pages = 1 << order;
struct page *p = page;
unsigned int loop;

prefetchw(p);
for (loop = 0; loop < (nr_pages - 1); loop++, p++) {
prefetchw(p + 1);
__ClearPageReserved(p);
set_page_count(p, 0);
}
__ClearPageReserved(p);
set_page_count(p, 0);

if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 0x100000) {
unsigned long hash = 0;
size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
Expand All @@ -1466,7 +1454,22 @@ void __free_pages_core(struct page *page, unsigned int order)
add_device_randomness((const void *)&hash, sizeof(hash));
#endif
}
}

void __free_pages_core(struct page *page, unsigned int order)
{
unsigned int nr_pages = 1 << order;
struct page *p = page;
unsigned int loop;

prefetchw(p);
for (loop = 0; loop < (nr_pages - 1); loop++, p++) {
prefetchw(p + 1);
__ClearPageReserved(p);
set_page_count(p, 0);
}
__ClearPageReserved(p);
set_page_count(p, 0);
atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
set_page_refcounted(page);
__free_pages(page, order);
Expand Down Expand Up @@ -1517,6 +1520,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
{
if (early_page_uninitialised(pfn))
return;
__gather_extra_latent_entropy(page, 1 << order);
__free_pages_core(page, order);
}

Expand Down Expand Up @@ -1607,13 +1611,15 @@ 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);
__gather_extra_latent_entropy(page, 1 << 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);
__gather_extra_latent_entropy(page, 1);
__free_pages_core(page, 0);
}
}
Expand Down

0 comments on commit c98a122

Please sign in to comment.