printk("Mem-info:\n");
        show_free_areas(filter);
 
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
+
        for_each_bank (i, mi) {
                struct membank *bank = &mi->bank[i];
                unsigned int pfn1, pfn2;
 
        printk(KERN_INFO "Mem-info:\n");
        show_free_areas(filter);
        printk(KERN_INFO "Node memory in pages:\n");
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
        for_each_online_pgdat(pgdat) {
                unsigned long present;
                unsigned long flags;
 
 
        printk(KERN_INFO "Mem-info:\n");
        show_free_areas(filter);
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
        printk(KERN_INFO "Node memory in pages:\n");
        for_each_online_pgdat(pgdat) {
                unsigned long present;
 
 
        printk(KERN_INFO "Mem-info:\n");
        show_free_areas(filter);
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
 #ifndef CONFIG_DISCONTIGMEM
        i = max_mapnr;
        while (i-- > 0) {
 
        printk(KERN_DEFAULT "Mem-info:\n");
        show_free_areas(filter);
 
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
+
        for_each_bank(i, mi) {
                struct membank *bank = &mi->bank[i];
                unsigned int pfn1, pfn2;
 
  * Flags passed to show_mem() and show_free_areas() to suppress output in
  * various contexts.
  */
-#define SHOW_MEM_FILTER_NODES  (0x0001u)       /* filter disallowed nodes */
+#define SHOW_MEM_FILTER_NODES          (0x0001u)       /* disallowed nodes */
+#define SHOW_MEM_FILTER_PAGE_COUNT     (0x0002u)       /* page type count */
 
 extern void show_free_areas(unsigned int flags);
 extern bool skip_free_areas_node(unsigned int flags, int nid);
 
        printk("Mem-Info:\n");
        show_free_areas(filter);
 
+       if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
+               return;
+
        for_each_online_pgdat(pgdat) {
                unsigned long i, flags;
 
 
            debug_guardpage_minorder() > 0)
                return;
 
+       /*
+        * Walking all memory to count page types is very expensive and should
+        * be inhibited in non-blockable contexts.
+        */
+       if (!(gfp_mask & __GFP_WAIT))
+               filter |= SHOW_MEM_FILTER_PAGE_COUNT;
+
        /*
         * This documents exceptions given to allocations in certain
         * contexts that are allowed to allocate outside current's set