lkml.org 
[lkml]   [2006]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: kernel BUGs when removing largish files with the SLOB allocator
    On 9/6/06, Nick Piggin <nickpiggin@yahoo.com.au> wrote:
    > Aubrey wrote:
    >
    > > Yeah, I agree with most of your opinion. Using PG_slab is really a
    > > quickest way to determine the size of the object. But I think using a
    > > flag named "PG_slab" on a memory algorithm named "slob" seems not
    > > reasonable. It may confuse the people who start to read the kernel
    > > source code. So I'm writing to ask if there is a better solution to
    > > fix the issue.
    >
    >
    > No, confusing would be a "slab replacement" that doesn't provide the same
    > API as slab and thus requires users to use ifdefs.
    >
    > I've already suggested exact same thing as David in the exact same situation
    > about 6 months ago. It is the right way to go.

    OK. Here is the patch and work properly on my side.
    Welcome any suggestions and comments.

    Thanks,
    -Aubrey
    =================================================================
    diff --git a/mm/slob.c b/mm/slob.c
    index 7b52b20..18ed170 100644
    --- a/mm/slob.c
    +++ b/mm/slob.c
    @@ -109,6 +109,7 @@ static void *slob_alloc(size_t size, gfp

    slob_free(cur, PAGE_SIZE);
    spin_lock_irqsave(&slob_lock, flags);
    + SetPageSlab(virt_to_page(cur));
    cur = slobfree;
    }
    }
    @@ -162,6 +163,8 @@ void *kmalloc(size_t size, gfp_t gfp)
    slob_t *m;
    bigblock_t *bb;
    unsigned long flags;
    + int i;
    + struct page *page;

    if (size < PAGE_SIZE - SLOB_UNIT) {
    m = slob_alloc(size + SLOB_UNIT, gfp, 0);
    @@ -173,12 +176,17 @@ void *kmalloc(size_t size, gfp_t gfp)
    return 0;

    bb->order = find_order(size);
    - bb->pages = (void *)__get_free_pages(gfp, bb->order);
    + page = alloc_pages(gfp, bb->order);
    + bb->pages = (void *)page_address(page);

    if (bb->pages) {
    spin_lock_irqsave(&block_lock, flags);
    bb->next = bigblocks;
    bigblocks = bb;
    + for (i = 0; i < (1 << bb->order); i++) {
    + SetPageSlab(page);
    + page++;
    + }
    spin_unlock_irqrestore(&block_lock, flags);
    return bb->pages;
    }
    @@ -202,8 +210,16 @@ void kfree(const void *block)
    spin_lock_irqsave(&block_lock, flags);
    for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
    if (bb->pages == block) {
    + struct page *page = virt_to_page(bb->pages);
    + int i;
    +
    *last = bb->next;
    spin_unlock_irqrestore(&block_lock, flags);
    + for (i = 0; i < (1 << bb->order); i++) {
    + if (!TestClearPageSlab(page))
    + BUG();
    + page++;
    + }
    free_pages((unsigned long)block, bb->order);
    slob_free(bb, sizeof(bigblock_t));
    return;
    @@ -332,10 +348,12 @@ static struct timer_list slob_timer = TI

    void kmem_cache_init(void)
    {
    +#if 0
    void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);

    if (p)
    free_page((unsigned long)p);
    +#endif

    mod_timer(&slob_timer, jiffies + HZ);
    }
    -
    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: 2006-09-12 19:19    [W:4.743 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site