mm, show_mem: remove SHOW_MEM_FILTER_PAGE_COUNT
Commit4b59e6c473("mm, show_mem: suppress page counts in non-blockable contexts") introduced SHOW_MEM_FILTER_PAGE_COUNT to suppress PFN walks on large memory machines. Commitc78e93630d("mm: do not walk all of system memory during show_mem") avoided a PFN walk in the generic show_mem helper which removes the requirement for SHOW_MEM_FILTER_PAGE_COUNT in that case. This patch removes PFN walkers from the arch-specific implementations that report on a per-node or per-zone granularity. ARM and unicore32 still do a PFN walk as they report memory usage on each bank which is a much finer granularity where the debugging information may still be of use. As the remaining arches doing PFN walks have relatively small amounts of memory, this patch simply removes SHOW_MEM_FILTER_PAGE_COUNT. [akpm@linux-foundation.org: fix parisc] Signed-off-by: Mel Gorman <mgorman@suse.de> Acked-by: David Rientjes <rientjes@google.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: James Bottomley <jejb@parisc-linux.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									ece86e222d
								
							
						
					
					
						commit
						aec6a8889a
					
				| @ -92,9 +92,6 @@ void show_mem(unsigned int filter) | ||||
| 	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; | ||||
|  | ||||
| @ -31,74 +31,6 @@ | ||||
| static unsigned long max_gap; | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * show_mem - give short summary of memory stats | ||||
|  * | ||||
|  * Shows a simple page count of reserved and used pages in the system. | ||||
|  * For discontig machines, it does this on a per-pgdat basis. | ||||
|  */ | ||||
| void show_mem(unsigned int filter) | ||||
| { | ||||
| 	int i, total_reserved = 0; | ||||
| 	int total_shared = 0, total_cached = 0; | ||||
| 	unsigned long total_present = 0; | ||||
| 	pg_data_t *pgdat; | ||||
| 
 | ||||
| 	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; | ||||
| 		int shared = 0, cached = 0, reserved = 0; | ||||
| 		int nid = pgdat->node_id; | ||||
| 
 | ||||
| 		if (skip_free_areas_node(filter, nid)) | ||||
| 			continue; | ||||
| 		pgdat_resize_lock(pgdat, &flags); | ||||
| 		present = pgdat->node_present_pages; | ||||
| 		for(i = 0; i < pgdat->node_spanned_pages; i++) { | ||||
| 			struct page *page; | ||||
| 			if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) | ||||
| 				touch_nmi_watchdog(); | ||||
| 			if (pfn_valid(pgdat->node_start_pfn + i)) | ||||
| 				page = pfn_to_page(pgdat->node_start_pfn + i); | ||||
| 			else { | ||||
| #ifdef CONFIG_VIRTUAL_MEM_MAP | ||||
| 				if (max_gap < LARGE_GAP) | ||||
| 					continue; | ||||
| #endif | ||||
| 				i = vmemmap_find_next_valid_pfn(nid, i) - 1; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (PageReserved(page)) | ||||
| 				reserved++; | ||||
| 			else if (PageSwapCache(page)) | ||||
| 				cached++; | ||||
| 			else if (page_count(page)) | ||||
| 				shared += page_count(page)-1; | ||||
| 		} | ||||
| 		pgdat_resize_unlock(pgdat, &flags); | ||||
| 		total_present += present; | ||||
| 		total_reserved += reserved; | ||||
| 		total_cached += cached; | ||||
| 		total_shared += shared; | ||||
| 		printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, " | ||||
| 		       "shrd: %10d, swpd: %10d\n", nid, | ||||
| 		       present, reserved, shared, cached); | ||||
| 	} | ||||
| 	printk(KERN_INFO "%ld pages of RAM\n", total_present); | ||||
| 	printk(KERN_INFO "%d reserved pages\n", total_reserved); | ||||
| 	printk(KERN_INFO "%d pages shared\n", total_shared); | ||||
| 	printk(KERN_INFO "%d pages swap cached\n", total_cached); | ||||
| 	printk(KERN_INFO "Total of %ld pages in page table cache\n", | ||||
| 	       quicklist_total_size()); | ||||
| 	printk(KERN_INFO "%ld free buffer pages\n", nr_free_buffer_pages()); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* physical address where the bootmem map is located */ | ||||
| unsigned long bootmap_start; | ||||
| 
 | ||||
|  | ||||
| @ -607,69 +607,6 @@ void *per_cpu_init(void) | ||||
| } | ||||
| #endif /* CONFIG_SMP */ | ||||
| 
 | ||||
