Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Apr 2008 23:55:49 +0200
From:      Mel <fbsd.questions@rachie.is-a-geek.net>
To:        freebsd-questions@freebsd.org, freebsd@sopwith.solgatos.com
Subject:   Re: 6.2 -> 7.0 now mlock(2) fails
Message-ID:  <200804122355.49490.fbsd.questions@rachie.is-a-geek.net>
In-Reply-To: <200804122051.UAA06080@sopwith.solgatos.com>
References:  <200804122051.UAA06080@sopwith.solgatos.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Saturday 12 April 2008 14:51:16 Dieter wrote:
> > > I never saw mlock(2) fail in 6.2 but with 7.0 I sometimes
> > > get mlock(2) failed: Resource temporarily unavailable.
> >
> > That's error EAGAIN:
> >
> >      [EAGAIN]           Locking the indicated range would exceed
> >                         either the system or per-process limit
> >                         for locked memory.
> >
> > You are hitting either the `vm.max_wired' limit, or the per-process
> > RLIMIT_MEMLOCK limit.
> >
> > > What changed and how do I fix it?
> >
> > It would be nice if you could run a test program that prints the value of
> > vm.max_wired and RLIMIT_MEMLOCK on 6.2 and then on 7.0.  As an extra
> > test, it may be worth printing these values in the log of your
> > application when mlock(2) fails.
>
> vm.max_wired looks like a sysctl, but sysctl doesn't know about it.
>
> sysctl: unknown oid 'vm.max_wired'
>
> sysctl -a | grep -i wire | grep -vi firewire
> vm.stats.vm.v_wire_count: 89046
>
> /usr/include/sys/resource.h:#define     RLIMIT_MEMLOCK  6               /*
> locked-in-memory address space */
>
> It doesn't always fail, just sometimes.  It is trying to lock 172490752
> bytes. There can be two processes wanting to do this at once.  Seems to be
> the 2nd one that sometimes fails.

If these are your own programs, you should build in the following logic:

struct rlimit rl;

if( -1 == getrlimit(RLMIT_MEMLOCK, &rlp) )
{
	/* cannot even get the limit, should probably bail here */
}
if( rlp.rlim_cur < sizeof(i_want_to_lock_this) )
{
	/* bail out or try increasing the limit then bail */
}

As for the sysctl, I'm pretty sure it's a loader tunable, like the more known 
kern.maxdsiz.

On a 7-stable and a 6.2-'stable' machine, I get exactly the same values:
# cat t.c
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <err.h>
#include <sysexits.h>
#include <stdio.h>

int main(int unused_argc, char **unused_argv)
{
        struct rlimit rl;

        if( -1 == getrlimit(RLIMIT_MEMLOCK, &rl) )
                err(EX_OSERR, "Cannot get limit");

        printf("memlock.current=%u\n", rl.rlim_cur);
        printf("memlock.max=%u\n", rl.rlim_max);

        return EX_OK;
}

# gcc -o t t.c

# ./t
memlock.current=4294967295
memlock.max=4294967295

-- 
Mel

Problem with today's modular software: they start with the modules
    and never get to the software part.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804122355.49490.fbsd.questions>