From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Christoph Lameter <clameter@sgi.com>
Cc: linux-mm@kvack.org, Pavel Machek <pavel@ucw.cz>
Subject: Re: Remove page flags for software suspend
Date: Fri, 16 Feb 2007 11:56:21 +0100 [thread overview]
Message-ID: <200702161156.21496.rjw@sisk.pl> (raw)
In-Reply-To: <Pine.LNX.4.64.0702160212150.21862@schroedinger.engr.sgi.com>
On Friday, 16 February 2007 11:13, Christoph Lameter wrote:
> I think we can just move the flags completely into the kernel/power
> directory? This centralizes all your handling of pageflags into snapshot.c
> so that you need no external definitions anymore.
Yes, I think we can do it this way, but can we generally assume that the
offset for eg. test_bit() won't be taken modulo 32 (or 64)?
And ...
> Index: linux-2.6.20-mm1/include/linux/mmzone.h
> ===================================================================
> --- linux-2.6.20-mm1.orig/include/linux/mmzone.h 2007-02-16 01:11:46.000000000 -0800
> +++ linux-2.6.20-mm1/include/linux/mmzone.h 2007-02-16 01:12:23.000000000 -0800
> @@ -295,6 +295,7 @@ struct zone {
> unsigned long spanned_pages; /* total size, including holes */
> unsigned long present_pages; /* amount of memory (excluding holes) */
>
> + unsigned long *suspend_flags;
> /*
> * rarely used fields:
> */
> Index: linux-2.6.20-mm1/include/linux/page-flags.h
> ===================================================================
> --- linux-2.6.20-mm1.orig/include/linux/page-flags.h 2007-02-16 01:05:26.000000000 -0800
> +++ linux-2.6.20-mm1/include/linux/page-flags.h 2007-02-16 01:16:45.000000000 -0800
> @@ -82,13 +82,11 @@
> #define PG_private 11 /* If pagecache, has fs-private data */
>
> #define PG_writeback 12 /* Page is under writeback */
> -#define PG_nosave 13 /* Used for system suspend/resume */
> #define PG_compound 14 /* Part of a compound page */
> #define PG_swapcache 15 /* Swap page: swp_entry_t in private */
>
> #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */
> #define PG_reclaim 17 /* To be reclaimed asap */
> -#define PG_nosave_free 18 /* Used for system suspend/resume */
> #define PG_buddy 19 /* Page is free, on buddy lists */
>
> #define PG_mlocked 20 /* Page is mlocked */
> @@ -192,16 +190,6 @@ static inline void SetPageUptodate(struc
> #define TestClearPageWriteback(page) test_and_clear_bit(PG_writeback, \
> &(page)->flags)
>
> -#define PageNosave(page) test_bit(PG_nosave, &(page)->flags)
> -#define SetPageNosave(page) set_bit(PG_nosave, &(page)->flags)
> -#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags)
> -#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 PageBuddy(page) test_bit(PG_buddy, &(page)->flags)
> #define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags)
> #define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags)
> Index: linux-2.6.20-mm1/include/linux/suspend.h
> ===================================================================
> --- linux-2.6.20-mm1.orig/include/linux/suspend.h 2007-02-16 01:15:30.000000000 -0800
> +++ linux-2.6.20-mm1/include/linux/suspend.h 2007-02-16 01:57:51.000000000 -0800
> @@ -21,7 +22,6 @@ struct pbe {
>
> /* mm/page_alloc.c */
> extern void drain_local_pages(void);
> -extern void mark_free_pages(struct zone *zone);
>
> #ifdef CONFIG_PM
> /* kernel/power/swsusp.c */
> @@ -42,6 +42,18 @@ static inline int software_suspend(void)
> }
> #endif /* CONFIG_PM */
>
> +#ifdef CONFIG_SOFTWARE_SUSPEND
> +int suspend_flags_init(struct zone *zone, unsigned long zone_size_pages);
> +void mark_free_pages(struct zone *zone);
> +#else
> +static inline int suspend_flags_init(struct zone *zone, unsigned long zone_size_pages)
> +{
> + return 0;
> +}
> +
> +static inline void mark_free_pages(struct zone *zone) {}
> +#endif
> +
> void save_processor_state(void);
> void restore_processor_state(void);
> struct saved_context;
> Index: linux-2.6.20-mm1/mm/page_alloc.c
> ===================================================================
> --- linux-2.6.20-mm1.orig/mm/page_alloc.c 2007-02-16 01:22:09.000000000 -0800
> +++ linux-2.6.20-mm1/mm/page_alloc.c 2007-02-16 01:40:39.000000000 -0800
> @@ -767,40 +767,6 @@ static void __drain_pages(unsigned int c
> }
>
> #ifdef CONFIG_PM
> -
> -void mark_free_pages(struct zone *zone)
> -{
> - unsigned long pfn, max_zone_pfn;
> - unsigned long flags;
> - int order;
> - struct list_head *curr;
> -
> - if (!zone->spanned_pages)
> - return;
> -
> - spin_lock_irqsave(&zone->lock, flags);
> -
> - max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages;
> - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++)
> - if (pfn_valid(pfn)) {
> - struct page *page = pfn_to_page(pfn);
> -
> - if (!PageNosave(page))
> - ClearPageNosaveFree(page);
> - }
> -
> - for (order = MAX_ORDER - 1; order >= 0; --order)
> - list_for_each(curr, &zone->free_area[order].free_list) {
> - unsigned long i;
> -
> - pfn = page_to_pfn(list_entry(curr, struct page, lru));
> - for (i = 0; i < (1UL << order); i++)
> - SetPageNosaveFree(pfn_to_page(pfn + i));
> - }
> -
> - spin_unlock_irqrestore(&zone->lock, flags);
> -}
> -
> /*
> * Spill all of this CPU's per-cpu pages back into the buddy allocator.
> */
> @@ -2354,6 +2320,9 @@ __meminit int init_currently_empty_zone(
> ret = zone_wait_table_init(zone, size);
> if (ret)
> return ret;
> + ret = suspend_flags_init(zone, size);
> + if (ret)
> + return ret;
> pgdat->nr_zones = zone_idx(zone) + 1;
>
> zone->zone_start_pfn = zone_start_pfn;
> Index: linux-2.6.20-mm1/kernel/power/snapshot.c
> ===================================================================
> --- linux-2.6.20-mm1.orig/kernel/power/snapshot.c 2007-02-16 01:46:02.000000000 -0800
> +++ linux-2.6.20-mm1/kernel/power/snapshot.c 2007-02-16 01:59:24.000000000 -0800
> @@ -34,6 +34,126 @@
>
> #include "power.h"
>
> +static inline int PageNosave(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + return test_bit(offset * 2, zone->suspend_flags);
> +}
> +
> +static inline void SetPageNosave(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + set_bit(offset * 2, zone->suspend_flags);
> +}
> +
> +static inline int TestSetPageNosave(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + return test_and_set_bit(offset * 2, zone->suspend_flags);
... I'd prefer
unsigned long offset = (page_to_pfn(page) - zone->zone_start_pfn) << 1;
return test_and_set_bit(offset, zone->suspend_flags);
> +}
> +
> +static inline void ClearPageNosave(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + clear_bit(offset * 2, zone->suspend_flags);
> +}
> +
> +static inline int TestClearPageNosave(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + return test_and_clear_bit(offset * 2, zone->suspend_flags);
> +}
> +
> +
> +static inline int PageNosaveFree(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + return test_bit(offset * 2 + 1, zone->suspend_flags);
> +}
> +
> +static inline void SetPageNosaveFree(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + set_bit(offset * 2 + 1, zone->suspend_flags);
> +}
> +
> +static inline void ClearPageNosaveFree(struct page *page)
> +{
> + struct zone *zone = page_zone(page);
> + unsigned long offset = page_to_pfn(page) - zone->zone_start_pfn;
> +
> + clear_bit(offset * 2 + 1, zone->suspend_flags);
> +}
> +
> +int suspend_flags_init(struct zone *zone, unsigned long zone_size_pages)
> +{
> + struct pglist_data *pgdat = zone->zone_pgdat;
> + size_t alloc_size;
> +
> + /*
> + * We need two bits per page in the zone. One for PageNosave and the other
> + * for PageNosaveFree.
> + */
> + alloc_size = BITS_TO_LONGS(zone_size_pages * 2);
> + if (system_state == SYSTEM_BOOTING) {
> + zone->suspend_flags = (unsigned long *)
> + alloc_bootmem_node(pgdat, alloc_size);
> + } else
> + zone->suspend_flags = (unsigned long *)vmalloc(alloc_size);
> + if (!zone->suspend_flags)
> + return -ENOMEM;
> +
> + bitmap_zero(zone->suspend_flags, 2 * zone_size_pages);
> + return 0;
> +}
> +
> +void mark_free_pages(struct zone *zone)
> +{
> + unsigned long pfn, max_zone_pfn;
> + unsigned long flags;
> + int order;
> + struct list_head *curr;
> +
> + if (!zone->spanned_pages)
> + return;
> +
> + spin_lock_irqsave(&zone->lock, flags);
> +
> + max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages;
> + for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++)
> + if (pfn_valid(pfn)) {
> + struct page *page = pfn_to_page(pfn);
> +
> + if (!PageNosave(page))
> + ClearPageNosaveFree(page);
> + }
> +
> + for (order = MAX_ORDER - 1; order >= 0; --order)
> + list_for_each(curr, &zone->free_area[order].free_list) {
> + unsigned long i;
> +
> + pfn = page_to_pfn(list_entry(curr, struct page, lru));
> + for (i = 0; i < (1UL << order); i++)
> + SetPageNosaveFree(pfn_to_page(pfn + i));
> + }
> +
> + spin_unlock_irqrestore(&zone->lock, flags);
> +}
> +
> /* List of PBEs needed for restoring the pages that were allocated before
> * the suspend and included in the suspend image, but have also been
> * allocated by the "resume" kernel, so their contents cannot be written
Greetings,
Rafael
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2007-02-16 10:56 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-16 10:13 Christoph Lameter
2007-02-16 10:56 ` Rafael J. Wysocki [this message]
2007-02-28 10:14 ` Pavel Machek
2007-02-28 15:25 ` Christoph Lameter
2007-02-28 17:13 ` Rafael J. Wysocki
2007-02-28 17:17 ` Christoph Lameter
2007-02-28 17:33 ` Rafael J. Wysocki
2007-02-28 17:35 ` Christoph Lameter
2007-02-28 17:51 ` Rafael J. Wysocki
2007-02-28 17:56 ` Christoph Lameter
2007-02-28 21:11 ` Pavel Machek
2007-03-01 2:35 ` Nick Piggin
2007-03-01 15:18 ` Nick Piggin
2007-03-01 15:33 ` Rafael J. Wysocki
2007-03-01 23:10 ` Rafael J. Wysocki
2007-03-04 13:50 ` [RFC][PATCH 0/3] swsusp: Do not use page flags (was: Re: Remove page flags for software suspend) Rafael J. Wysocki
2007-03-04 14:07 ` [RFC][PATCH 1/3] swsusp: Do not use page flags directly Rafael J. Wysocki
2007-03-13 4:45 ` Nick Piggin
2007-03-04 14:07 ` [RFC][PATCH 2/3] swsusp: Do not use page flags Rafael J. Wysocki
2007-03-13 4:47 ` Nick Piggin
2007-03-13 9:16 ` Rafael J. Wysocki
2007-03-13 9:23 ` Nick Piggin
2007-03-13 10:17 ` Rafael J. Wysocki
2007-03-13 10:31 ` Nick Piggin
2007-03-13 21:20 ` Rafael J. Wysocki
2007-03-14 3:17 ` Nick Piggin
2007-03-14 8:30 ` Rafael J. Wysocki
2007-03-04 14:08 ` [RFC][PATCH 3/3] mm: Remove nosave and nosave_free " Rafael J. Wysocki
2007-03-08 1:00 ` [RFC][PATCH 0/3] swsusp: Do not use page flags (was: Re: Remove page flags for software suspend) Johannes Berg
2007-03-08 22:05 ` Rafael J. Wysocki
2007-03-08 22:10 ` Johannes Berg
2007-03-08 22:33 ` Rafael J. Wysocki
2007-03-08 22:43 ` Johannes Berg
2007-03-08 22:54 ` Rafael J. Wysocki
2007-03-08 22:54 ` Johannes Berg
2007-03-08 23:15 ` Pavel Machek
2007-03-08 23:21 ` Johannes Berg
2007-03-08 23:23 ` Pavel Machek
2007-03-08 23:34 ` Rafael J. Wysocki
2007-03-08 23:36 ` Pavel Machek
2007-03-08 15:09 ` Johannes Berg
2007-03-08 22:10 ` Rafael J. Wysocki
2007-03-08 22:12 ` Johannes Berg
2007-03-08 15:53 ` Peter Zijlstra
2007-03-08 22:11 ` Rafael J. Wysocki
2007-03-01 17:48 ` Remove page flags for software suspend Hugh Dickins
2007-03-13 3:36 ` Nick Piggin
2007-03-01 20:46 ` Rafael J. Wysocki
2007-03-02 10:17 ` Pavel Machek
2007-02-28 21:08 ` Pavel Machek
2007-02-28 21:16 ` Christoph Lameter
2007-02-28 21:22 ` Pavel Machek
2007-02-28 22:23 ` Rafael J. Wysocki
2007-03-01 2:31 ` Nick Piggin
2007-02-28 10:14 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200702161156.21496.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=clameter@sgi.com \
--cc=linux-mm@kvack.org \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox