6.2 -> 7.0 now mlock(2) fails

Giorgos Keramidas keramida at ceid.upatras.gr
Sat Apr 12 21:58:40 UTC 2008


On Sat, 12 Apr 2008 13:51:16 +0100, Dieter <freebsd at sopwith.solgatos.com> 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'

Yes, indeed.  I posted before looking at the diffs between RELENG_7 and
CURRENT.  The sysctl is only present in 8.0-CURRENT:

,-----------------------------------------------------------------------
| $ pwd
| /ws/bsd/src/sys/vm
| $ cvs -qR di -u -r RELENG_7 vm_pageout.c | more
| [...]
|  int vm_page_max_wired;         /* XXX max # of wired pages system-wide
|  */
| +SYSCTL_INT(_vm, OID_AUTO, max_wired,
| +       CTLFLAG_RW, &vm_page_max_wired, 0, "System-wide limit to wired page count");
`-----------------------------------------------------------------------

The max wired page count is initialized to 1/3 of the free page count in
the pageout daemon.

> 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.
>
> with one process:
> vm.stats.vm.v_wire_count: 130992  (41946 more)
>
> with two processes (mlock failed):
> vm.stats.vm.v_wire_count: 131047  (55 more)
>
> killed both proceses:
> vm.stats.vm.v_wire_count: 88788

Can you run your first process, which successfully wires the pages, and
then capture the output of:

    sysctl vm.stats

Finally, run the second process, even if it fails to wire the pages, and
capture vm.stats once more.

PS: Please Cc: me in any responces.  I may not see your message if it
gets lots in the `noise' of a busy list like -questions.  I *do* try to
respond to messages which hit my INBOX, though :)



More information about the freebsd-questions mailing list