The patch titled mm: verify the page links and memory model has been added to the -mm tree. Its filename is mm-verify-the-page-links-and-memory-model.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: mm: verify the page links and memory model From: Mel Gorman <mel@xxxxxxxxx> Print out information on how the page flags are being used if mminit_loglevel is MMINIT_VERIFY or higher and unconditionally performs sanity checks on the flags regardless of loglevel. When the page flags are updated with section, node and zone information, a check are made to ensure the values can be retrieved correctly. Finally we confirm that pfn_to_page and page_to_pfn are the correct inverse functions. Signed-off-by: Mel Gorman <mel@xxxxxxxxx> Cc: Christoph Lameter <clameter@xxxxxxx> Cc: Andy Whitcroft <apw@xxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/internal.h | 12 +++++++ mm/mm_init.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++ mm/page_alloc.c | 6 +++ 3 files changed, 88 insertions(+) diff -puN mm/internal.h~mm-verify-the-page-links-and-memory-model mm/internal.h --- a/mm/internal.h~mm-verify-the-page-links-and-memory-model +++ a/mm/internal.h @@ -78,6 +78,10 @@ do { \ } \ } while (0) +extern void mminit_verify_pageflags_layout(void); +extern void mminit_verify_page_links(struct page *page, + enum zone_type zone, unsigned long nid, unsigned long pfn); + #else static inline void mminit_dprintk(enum mminit_level level, @@ -85,5 +89,13 @@ static inline void mminit_dprintk(enum m { } +static inline void mminit_verify_pageflags_layout(void) +{ +} + +static inline void mminit_verify_page_links(struct page *page, + enum zone_type zone, unsigned long nid, unsigned long pfn) +{ +} #endif /* CONFIG_DEBUG_MEMORY_INIT */ #endif diff -puN mm/mm_init.c~mm-verify-the-page-links-and-memory-model mm/mm_init.c --- a/mm/mm_init.c~mm-verify-the-page-links-and-memory-model +++ a/mm/mm_init.c @@ -7,9 +7,79 @@ */ #include <linux/kernel.h> #include <linux/init.h> +#include "internal.h" int __meminitdata mminit_loglevel; +void __init mminit_verify_pageflags_layout(void) +{ + int shift, width; + unsigned long or_mask, add_mask; + + shift = 8 * sizeof(unsigned long); + width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH; + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths", + "Section %d Node %d Zone %d Flags %d\n", + SECTIONS_WIDTH, + NODES_WIDTH, + ZONES_WIDTH, + NR_PAGEFLAGS); + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", + "Section %d Node %d Zone %d\n", +#ifdef SECTIONS_SHIFT + SECTIONS_SHIFT, +#else + 0, +#endif + NODES_SHIFT, + ZONES_SHIFT); + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_offsets", + "Section %d Node %d Zone %d\n", + SECTIONS_PGSHIFT, + NODES_PGSHIFT, + ZONES_PGSHIFT); + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_zoneid", + "Zone ID: %d -> %d\n", + ZONEID_PGOFF, ZONEID_PGOFF + ZONEID_SHIFT); + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_usage", + "location: %d -> %d unused %d -> %d flags %d -> %d\n", + shift, width, width, NR_PAGEFLAGS, NR_PAGEFLAGS, 0); +#ifdef NODE_NOT_IN_PAGE_FLAGS + mminit_dprintk(MMINIT_TRACE, "pageflags_layout_nodeflags", + "Node not in page flags"); +#endif + + if (SECTIONS_WIDTH) { + shift -= SECTIONS_WIDTH; + BUG_ON(shift != SECTIONS_PGSHIFT); + } + if (NODES_WIDTH) { + shift -= NODES_WIDTH; + BUG_ON(shift != NODES_PGSHIFT); + } + if (ZONES_WIDTH) { + shift -= ZONES_WIDTH; + BUG_ON(shift != ZONES_PGSHIFT); + } + + /* Check for bitmask overlaps */ + or_mask = (ZONES_MASK << ZONES_PGSHIFT) | + (NODES_MASK << NODES_PGSHIFT) | + (SECTIONS_MASK << SECTIONS_PGSHIFT); + add_mask = (ZONES_MASK << ZONES_PGSHIFT) + + (NODES_MASK << NODES_PGSHIFT) + + (SECTIONS_MASK << SECTIONS_PGSHIFT); + BUG_ON(or_mask != add_mask); +} + +void __meminit mminit_verify_page_links(struct page *page, enum zone_type zone, + unsigned long nid, unsigned long pfn) +{ + BUG_ON(page_to_nid(page) != nid); + BUG_ON(page_zonenum(page) != zone); + BUG_ON(page_to_pfn(page) != pfn); +} + static __init int set_mminit_loglevel(char *str) { get_option(&str, &mminit_loglevel); diff -puN mm/page_alloc.c~mm-verify-the-page-links-and-memory-model mm/page_alloc.c --- a/mm/page_alloc.c~mm-verify-the-page-links-and-memory-model +++ a/mm/page_alloc.c @@ -2554,6 +2554,7 @@ void __meminit memmap_init_zone(unsigned } page = pfn_to_page(pfn); set_page_links(page, zone, nid, pfn); + mminit_verify_page_links(page, zone, nid, pfn); init_page_count(page); reset_page_mapcount(page); SetPageReserved(page); @@ -2856,6 +2857,10 @@ __meminit int init_currently_empty_zone( zone->zone_start_pfn = zone_start_pfn; + mminit_dprintk(MMINIT_TRACE, "memmap_init", + "Initialising map node %d zone %d pfns %lu -> %lu\n", + pgdat->node_id, zone_idx(zone), + zone_start_pfn, (zone_start_pfn + size)); memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn); zone_init_free_lists(zone); @@ -3923,6 +3928,7 @@ void __init free_area_init_nodes(unsigne early_node_map[i].end_pfn); /* Initialise every node */ + mminit_verify_pageflags_layout(); setup_nr_node_ids(); for_each_online_node(nid) { pg_data_t *pgdat = NODE_DATA(nid); _ Patches currently in -mm which might be from mel@xxxxxxxxx are origin.patch mm-fix-usemap-initialization.patch mm-fix-misleading-__gfp_repeat-related-comments.patch page-allcoator-smarter-retry-of-costly-order-allocations.patch page-allocator-explicitly-retry-hugepage-allocations.patch memcgroup-move-memory-controller-allocations-to-their-own-slabs.patch proc-pagetypeinfo-fix-output-for-memoryless-nodes.patch mm-add-a-basic-debugging-framework-for-memory-initialisation.patch mm-verify-the-page-links-and-memory-model.patch mm-make-defensive-checks-around-pfn-values-registered-for-memory-usage.patch mm-print-out-the-zonelists-on-request-for-manual-verification.patch page-owner-tracking-leak-detector.patch add-debugging-aid-for-memory-initialisation-problems.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html