| /**
 | ||||
|  * show_mem - give short summary of memory stats | ||||
|  * | ||||
|  * Shows a simple page count of reserved and used pages in the system. | ||||
|  * For discontig machines, it does this on a per-pgdat basis. | ||||
|  */ | ||||
| void show_mem(unsigned int filter) | ||||
| { | ||||
| 	int i, total_reserved = 0; | ||||
| 	int total_shared = 0, total_cached = 0; | ||||
| 	unsigned long total_present = 0; | ||||
| 	pg_data_t *pgdat; | ||||
| 
 | ||||
| 	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; | ||||
| 		unsigned long flags; | ||||
| 		int shared = 0, cached = 0, reserved = 0; | ||||
| 		int nid = pgdat->node_id; | ||||
| 
 | ||||
| 		if (skip_free_areas_node(filter, nid)) | ||||
| 			continue; | ||||
| 		pgdat_resize_lock(pgdat, &flags); | ||||
| 		present = pgdat->node_present_pages; | ||||
| 		for(i = 0; i < pgdat->node_spanned_pages; i++) { | ||||
| 			struct page *page; | ||||
| 			if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) | ||||
| 				touch_nmi_watchdog(); | ||||
| 			if (pfn_valid(pgdat->node_start_pfn + i)) | ||||
| 				page = pfn_to_page(pgdat->node_start_pfn + i); | ||||
| 			else { | ||||
| 				i = vmemmap_find_next_valid_pfn(nid, i) - 1; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (PageReserved(page)) | ||||
| 				reserved++; | ||||
| 			else if (PageSwapCache(page)) | ||||
| 				cached++; | ||||
| 			else if (page_count(page)) | ||||
| 				shared += page_count(page)-1; | ||||
| 		} | ||||
| 		pgdat_resize_unlock(pgdat, &flags); | ||||
| 		total_present += present; | ||||
| 		total_reserved += reserved; | ||||
| 		total_cached += cached; | ||||
| 		total_shared += shared; | ||||
| 		printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, " | ||||
| 		       "shrd: %10d, swpd: %10d\n", nid, | ||||
| 		       present, reserved, shared, cached); | ||||
| 	} | ||||
| 	printk(KERN_INFO "%ld pages of RAM\n", total_present); | ||||
| 	printk(KERN_INFO "%d reserved pages\n", total_reserved); | ||||
| 	printk(KERN_INFO "%d pages shared\n", total_shared); | ||||
| 	printk(KERN_INFO "%d pages swap cached\n", total_cached); | ||||
| 	printk(KERN_INFO "Total of %ld pages in page table cache\n", | ||||
| 	       quicklist_total_size()); | ||||
| 	printk(KERN_INFO "%ld free buffer pages\n", nr_free_buffer_pages()); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * call_pernode_memory - use SRAT to call callback functions with node info | ||||
|  * @start: physical start of range | ||||
|  | ||||
| @ -684,3 +684,51 @@ per_linux32_init(void) | ||||
| } | ||||
| 
 | ||||
| __initcall(per_linux32_init); | ||||
| 
 | ||||
| /**
 | ||||
|  * show_mem - give short summary of memory stats | ||||
|  * | ||||
|  * Shows a simple page count of reserved and used pages in the system. | ||||
|  * For discontig machines, it does this on a per-pgdat basis. | ||||
|  */ | ||||
| void show_mem(unsigned int filter) | ||||
| { | ||||
| 	int total_reserved = 0; | ||||
| 	unsigned long total_present = 0; | ||||
| 	pg_data_t *pgdat; | ||||
| 
 | ||||
| 	printk(KERN_INFO "Mem-info:\n"); | ||||
| 	show_free_areas(filter); | ||||
| 	printk(KERN_INFO "Node memory in pages:\n"); | ||||
| 	for_each_online_pgdat(pgdat) { | ||||
| 		unsigned long present; | ||||
| 		unsigned long flags; | ||||
| 		int reserved = 0; | ||||
| 		int nid = pgdat->node_id; | ||||
| 		int zoneid; | ||||
| 
 | ||||
| 		if (skip_free_areas_node(filter, nid)) | ||||
| 			continue; | ||||
| 		pgdat_resize_lock(pgdat, &flags); | ||||
| 
 | ||||
| 		for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { | ||||
| 			struct zone *zone = &pgdat->node_zones[zoneid]; | ||||
| 			if (!populated_zone(zone)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			reserved += zone->present_pages - zone->managed_pages; | ||||
| 		} | ||||
| 		present = pgdat->node_present_pages; | ||||
| 
 | ||||
| 		pgdat_resize_unlock(pgdat, &flags); | ||||
| 		total_present += present; | ||||
| 		total_reserved += reserved; | ||||
| 		printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, ", | ||||
| 		       nid, present, reserved); | ||||
| 	} | ||||
| 	printk(KERN_INFO "%ld pages of RAM\n", total_present); | ||||
| 	printk(KERN_INFO "%d reserved pages\n", total_reserved); | ||||
| 	printk(KERN_INFO "Total of %ld pages in page table cache\n", | ||||
| 	       quicklist_total_size()); | ||||
| 	printk(KERN_INFO "%ld free buffer pages\n", nr_free_buffer_pages()); | ||||
| } | ||||
|  | ||||
| @ -645,55 +645,30 @@ EXPORT_SYMBOL(empty_zero_page); | ||||
| 
 | ||||
