lkml.org 
[lkml]   [2005]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/3] swsusp: reduce code duplication
    Date
    The changes made by this patch are necessary for the pagedir relocation
    simplification in the next patch.  Additionally, these changes allow us to
    drop check_pagedir() and make get_safe_page() be a one-line wrapper around
    alloc_image_page() (get_safe_page() goes to snapshot.c, because
    alloc_image_page() is static and it does not make sense to export
    it).

    Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>

    kernel/power/power.h | 3 +-
    kernel/power/snapshot.c | 62 +++++++++++++++++++++++++++++++++++++-----------
    kernel/power/swsusp.c | 57 +-------------------------------------------
    3 files changed, 52 insertions(+), 70 deletions(-)

    Index: linux-2.6.14-git4/kernel/power/power.h
    ===================================================================
    --- linux-2.6.14-git4.orig/kernel/power/power.h 2005-11-01 18:18:31.000000000 +0100
    +++ linux-2.6.14-git4/kernel/power/power.h 2005-11-01 18:20:28.000000000 +0100
    @@ -66,7 +66,8 @@
    extern asmlinkage int swsusp_arch_resume(void);

    extern int restore_highmem(void);
    -extern struct pbe * alloc_pagedir(unsigned nr_pages);
    +extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
    extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
    extern void swsusp_free(void);
    +extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
    extern int enough_swap(unsigned nr_pages);
    Index: linux-2.6.14-git4/kernel/power/snapshot.c
    ===================================================================
    --- linux-2.6.14-git4.orig/kernel/power/snapshot.c 2005-11-01 18:18:31.000000000 +0100
    +++ linux-2.6.14-git4/kernel/power/snapshot.c 2005-11-01 18:20:28.000000000 +0100
    @@ -270,9 +270,30 @@
    pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
    }

    -static void *alloc_image_page(void)
    +/**
    + * @safe_needed - on resume, for storing the PBE list and the image,
    + * we can only use memory pages that do not conflict with the pages
    + * which had been used before suspend.
    + *
    + * The unsafe pages are marked with the PG_nosave_free flag
    + *
    + * Allocated but unusable (ie eaten) memory pages should be marked
    + * so that swsusp_free() can release them
    + */
    +
    +static inline void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
    {
    - void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
    + void *res;
    +
    + if (safe_needed)
    + do {
    + res = (void *)get_zeroed_page(gfp_mask);
    + if (res && PageNosaveFree(virt_to_page(res)))
    + /* This is for swsusp_free() */
    + SetPageNosave(virt_to_page(res));
    + } while (res && PageNosaveFree(virt_to_page(res)));
    + else
    + res = (void *)get_zeroed_page(gfp_mask);
    if (res) {
    SetPageNosave(virt_to_page(res));
    SetPageNosaveFree(virt_to_page(res));
    @@ -280,6 +301,11 @@
    return res;
    }

    +unsigned long get_safe_page(gfp_t gfp_mask)
    +{
    + return (unsigned long)alloc_image_page(gfp_mask, 1);
    +}
    +
    /**
    * alloc_pagedir - Allocate the page directory.
    *
    @@ -293,7 +319,7 @@
    * On each page we set up a list of struct_pbe elements.
    */

    -struct pbe *alloc_pagedir(unsigned nr_pages)
    +struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed)
    {
    unsigned num;
    struct pbe *pblist, *pbe;
    @@ -302,12 +328,12 @@
    return NULL;

    pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
    - pblist = alloc_image_page();
    + pblist = alloc_image_page(gfp_mask, safe_needed);
    /* FIXME: rewrite this ugly loop */
    for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
    pbe = pbe->next, num += PBES_PER_PAGE) {
    pbe += PB_PAGE_SKIP;
    - pbe->next = alloc_image_page();
    + pbe->next = alloc_image_page(gfp_mask, safe_needed);
    }
    if (!pbe) { /* get_zeroed_page() failed */
    free_pagedir(pblist);
    @@ -355,24 +381,32 @@
    (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
    }

    +int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
    +{
    + struct pbe *p;
    +
    + for_each_pbe (p, pblist) {
    + p->address = (unsigned long)alloc_image_page(gfp_mask, safe_needed);
    + if (!p->address)
    + return -ENOMEM;
    + }
    + return 0;
    +}

    static struct pbe *swsusp_alloc(unsigned nr_pages)
    {
    - struct pbe *pblist, *p;
    + struct pbe *pblist;

    - if (!(pblist = alloc_pagedir(nr_pages))) {
    + if (!(pblist = alloc_pagedir(nr_pages, GFP_ATOMIC | __GFP_COLD, 0))) {
    printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
    return NULL;
    }
    create_pbe_list(pblist, nr_pages);

    - for_each_pbe (p, pblist) {
    - p->address = (unsigned long)alloc_image_page();
    - if (!p->address) {
    - printk(KERN_ERR "suspend: Allocating image pages failed.\n");
    - swsusp_free();
    - return NULL;
    - }
    + if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
    + printk(KERN_ERR "suspend: Allocating image pages failed.\n");
    + swsusp_free();
    + return NULL;
    }

    return pblist;
    Index: linux-2.6.14-git4/kernel/power/swsusp.c
    ===================================================================
    --- linux-2.6.14-git4.orig/kernel/power/swsusp.c 2005-11-01 18:18:31.000000000 +0100
    +++ linux-2.6.14-git4/kernel/power/swsusp.c 2005-11-01 18:20:28.000000000 +0100
    @@ -636,59 +636,6 @@
    }

    /**
    - * On resume, for storing the PBE list and the image,
    - * we can only use memory pages that do not conflict with the pages
    - * which had been used before suspend.
    - *
    - * We don't know which pages are usable until we allocate them.
    - *
    - * Allocated but unusable (ie eaten) memory pages are marked so that
    - * swsusp_free() can release them
    - */
    -
    -unsigned long get_safe_page(gfp_t gfp_mask)
    -{
    - unsigned long m;
    -
    - do {
    - m = get_zeroed_page(gfp_mask);
    - if (m && PageNosaveFree(virt_to_page(m)))
    - /* This is for swsusp_free() */
    - SetPageNosave(virt_to_page(m));
    - } while (m && PageNosaveFree(virt_to_page(m)));
    - if (m) {
    - /* This is for swsusp_free() */
    - SetPageNosave(virt_to_page(m));
    - SetPageNosaveFree(virt_to_page(m));
    - }
    - return m;
    -}
    -
    -/**
    - * check_pagedir - We ensure here that pages that the PBEs point to
    - * won't collide with pages where we're going to restore from the loaded
    - * pages later
    - */
    -
    -static int check_pagedir(struct pbe *pblist)
    -{
    - struct pbe *p;
    -
    - /* This is necessary, so that we can free allocated pages
    - * in case of failure
    - */
    - for_each_pbe (p, pblist)
    - p->address = 0UL;
    -
    - for_each_pbe (p, pblist) {
    - p->address = get_safe_page(GFP_ATOMIC);
    - if (!p->address)
    - return -ENOMEM;
    - }
    - return 0;
    -}
    -
    -/**
    * swsusp_pagedir_relocate - It is possible, that some memory pages
    * occupied by the list of PBEs collide with pages where we're going to
    * restore from the loaded pages later. We relocate them here.
    @@ -997,7 +944,7 @@
    int error = 0;
    struct pbe *p;

    - if (!(p = alloc_pagedir(nr_copy_pages)))
    + if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
    return -ENOMEM;

    if ((error = read_pagedir(p)))
    @@ -1010,7 +957,7 @@

    /* Allocate memory for the image and read the data from swap */

    - error = check_pagedir(pagedir_nosave);
    + error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);

    if (!error)
    error = data_read(pagedir_nosave);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-11-02 00:58    [W:0.054 / U:237.860 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site