[lkml]   [1997]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    SubjectPatch for large kmalloc() problems
    There is a longstanding problem that kmalloc() often fails to allocate
    big blocks of memory, due to memory fragmentation. While we can't do
    much about it in the GFP_ATOMIC case, I think kmalloc() should try
    a little harder to free some pages for normal GFP_KERNEL allocations.
    For example, the ftape module often fails to load if the system has
    been up for some time - needs three contiguous 32K DMA buffers, and
    there are enough free pages, but they are too fragmented.

    The following test module was used to test the patch. Without the
    patch, trying to insmod it almost always fails (with a "Couldn't get
    a free page..." printk), with the patch it works. The patch is at
    the end of this mail.

    /* big.c - kmalloc test module */

    #define __KERNEL__
    #define MODULE

    #include <linux/module.h>
    #include <linux/malloc.h>

    /* can be changed via insmod, maximum kmalloc size is the default */
    int size = 131048;

    static void *p;

    p = kmalloc(size, GFP_KERNEL | GFP_DMA);
    if (!p)
    return -ENOMEM;
    return 0;

    /* end of kmalloc test module */

    Below is the patch (for 2.0.27 - but shouldn't be too hard to apply
    to 2.1.xx by hand). Please test it and let me know if there are any
    problems with it. If there will ever be another 2.0.xx kernel, and
    the patch doesn't cause problems, I think this small patch should be
    integrated in the stable kernel - otherwise it is problematic to use
    ftape as a module: you never know if it will load this time or not
    (loads fine at system startup - not much memory fragmentation yet).

    Happy hacking,


    --- linux/mm/page_alloc.c.orig Sat Aug 17 20:19:29 1996
    +++ linux/mm/page_alloc.c Sat Jan 11 05:44:58 1997
    @@ -210,11 +210,10 @@
    if ((priority==GFP_ATOMIC) || nr_free_pages > reserved_pages) {
    RMQUEUE(order, dma);
    - restore_flags(flags);
    - return 0;
    - if (priority != GFP_BUFFER && try_to_free_page(priority, dma, 1))
    + if (priority != GFP_ATOMIC && priority != GFP_BUFFER &&
    + try_to_free_page(priority, dma, 1))
    goto repeat;
    return 0;
     \ /
      Last update: 2005-03-22 13:38    [W:0.019 / U:8.132 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site