| void show_mem(unsigned int filter) | ||||
| { | ||||
| 	int i,free = 0,total = 0,reserved = 0; | ||||
| 	int shared = 0, cached = 0; | ||||
| 	int total = 0,reserved = 0; | ||||
| 	pg_data_t *pgdat; | ||||
| 
 | ||||
| 	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) { | ||||
| 		total++; | ||||
| 		if (PageReserved(mem_map+i)) | ||||
| 			reserved++; | ||||
| 		else if (PageSwapCache(mem_map+i)) | ||||
| 			cached++; | ||||
| 		else if (!page_count(&mem_map[i])) | ||||
| 			free++; | ||||
| 		else | ||||
| 			shared += page_count(&mem_map[i]) - 1; | ||||
| 
 | ||||
| 	for_each_online_pgdat(pgdat) { | ||||
| 		unsigned long flags; | ||||
| 		int zoneid; | ||||
| 
 | ||||
| 		pgdat_resize_lock(pgdat, &flags); | ||||
| 		for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { | ||||
| 			struct zone *zone = &pgdat->node_zones[zoneid]; | ||||
| 			if (!populated_zone(zone)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			total += zone->present_pages; | ||||
| 			reserved = zone->present_pages - zone->managed_pages; | ||||
| 		} | ||||
| 		pgdat_resize_unlock(pgdat, &flags); | ||||
| 	} | ||||
| #else | ||||
| 	for (i = 0; i < npmem_ranges; i++) { | ||||
| 		int j; | ||||
| 
 | ||||
| 		for (j = node_start_pfn(i); j < node_end_pfn(i); j++) { | ||||
| 			struct page *p; | ||||
| 			unsigned long flags; | ||||
| 
 | ||||
| 			pgdat_resize_lock(NODE_DATA(i), &flags); | ||||
| 			p = nid_page_nr(i, j) - node_start_pfn(i); | ||||
| 
 | ||||
| 			total++; | ||||
| 			if (PageReserved(p)) | ||||
| 				reserved++; | ||||
| 			else if (PageSwapCache(p)) | ||||
| 				cached++; | ||||
| 			else if (!page_count(p)) | ||||
| 				free++; | ||||
| 			else | ||||
| 				shared += page_count(p) - 1; | ||||
| 			pgdat_resize_unlock(NODE_DATA(i), &flags); | ||||
|         	} | ||||
| 	} | ||||
| #endif | ||||
| 	printk(KERN_INFO "%d pages of RAM\n", total); | ||||
| 	printk(KERN_INFO "%d reserved pages\n", reserved); | ||||
| 	printk(KERN_INFO "%d pages shared\n", shared); | ||||
| 	printk(KERN_INFO "%d pages swap cached\n", cached); | ||||
| 
 | ||||
| 
 | ||||
| #ifdef CONFIG_DISCONTIGMEM | ||||
| 	{ | ||||
|  | ||||
| @ -66,9 +66,6 @@ void show_mem(unsigned int filter) | ||||
| 	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; | ||||
|  | ||||
| @ -1016,7 +1016,6 @@ extern void pagefault_out_of_memory(void); | ||||
|  * various contexts. | ||||
|  */ | ||||
| #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); | ||||
|  | ||||
| @ -17,9 +17,6 @@ void show_mem(unsigned int filter) | ||||
| 	printk("Mem-Info:\n"); | ||||
| 	show_free_areas(filter); | ||||
| 
 | ||||
| 	if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||||
| 		return; | ||||
| 
 | ||||
| 	for_each_online_pgdat(pgdat) { | ||||
| 		unsigned long flags; | ||||
| 		int zoneid; | ||||
|  | ||||
| @ -2071,13 +2071,6 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) | ||||
| 	    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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user