Speed up swsusp + progress indication
Subsystems (5)
Hi!
This speeds up swsusp and adds progress indication from Erik. I'd like to get some testing...
Pavel
include/linux/page-flags.h +5 -1
@@ -74,7 +74,7 @@#define PG_swapcache 16/* Swap page: swp_entry_t in private */ #define PG_mappedtodisk 17/* Has blocks allocated on-disk */ #define PG_reclaim 18/* To be reclaimed asap */ - +#define PG_nosave_free 19/* Page is free and should not be written */ /* * Global page accounting. One instance per CPU. Only unsigned longs are
@@ -277,6 +277,10 @@#define ClearPageNosave (page) clear_bit(PG_nosave, &(page)->flags)#define TestClearPageNosave (page) test_and_clear_bit(PG_nosave, &(page)->flags) +#define PageNosaveFree (page) test_bit(PG_nosave_free, &(page)->flags) +#define SetPageNosaveFree (page) set_bit(PG_nosave_free, &(page)->flags) +#define ClearPageNosaveFree (page) clear_bit(PG_nosave_free, &(page)->flags) +#define PageMappedToDisk (page) test_bit(PG_mappedtodisk, &(page)->flags)#define SetPageMappedToDisk (page) set_bit(PG_mappedtodisk, &(page)->flags)#define ClearPageMappedToDisk (page) clear_bit(PG_mappedtodisk, &(page)->flags)
include/linux/suspend.h +1 -0
@@ -31,6 +31,7 @@/* mm/page_alloc.c */ extern void drain_local_pages (void ); +extern void mark_free_pages (struct zone *zone);/* kernel/power/swsusp.c */ extern int software_suspend (void );
kernel/power/disk.c +14 -4
@@ -91,10 +91,20 @@static void free_some_memory (void ) { -printk ("Freeing memory: " ); -while (shrink_all_memory (10000 )) -printk ("." ); -printk ("|\n" ); +unsigned int i =0 ; +unsigned int tmp; +unsigned long pages =0 ; +char *p ="-\\|/" ; + +printk ("Freeing memory... " ); +while (tmp =shrink_all_memory (10000 )) { + pages += tmp; +printk ("\b%c" , p[i]); + i++; +if (i >3 ) + i =0 ; + } +printk ("\bdone (%li pages freed)\n" , pages); }
kernel/power/swsusp.c +38 -35
167 lines not on this page · raw message
mm/page_alloc.c +17 -13
@@ -437,26 +437,30 @@#endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_PM -int is_head_of_free_region (struct page *page) + +void mark_free_pages (struct zone *zone) { -struct zone *zone =page_zone (page); -unsigned long flags; +unsigned long zone_pfn, flags;int order;struct list_head *curr; -/* -* Should not matter as we need quiescent system for -* suspend anyway, but... -*/ +if (!zone->spanned_pages) +return ; +spin_lock_irqsave (&zone->lock, flags); +for (zone_pfn =0 ; zone_pfn < zone->spanned_pages; ++zone_pfn) +ClearPageNosaveFree (pfn_to_page (zone_pfn + zone->zone_start_pfn)); +for (order =MAX_ORDER -1 ; order >=0 ; --order) -list_for_each (curr, &zone->free_area[order].free_list) - if (page == list_entry(curr, struct page, lru)) { -spin_unlock_irqrestore (&zone->lock, flags); -return 1 << order; - } +list_for_each (curr, &zone->free_area[order].free_list) { +unsigned long start_pfn, i; + + start_pfn = page_to_pfn(list_entry(curr, struct page, lru)); + +for (i=0 ; i < (1 <<order); i++) +SetPageNosaveFree (pfn_to_page (start_pfn+i)); + }spin_unlock_irqrestore (&zone->lock, flags); -return 0 ; }/*
Signature · 2 lines
People were complaining that M$ turns users into beta-testers... ...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!