mlock() return value issue in kernel 2.6.23.17 - Kernel

This is a discussion on mlock() return value issue in kernel 2.6.23.17 - Kernel ; Hi all, Please find the below testcase provide to test mlock. Test Case : =========================== #include #include #include #include #include #include #include #include #include int main(void) { int fd,ret, i = 0; char *addr, *addr1 = NULL; unsigned int page_size; ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: mlock() return value issue in kernel 2.6.23.17

  1. mlock() return value issue in kernel 2.6.23.17


    Hi all,

    Please find the below testcase provide to test mlock.

    Test Case :
    ===========================

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    int main(void)
    {
    int fd,ret, i = 0;
    char *addr, *addr1 = NULL;
    unsigned int page_size;
    struct rlimit rlim;

    if (0 != geteuid())
    {
    printf("Execute this pgm as root\n");
    exit(1);
    }

    /* create a file */
    if ((fd = open("mmap_test.c",O_RDWR|O_CREAT,0755)) == -1)
    {
    printf("cant create test file\n");
    exit(1);
    }

    page_size = sysconf(_SC_PAGE_SIZE);

    /* set the MEMLOCK limit */
    rlim.rlim_cur = 2000;
    rlim.rlim_max = 2000;

    if ((ret = setrlimit(RLIMIT_MEMLOCK,&rlim)) != 0)
    {
    printf("Cant change limit values\n");
    exit(1);
    }

    addr = 0;
    while (1)
    {
    /* map a page into memory each time*/
    if ((addr = (char *) mmap(addr,page_size, PROT_READ |
    PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED)
    {
    printf("cant do mmap on file\n");
    exit(1);
    }

    if (0 == i)
    addr1 = addr;
    i++;
    errno = 0;
    /* lock the mapped memory pagewise*/
    if ((ret = mlock((char *)addr, 1500)) == -1)
    {
    printf("errno value is %d\n", errno);
    printf("cant lock maped region\n");
    exit(1);
    }
    addr = addr + page_size;
    }
    }
    ================================================== ====


    This testcase results with mlock failure with errno 14 that is EFAULT, but this
    has been no where reported that mlock will give EFAULT, When i tested the same
    on older kernel like 2.6.18, I got the correct result i.e errno 12 (ENOMEM).


    I think in source code mlock(2), setting errno ENOMEM has been missed in
    do_mlock() , on mlock_fixup() failure.

    Let me know if my understanding is wrong!

    Thanks,
    Halesh


    --
    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/

  2. Re: mlock() return value issue in kernel 2.6.23.17

    >
    > This testcase results with mlock failure with errno 14 that is EFAULT, but this
    > has been no where reported that mlock will give EFAULT, When i tested the same
    > on older kernel like 2.6.18, I got the correct result i.e errno 12 (ENOMEM).
    >
    >
    > I think in source code mlock(2), setting errno ENOMEM has been missed in
    > do_mlock() , on mlock_fixup() failure.
    >
    > Let me know if my understanding is wrong!


    Hi Halesh,

    Could you try to following patch?

    -----------------------------------------------------
    SUSv3 require following behavior to mlock(2).

    [ENOMEM]
    Some or all of the address range specified by the addr and
    len arguments does not correspond to valid mapped pages
    in the address space of the process.

    [EAGAIN]
    Some or all of the memory identified by the operation could not
    be locked when the call was made.


    This rule isn't so nice and slighly strange.
    but many people think POSIX/SUS compliance is important.


    ---
    mm/memory.c | 16 +++++++++++++---
    mm/mlock.c | 2 --
    2 files changed, 13 insertions(+), 5 deletions(-)

    Index: b/mm/memory.c
    ================================================== =================
    --- a/mm/memory.c
    +++ b/mm/memory.c
    @@ -2736,16 +2736,26 @@ int make_pages_present(unsigned long add

    vma = find_vma(current->mm, addr);
    if (!vma)
    - return -1;
    + return -ENOMEM;
    write = (vma->vm_flags & VM_WRITE) != 0;
    BUG_ON(addr >= end);
    BUG_ON(end > vma->vm_end);
    len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE;
    ret = get_user_pages(current, current->mm, addr,
    len, write, 0, NULL, NULL);
    - if (ret < 0)
    + if (ret < 0) {
    + /*
    + SUS require strange return value to mlock
    + - invalid addr generate to ENOMEM.
    + - out of memory should generate EAGAIN.
    + */
    + if (ret == -EFAULT)
    + ret = -ENOMEM;
    + else if (ret == -ENOMEM)
    + ret = -EAGAIN;
    return ret;
    - return ret == len ? 0 : -1;
    + }
    + return ret == len ? 0 : -ENOMEM;
    }

    #if !defined(__HAVE_ARCH_GATE_AREA)
    Index: b/mm/mlock.c
    ================================================== =================
    --- a/mm/mlock.c
    +++ b/mm/mlock.c
    @@ -78,8 +78,6 @@ success:

    mm->locked_vm -= pages;
    out:
    - if (ret == -ENOMEM)
    - ret = -EAGAIN;
    return ret;
    }



    --
    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/

  3. Re: mlock() return value issue in kernel 2.6.23.17

    On Thu, 31 Jul 2008 21:50:06 +0900
    KOSAKI Motohiro wrote:

    > >
    > > This testcase results with mlock failure with errno 14 that is EFAULT, but this
    > > has been no where reported that mlock will give EFAULT, When i tested the same
    > > on older kernel like 2.6.18, I got the correct result i.e errno 12 (ENOMEM).
    > >
    > >
    > > I think in source code mlock(2), setting errno ENOMEM has been missed in
    > > do_mlock() , on mlock_fixup() failure.
    > >
    > > Let me know if my understanding is wrong!

    >
    > Hi Halesh,
    >
    > Could you try to following patch?
    >
    > -----------------------------------------------------
    > SUSv3 require following behavior to mlock(2).
    >
    > [ENOMEM]
    > Some or all of the address range specified by the addr and
    > len arguments does not correspond to valid mapped pages
    > in the address space of the process.
    >
    > [EAGAIN]
    > Some or all of the memory identified by the operation could not
    > be locked when the call was made.
    >
    >
    > This rule isn't so nice and slighly strange.
    > but many people think POSIX/SUS compliance is important.
    >
    >
    > ---
    > mm/memory.c | 16 +++++++++++++---
    > mm/mlock.c | 2 --
    > 2 files changed, 13 insertions(+), 5 deletions(-)
    >
    > Index: b/mm/memory.c
    > ================================================== =================
    > --- a/mm/memory.c
    > +++ b/mm/memory.c
    > @@ -2736,16 +2736,26 @@ int make_pages_present(unsigned long add
    >
    > vma = find_vma(current->mm, addr);
    > if (!vma)
    > - return -1;
    > + return -ENOMEM;
    > write = (vma->vm_flags & VM_WRITE) != 0;
    > BUG_ON(addr >= end);
    > BUG_ON(end > vma->vm_end);
    > len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE;
    > ret = get_user_pages(current, current->mm, addr,
    > len, write, 0, NULL, NULL);
    > - if (ret < 0)
    > + if (ret < 0) {
    > + /*
    > + SUS require strange return value to mlock
    > + - invalid addr generate to ENOMEM.
    > + - out of memory should generate EAGAIN.
    > + */
    > + if (ret == -EFAULT)
    > + ret = -ENOMEM;
    > + else if (ret == -ENOMEM)
    > + ret = -EAGAIN;
    > return ret;
    > - return ret == len ? 0 : -1;
    > + }
    > + return ret == len ? 0 : -ENOMEM;
    > }
    >
    > #if !defined(__HAVE_ARCH_GATE_AREA)
    > Index: b/mm/mlock.c
    > ================================================== =================
    > --- a/mm/mlock.c
    > +++ b/mm/mlock.c
    > @@ -78,8 +78,6 @@ success:
    >
    > mm->locked_vm -= pages;
    > out:
    > - if (ret == -ENOMEM)
    > - ret = -EAGAIN;
    > return ret;
    > }
    >
    >


    I assume that you tested it too?

    If it comes down to a choice between complying with SuS versus
    complying with earlier Linux versions then we'd usually prefer to
    comply with earlier Linux versions.

    I queued this, but would prefer to await confirmation that it has been
    tested to take us back to the 2.6.18 interface, please.

    Also, please send a Signed-off-by: for this change.
    --
    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/

  4. Re: mlock() return value issue in kernel 2.6.23.17

    Hi Andrew,

    > I assume that you tested it too?


    Yes, my x86_64 box works well.

    sorry, ambiguity e-mail.

    halesh's test check two point.
    - mlock rlimit
    - invlid address range

    and, I think rlimit already works well.
    So, I ask halesh re-confirming.

    > If it comes down to a choice between complying with SuS versus
    > complying with earlier Linux versions then we'd usually prefer to
    > comply with earlier Linux versions.


    I see.

    > I queued this, but would prefer to await confirmation that it has been
    > tested to take us back to the 2.6.18 interface, please.


    Yes.
    this patch wasn't tested on split-lru yet.
    I'll do that. (and probably fix it)

    > Also, please send a Signed-off-by: for this change.


    Agghh, sorry. it is stupid forgotten.



    --
    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/

+ Reply to Thread