Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch, mm: filter disallowed nodes from arch specific show_mem functions

Architectures that implement their own show_mem() function did not pass
the filter argument to show_free_areas() to appropriately avoid emitting
the state of nodes that are disallowed in the current context. This patch
now passes the filter argument to show_free_areas() so those nodes are now
avoided.

This patch also removes the show_free_areas() wrapper around
__show_free_areas() and converts existing callers to pass an empty filter.

ia64 emits additional information for each node, so skip_free_areas_zone()
must be made global to filter disallowed nodes and it is converted to use
a nid argument rather than a zone for this use case.

Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Helge Deller <deller@gmx.de>
Cc: James Bottomley <jejb@parisc-linux.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Rientjes and committed by
Linus Torvalds
7bf02ea2 851cc856

+34 -36
+1 -1
arch/arm/mm/init.c
··· 85 85 struct meminfo * mi = &meminfo; 86 86 87 87 printk("Mem-info:\n"); 88 - show_free_areas(); 88 + show_free_areas(filter); 89 89 90 90 for_each_bank (i, mi) { 91 91 struct membank *bank = &mi->bank[i];
+6 -4
arch/ia64/mm/contig.c
··· 44 44 pg_data_t *pgdat; 45 45 46 46 printk(KERN_INFO "Mem-info:\n"); 47 - show_free_areas(); 47 + show_free_areas(filter); 48 48 printk(KERN_INFO "Node memory in pages:\n"); 49 49 for_each_online_pgdat(pgdat) { 50 50 unsigned long present; 51 51 unsigned long flags; 52 52 int shared = 0, cached = 0, reserved = 0; 53 + int nid = pgdat->node_id; 53 54 55 + if (skip_free_areas_node(filter, nid)) 56 + continue; 54 57 pgdat_resize_lock(pgdat, &flags); 55 58 present = pgdat->node_present_pages; 56 59 for(i = 0; i < pgdat->node_spanned_pages; i++) { ··· 67 64 if (max_gap < LARGE_GAP) 68 65 continue; 69 66 #endif 70 - i = vmemmap_find_next_valid_pfn(pgdat->node_id, 71 - i) - 1; 67 + i = vmemmap_find_next_valid_pfn(nid, i) - 1; 72 68 continue; 73 69 } 74 70 if (PageReserved(page)) ··· 83 81 total_cached += cached; 84 82 total_shared += shared; 85 83 printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, " 86 - "shrd: %10d, swpd: %10d\n", pgdat->node_id, 84 + "shrd: %10d, swpd: %10d\n", nid, 87 85 present, reserved, shared, cached); 88 86 } 89 87 printk(KERN_INFO "%ld pages of RAM\n", total_present);
+6 -4
arch/ia64/mm/discontig.c
··· 622 622 pg_data_t *pgdat; 623 623 624 624 printk(KERN_INFO "Mem-info:\n"); 625 - show_free_areas(); 625 + show_free_areas(filter); 626 626 printk(KERN_INFO "Node memory in pages:\n"); 627 627 for_each_online_pgdat(pgdat) { 628 628 unsigned long present; 629 629 unsigned long flags; 630 630 int shared = 0, cached = 0, reserved = 0; 631 + int nid = pgdat->node_id; 631 632 633 + if (skip_free_areas_node(filter, nid)) 634 + continue; 632 635 pgdat_resize_lock(pgdat, &flags); 633 636 present = pgdat->node_present_pages; 634 637 for(i = 0; i < pgdat->node_spanned_pages; i++) { ··· 641 638 if (pfn_valid(pgdat->node_start_pfn + i)) 642 639 page = pfn_to_page(pgdat->node_start_pfn + i); 643 640 else { 644 - i = vmemmap_find_next_valid_pfn(pgdat->node_id, 645 - i) - 1; 641 + i = vmemmap_find_next_valid_pfn(nid, i) - 1; 646 642 continue; 647 643 } 648 644 if (PageReserved(page)) ··· 657 655 total_cached += cached; 658 656 total_shared += shared; 659 657 printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, " 660 - "shrd: %10d, swpd: %10d\n", pgdat->node_id, 658 + "shrd: %10d, swpd: %10d\n", nid, 661 659 present, reserved, shared, cached); 662 660 } 663 661 printk(KERN_INFO "%ld pages of RAM\n", total_present);
+1 -1
arch/parisc/mm/init.c
··· 686 686 int shared = 0, cached = 0; 687 687 688 688 printk(KERN_INFO "Mem-info:\n"); 689 - show_free_areas(); 689 + show_free_areas(filter); 690 690 #ifndef CONFIG_DISCONTIGMEM 691 691 i = max_mapnr; 692 692 while (i-- > 0) {
+1 -1
arch/sparc/kernel/setup_32.c
··· 82 82 "nop\n\t" : : "r" (&trapbase)); 83 83 84 84 prom_printf("PROM SYNC COMMAND...\n"); 85 - show_free_areas(); 85 + show_free_areas(0); 86 86 if(current->pid != 0) { 87 87 local_irq_enable(); 88 88 sys_sync();
+1 -1
arch/sparc/mm/init_32.c
··· 78 78 void show_mem(unsigned int filter) 79 79 { 80 80 printk("Mem-info:\n"); 81 - show_free_areas(); 81 + show_free_areas(filter); 82 82 printk("Free swap: %6ldkB\n", 83 83 nr_swap_pages << (PAGE_SHIFT-10)); 84 84 printk("%ld pages of RAM\n", totalram_pages);
+1 -1
arch/unicore32/mm/init.c
··· 62 62 struct meminfo *mi = &meminfo; 63 63 64 64 printk(KERN_DEFAULT "Mem-info:\n"); 65 - show_free_areas(); 65 + show_free_areas(filter); 66 66 67 67 for_each_bank(i, mi) { 68 68 struct membank *bank = &mi->bank[i];
+1 -1
drivers/net/ioc3-eth.c
··· 915 915 916 916 skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC); 917 917 if (!skb) { 918 - show_free_areas(); 918 + show_free_areas(0); 919 919 continue; 920 920 } 921 921
+1 -1
drivers/tty/serial/68328serial.c
··· 281 281 #ifdef CONFIG_MAGIC_SYSRQ 282 282 } else if (ch == 0x10) { /* ^P */ 283 283 show_state(); 284 - show_free_areas(); 284 + show_free_areas(0); 285 285 show_buffers(); 286 286 /* show_net_buffers(); */ 287 287 return;
+3 -3
include/linux/mm.h
··· 862 862 #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) 863 863 864 864 /* 865 - * Flags passed to show_mem() and __show_free_areas() to suppress output in 865 + * Flags passed to show_mem() and show_free_areas() to suppress output in 866 866 * various contexts. 867 867 */ 868 868 #define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ 869 869 870 - extern void show_free_areas(void); 871 - extern void __show_free_areas(unsigned int flags); 870 + extern void show_free_areas(unsigned int flags); 871 + extern bool skip_free_areas_node(unsigned int flags, int nid); 872 872 873 873 int shmem_lock(struct file *file, int lock, struct user_struct *user); 874 874 struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags);
+1 -1
lib/show_mem.c
··· 16 16 nonshared = 0, highmem = 0; 17 17 18 18 printk("Mem-Info:\n"); 19 - __show_free_areas(filter); 19 + show_free_areas(filter); 20 20 21 21 for_each_online_pgdat(pgdat) { 22 22 unsigned long i, flags;
+3 -3
mm/nommu.c
··· 1235 1235 enomem: 1236 1236 printk("Allocation of length %lu from process %d (%s) failed\n", 1237 1237 len, current->pid, current->comm); 1238 - show_free_areas(); 1238 + show_free_areas(0); 1239 1239 return -ENOMEM; 1240 1240 } 1241 1241 ··· 1468 1468 printk(KERN_WARNING "Allocation of vma for %lu byte allocation" 1469 1469 " from process %d failed\n", 1470 1470 len, current->pid); 1471 - show_free_areas(); 1471 + show_free_areas(0); 1472 1472 return -ENOMEM; 1473 1473 1474 1474 error_getting_region: 1475 1475 printk(KERN_WARNING "Allocation of vm region for %lu byte allocation" 1476 1476 " from process %d failed\n", 1477 1477 len, current->pid); 1478 - show_free_areas(); 1478 + show_free_areas(0); 1479 1479 return -ENOMEM; 1480 1480 } 1481 1481 EXPORT_SYMBOL(do_mmap_pgoff);
+8 -14
mm/page_alloc.c
··· 2473 2473 #endif 2474 2474 2475 2475 /* 2476 - * Determine whether the zone's node should be displayed or not, depending on 2477 - * whether SHOW_MEM_FILTER_NODES was passed to __show_free_areas(). 2476 + * Determine whether the node should be displayed or not, depending on whether 2477 + * SHOW_MEM_FILTER_NODES was passed to show_free_areas(). 2478 2478 */ 2479 - static bool skip_free_areas_zone(unsigned int flags, const struct zone *zone) 2479 + bool skip_free_areas_node(unsigned int flags, int nid) 2480 2480 { 2481 2481 bool ret = false; 2482 2482 ··· 2484 2484 goto out; 2485 2485 2486 2486 get_mems_allowed(); 2487 - ret = !node_isset(zone->zone_pgdat->node_id, 2488 - cpuset_current_mems_allowed); 2487 + ret = !node_isset(nid, cpuset_current_mems_allowed); 2489 2488 put_mems_allowed(); 2490 2489 out: 2491 2490 return ret; ··· 2499 2500 * Suppresses nodes that are not allowed by current's cpuset if 2500 2501 * SHOW_MEM_FILTER_NODES is passed. 2501 2502 */ 2502 - void __show_free_areas(unsigned int filter) 2503 + void show_free_areas(unsigned int filter) 2503 2504 { 2504 2505 int cpu; 2505 2506 struct zone *zone; 2506 2507 2507 2508 for_each_populated_zone(zone) { 2508 - if (skip_free_areas_zone(filter, zone)) 2509 + if (skip_free_areas_node(filter, zone_to_nid(zone))) 2509 2510 continue; 2510 2511 show_node(zone); 2511 2512 printk("%s per-cpu:\n", zone->name); ··· 2548 2549 for_each_populated_zone(zone) { 2549 2550 int i; 2550 2551 2551 - if (skip_free_areas_zone(filter, zone)) 2552 + if (skip_free_areas_node(filter, zone_to_nid(zone))) 2552 2553 continue; 2553 2554 show_node(zone); 2554 2555 printk("%s" ··· 2617 2618 for_each_populated_zone(zone) { 2618 2619 unsigned long nr[MAX_ORDER], flags, order, total = 0; 2619 2620 2620 - if (skip_free_areas_zone(filter, zone)) 2621 + if (skip_free_areas_node(filter, zone_to_nid(zone))) 2621 2622 continue; 2622 2623 show_node(zone); 2623 2624 printk("%s: ", zone->name); ··· 2636 2637 printk("%ld total pagecache pages\n", global_page_state(NR_FILE_PAGES)); 2637 2638 2638 2639 show_swap_cache_info(); 2639 - } 2640 - 2641 - void show_free_areas(void) 2642 - { 2643 - __show_free_areas(0); 2644 2640 } 2645 2641 2646 2642 static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref)