Commit 40bac04d authored by Patrick Mochel's avatar Patrick Mochel

[swsusp] Add big fat comment to calc_order().

parent 1a8e07b6
...@@ -659,13 +659,38 @@ void swsusp_free(void) ...@@ -659,13 +659,38 @@ void swsusp_free(void)
} }
/**
* calc_order - Determine the order of allocation needed for pagedir_save.
*
* This looks tricky, but is just subtle. Please fix it some time.
* Since there are %nr_copy_pages worth of pages in the snapshot, we need
* to allocate enough contiguous space to hold
* (%nr_copy_pages * sizeof(struct pbe)),
* which has the saved/orig locations of the page..
*
* SUSPEND_PD_PAGES() tells us how many pages we need to hold those
* structures, then we call get_bitmask_order(), which will tell us the
* last bit set in the number, starting with 1. (If we need 30 pages, that
* is 0x0000001e in hex. The last bit is the 5th, which is the order we
* would use to allocate 32 contiguous pages).
*
* Since we also need to save those pages, we add the number of pages that
* we need to nr_copy_pages, and in case of an overflow, do the
* calculation again to update the number of pages needed.
*
* With this model, we will tend to waste a lot of memory if we just cross
* an order boundary. Plus, the higher the order of allocation that we try
* to do, the more likely we are to fail in a low-memory situtation
* (though we're unlikely to get this far in such a case, since swsusp
* requires half of memory to be free anyway).
*/
static void calc_order(void) static void calc_order(void)
{ {
int diff; int diff = 0;
int order; int order = 0;
order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
nr_copy_pages += 1 << order;
do { do {
diff = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages)) - order; diff = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages)) - order;
if (diff) { if (diff) {
...@@ -687,7 +712,7 @@ static void calc_order(void) ...@@ -687,7 +712,7 @@ static void calc_order(void)
static int alloc_pagedir(void) static int alloc_pagedir(void)
{ {
calc_order(); calc_order();
pagedir_save = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_save = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD,
pagedir_order); pagedir_order);
if(!pagedir_save) if(!pagedir_save)
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment