lkml.org 
[lkml]   [2002]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH]Fix: Init page count for all pages during higher order allocs
    The call to set_page_count(page, 1) in page_alloc.c appears to happen 
    only for the first page, for order 1 and higher allocations.
    This leaves the count for the rest of the pages in that block
    uninitialised.

    We ran into this while working on some lkcd changes where we check
    the page count to help exclude unreferenced pages, and found
    that we were missing some referenced pages too (e.g the second page
    of thread_info/stack pages which involve order 1 allocations)

    Here is a patch from Bharata B. Rao that sets the page count
    for all the pages allocated. This is along the same lines
    as the code in slab.c to issue SET_PAGE_CACHE/SET_PAGE_SLAB
    on all the pages in an allocated block based on the slab order.
    (That code seems to be preceded by a somewhat scary comment
    so hope there is nothing to be concerned about; are there
    any caveats ? )

    Comments ?
    Does this look like the right thing to do ?

    Regards
    Suparna

    --- 2418-pure/mm/page_alloc.c Tue Feb 26 01:08:14 2002
    +++ linux-2.4.18+lkcd/mm/page_alloc.c Mon Apr 29 14:16:37 2002
    @@ -181,7 +181,7 @@
    static struct page * rmqueue(zone_t *zone, unsigned int order)
    {
    free_area_t * area = zone->free_area + order;
    - unsigned int curr_order = order;
    + unsigned int i, curr_order = order;
    struct list_head *head, *curr;
    unsigned long flags;
    struct page *page;
    @@ -206,13 +206,18 @@
    page = expand(zone, page, index, order, curr_order, area);
    spin_unlock_irqrestore(&zone->lock, flags);

    - set_page_count(page, 1);
    - if (BAD_RANGE(zone,page))
    - BUG();
    - if (PageLRU(page))
    - BUG();
    - if (PageActive(page))
    - BUG();
    + i = 1UL << order;
    + page += i;
    + do {
    + page--;
    + set_page_count(page, 1);
    + if (BAD_RANGE(zone,page))
    + BUG();
    + if (PageLRU(page))
    + BUG();
    + if (PageActive(page))
    + BUG();
    + } while (--i);
    return page;
    }
    curr_order++;
    @@ -236,6 +241,7 @@
    {
    struct page * page = NULL;
    int __freed = 0;
    + unsigned int i;

    if (!(gfp_mask & __GFP_WAIT))
    goto out;
    @@ -264,25 +270,29 @@
    if (tmp->index == order && memclass(tmp->zone, classzone)) {
    list_del(entry);
    current->nr_local_pages--;
    - set_page_count(tmp, 1);
    - page = tmp;

    - if (page->buffers)
    - BUG();
    - if (page->mapping)
    - BUG();
    - if (!VALID_PAGE(page))
    - BUG();
    - if (PageSwapCache(page))
    - BUG();
    - if (PageLocked(page))
    - BUG();
    - if (PageLRU(page))
    - BUG();
    - if (PageActive(page))
    - BUG();
    - if (PageDirty(page))
    - BUG();
    + i = 1UL << order;
    + page = tmp + i;
    + do {
    + page--;
    + set_page_count(page, 1);
    + if (page->buffers)
    + BUG();
    + if (page->mapping)
    + BUG();
    + if (!VALID_PAGE(page))
    + BUG();
    + if (PageSwapCache(page))
    + BUG();
    + if (PageLocked(page))
    + BUG();
    + if (PageLRU(page))
    + BUG();
    + if (PageActive(page))
    + BUG();
    + if (PageDirty(page))
    + BUG();
    + } while (--i);

    break;
    }
    -
    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-03-22 13:25    [W:0.029 / U:31.104 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site