lkml.org 
[lkml]   [2008]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH -mm] relayfs: support larger relay buffer take 3
    Use vmalloc() and memset() instead of kcalloc() to allocate a page* array
    when the array size is bigger than one page. This enables relayfs to support
    bigger relay buffers than 64MB on 4k-page system, 512MB on 16k-page system.

    Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
    ---
    Changes from take2 to take3:
    - Use struct page ** instead of struct page *.
    - move functions to the place before relay_mmap_buf.
    - add comments.

    This is useful for a 64-bit system which has a plenty of memory (tens of
    giga bytes) and a large kernel memory space.

    I tested it on x86-64 and ia64.

    kernel/relay.c | 35 ++++++++++++++++++++++++++++++++---
    1 file changed, 32 insertions(+), 3 deletions(-)

    Index: 2.6.25-rc8-mm2/kernel/relay.c
    ===================================================================
    --- 2.6.25-rc8-mm2.orig/kernel/relay.c
    +++ 2.6.25-rc8-mm2/kernel/relay.c
    @@ -65,6 +65,35 @@ static struct vm_operations_struct relay
    .close = relay_file_mmap_close,
    };

    +/*
    + * allocate an array of pointers of struct page
    + */
    +static struct page **relay_alloc_page_array(unsigned int n_pages)
    +{
    + struct page **array;
    + unsigned int pa_size = n_pages * sizeof(struct page *);
    +
    + if (pa_size > PAGE_SIZE) {
    + array = vmalloc(pa_size);
    + if (array)
    + memset(array, 0, pa_size);
    + } else {
    + array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL);
    + }
    + return array;
    +}
    +
    +/*
    + * free an array of pointers of struct page
    + */
    +static void relay_free_page_array(struct page **array)
    +{
    + if (is_vmalloc_addr(array))
    + vfree(array);
    + else
    + kfree(array);
    +}
    +
    /**
    * relay_mmap_buf: - mmap channel buffer to process address space
    * @buf: relay channel buffer
    @@ -109,7 +138,7 @@ static void *relay_alloc_buf(struct rcha
    *size = PAGE_ALIGN(*size);
    n_pages = *size >> PAGE_SHIFT;

    - buf->page_array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL);
    + buf->page_array = relay_alloc_page_array(n_pages);
    if (!buf->page_array)
    return NULL;

    @@ -130,7 +159,7 @@ static void *relay_alloc_buf(struct rcha
    depopulate:
    for (j = 0; j < i; j++)
    __free_page(buf->page_array[j]);
    - kfree(buf->page_array);
    + relay_free_page_array(buf->page_array);
    return NULL;
    }

    @@ -189,7 +218,7 @@ static void relay_destroy_buf(struct rch
    vunmap(buf->start);
    for (i = 0; i < buf->page_count; i++)
    __free_page(buf->page_array[i]);
    - kfree(buf->page_array);
    + relay_free_page_array(buf->page_array);
    }
    chan->buf[buf->cpu] = NULL;
    kfree(buf->padding);
    --
    Masami Hiramatsu
    Software Engineer
    Hitachi Computer Products (America) Inc.
    Software Solutions Division

    e-mail: mhiramat@redhat.com



    \
     
     \ /
      Last update: 2008-04-16 21:59    [W:0.024 / U:13.304 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site