From c9253e931d306584898f210227172785fe663d45 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 23 Jun 2009 20:57:27 +0000 Subject: [PATCH] Usermode portion of the support for swap allocation accounting: - update for getrlimit(2) manpage; - support for setting RLIMIT_SWAP in login class; - addition to the limits(1) and sh and csh limit-setting builtins; - tuning(7) documentation on the sysctls controlling overcommit. In collaboration with: pho Reviewed by: alc Approved by: re (kensmith) --- bin/sh/miscbltin.c | 2 +- contrib/tcsh/sh.func.c | 4 ++++ contrib/tcsh/tcsh.man | 3 +++ etc/login.conf | 1 + lib/libc/sys/getrlimit.2 | 9 +++++++++ lib/libutil/login_class.c | 1 + share/man/man7/tuning.7 | 29 +++++++++++++++++++++++++++++ share/man/man9/vm_map.9 | 4 ++++ usr.bin/limits/limits.c | 36 +++++++++++++++++++++++------------- 9 files changed, 75 insertions(+), 14 deletions(-) diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index acb565468d16..a663c7535a55 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -403,7 +403,7 @@ ulimitcmd(int argc __unused, char **argv __unused) struct rlimit limit; what = 'f'; - while ((optc = nextopt("HSatfdsmcnuvlbp")) != '\0') + while ((optc = nextopt("HSatfdsmcnuvlbpw")) != '\0') switch (optc) { case 'H': how = HARD; diff --git a/contrib/tcsh/sh.func.c b/contrib/tcsh/sh.func.c index 92e2447f3851..f3a1fb04f2f1 100644 --- a/contrib/tcsh/sh.func.c +++ b/contrib/tcsh/sh.func.c @@ -1796,6 +1796,10 @@ struct limits limits[] = { RLIMIT_SBSIZE, "sbsize", 1, "" }, # endif /* RLIMIT_SBSIZE */ +# ifdef RLIMIT_SWAP + { RLIMIT_SWAP, "swaplimit", 1024, "kbytes" }, +# endif /* RLIMIT_SWAP */ + { -1, NULL, 0, NULL } }; diff --git a/contrib/tcsh/tcsh.man b/contrib/tcsh/tcsh.man index 0c9c3b6a10af..ac0de18a227e 100644 --- a/contrib/tcsh/tcsh.man +++ b/contrib/tcsh/tcsh.man @@ -2921,6 +2921,9 @@ the maximum number of simultaneous processes for this user id .TP \fIsbsize\fR the maximum size of socket buffer usage for this user +.TP +\fIswaplimit\fR +the maximum amount of swap space reserved or used for this user .PP \fImaximum-use\fR may be given as a (floating point or integer) number followed by a scale factor. For all limits diff --git a/etc/login.conf b/etc/login.conf index 8d2e16e26e19..c55054c07265 100644 --- a/etc/login.conf +++ b/etc/login.conf @@ -40,6 +40,7 @@ default:\ :maxproc=unlimited:\ :sbsize=unlimited:\ :vmemoryuse=unlimited:\ + :swapuse=unlimited:\ :pseudoterminals=unlimited:\ :priority=0:\ :ignoretime@:\ diff --git a/lib/libc/sys/getrlimit.2 b/lib/libc/sys/getrlimit.2 index d3550d296825..48feea0e440e 100644 --- a/lib/libc/sys/getrlimit.2 +++ b/lib/libc/sys/getrlimit.2 @@ -97,6 +97,15 @@ mbufs, that this user may hold at any time. The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed automatically by the system. +.It Dv RLIMIT_SWAP +The maximum size (in bytes) of the swap space that may be reserved or +used by all of this user id's processes. +This limit is enforced only if bit 1 of the +.Va vm.overcommit +sysctl is set. +Please see +.Xr tuning 7 +for a complete description of this sysctl. .It Dv RLIMIT_NPTS The maximum number of pseudo-terminals created by this user id. .El diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 507451958d1e..d54b30140e0b 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -64,6 +64,7 @@ static struct login_res { { "sbsize", login_getcapsize, RLIMIT_SBSIZE }, { "vmemoryuse", login_getcapsize, RLIMIT_VMEM }, { "pseudoterminals", login_getcapnum, RLIMIT_NPTS }, + { "swapuse", login_getcapsize, RLIMIT_SWAP }, { NULL, 0, 0 } }; diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7 index 9041181984c3..34c8ac37c188 100644 --- a/share/man/man7/tuning.7 +++ b/share/man/man7/tuning.7 @@ -404,6 +404,35 @@ In this document we will only cover the ones that have the greatest effect on the system. .Pp The +.Va vm.overcommit +sysctl defines the overcommit behaviour of the vm subsystem. +The virtual memory system always does accounting of the swap space +reservation, both total for system and per-user. Corresponding values +are available through sysctl +.Va vm.swap_total, +that gives the total bytes available for swapping, and +.Va vm.swap_reserved, +that gives number of bytes that may be needed to back all currently +allocated anonymous memory. +.Pp +Setting bit 0 of the +.Va vm.overcommit +sysctl causes the virtual memory system to return failure +to the process when allocation of memory causes vm.swap_reserved +to exceed vm.swap_total. +Bit 1 of the sysctl enforces RLIMIT_SWAP limit +(see +.Xr getrlimit 2 ). +Root is exempt from this limit. +Bit 2 allows to count most of the physical +memory as allocatable, except wired and free reserved pages +(accounted by +.Va vm.stats.vm.v_free_target +and +.Va vm.stats.vm.v_wire_count +sysctls, respectively). +.Pp +The .Va kern.ipc.maxpipekva loader tunable is used to set a hard limit on the amount of kernel address space allocated to mapping of pipe buffers. diff --git a/share/man/man9/vm_map.9 b/share/man/man9/vm_map.9 index 285d1d750eaa..12112cd21da5 100644 --- a/share/man/man9/vm_map.9 +++ b/share/man/man9/vm_map.9 @@ -146,6 +146,10 @@ Do not include the mapping in a core dump. .It Dv MAP_PREFAULT_MADVISE Specify that the request is from a user process calling .Xr madvise 2 . +.It Dv MAP_ACC_CHARGED +Region is already charged to the requestor by some means. +.It Dv MAP_ACC_NO_CHARGE +Do not charge for allocated region. .El .Pp The diff --git a/usr.bin/limits/limits.c b/usr.bin/limits/limits.c index 1440250349dc..2da69a23c64f 100644 --- a/usr.bin/limits/limits.c +++ b/usr.bin/limits/limits.c @@ -87,7 +87,8 @@ static struct { { " openfiles%-4s %8s", "\n", 1 }, { " sbsize%-4s %8s", " bytes\n", 1 }, { " vmemoryuse%-4s %8s", " kB\n", 1024 }, - { " pseudo-terminals%-4s %8s", "\n", 1 } + { " pseudo-terminals%-4s %8s", "\n", 1 }, + { " swapuse%-4s %8s", " kB\n", 1024 } } }, { "sh", "unlimited", "", " -H", " -S", "", @@ -103,7 +104,8 @@ static struct { { "ulimit%s -n %s", ";\n", 1 }, { "ulimit%s -b %s", ";\n", 1 }, { "ulimit%s -v %s", ";\n", 1024 }, - { "ulimit%s -p %s", ";\n", 1 } + { "ulimit%s -p %s", ";\n", 1 }, + { "ulimit%s -w %s", ";\n", 1024 } } }, { "csh", "unlimited", "", " -h", "", NULL, @@ -119,7 +121,8 @@ static struct { { "limit%s openfiles %s", ";\n", 1 }, { "limit%s sbsize %s", ";\n", 1 }, { "limit%s vmemoryuse %s", ";\n", 1024 }, - { "limit%s pseudoterminals %s", ";\n", 1 } + { "limit%s pseudoterminals %s", ";\n", 1 }, + { "limit%s swapuse %s", ";\n", 1024 } } }, { "bash|bash2", "unlimited", "", " -H", " -S", "", @@ -135,7 +138,8 @@ static struct { { "ulimit%s -n %s", ";\n", 1 }, { "ulimit%s -b %s", ";\n", 1 }, { "ulimit%s -v %s", ";\n", 1024 }, - { "ulimit%s -p %s", ";\n", 1 } + { "ulimit%s -p %s", ";\n", 1 }, + { "ulimit%s -w %s", ";\n", 1024 } } }, { "tcsh", "unlimited", "", " -h", "", NULL, @@ -151,7 +155,8 @@ static struct { { "limit%s descriptors %s", ";\n", 1 }, { "limit%s sbsize %s", ";\n", 1 }, { "limit%s vmemoryuse %s", ";\n", 1024 }, - { "limit%s pseudoterminals %s", ";\n", 1 } + { "limit%s pseudoterminals %s", ";\n", 1 }, + { "limit%s swapuse %s", ";\n", 1024 } } }, { "ksh|pdksh", "unlimited", "", " -H", " -S", "", @@ -167,7 +172,8 @@ static struct { { "ulimit%s -n %s", ";\n", 1 }, { "ulimit%s -b %s", ";\n", 1 }, { "ulimit%s -v %s", ";\n", 1024 }, - { "ulimit%s -p %s", ";\n", 1 } + { "ulimit%s -p %s", ";\n", 1 }, + { "ulimit%s -w %s", ";\n", 1024 } } }, { "zsh", "unlimited", "", " -H", " -S", "", @@ -183,7 +189,8 @@ static struct { { "ulimit%s -n %s", ";\n", 1 }, { "ulimit%s -b %s", ";\n", 1 }, { "ulimit%s -v %s", ";\n", 1024 }, - { "ulimit%s -p %s", ";\n", 1 } + { "ulimit%s -p %s", ";\n", 1 }, + { "ulimit%s -w %s", ";\n", 1024 } } }, { "rc|es", "unlimited", "", " -h", "", NULL, @@ -199,7 +206,8 @@ static struct { { "limit%s descriptors %s", ";\n", 1 }, { "limit%s sbsize %s", ";\n", 1 }, { "limit%s vmemoryuse %s", ";\n", 1024 }, - { "limit%s pseudoterminals %s", ";\n", 1 } + { "limit%s pseudoterminals %s", ";\n", 1 }, + { "limit%s swapuse %s", ";\n", 1024 } } }, { NULL, NULL, NULL, NULL, NULL, NULL, @@ -220,9 +228,10 @@ static struct { { "memorylocked", login_getcapsize }, { "maxproc", login_getcapnum }, { "openfiles", login_getcapnum }, - { "sbsize", login_getcapsize }, - { "vmemoryuse", login_getcapsize }, + { "sbsize", login_getcapsize }, + { "vmemoryuse", login_getcapsize }, { "pseudoterminals",login_getcapnum }, + { "swapuse", login_getcapsize } }; /* @@ -233,7 +242,7 @@ static struct { * to be modified accordingly! */ -#define RCS_STRING "tfdscmlunbvp" +#define RCS_STRING "tfdscmlunbvpw" static rlim_t resource_num(int which, int ch, const char *str); static void usage(void); @@ -270,7 +279,7 @@ main(int argc, char *argv[]) } optarg = NULL; - while ((ch = getopt(argc, argv, ":EeC:U:BSHab:c:d:f:l:m:n:s:t:u:v:p:")) != -1) { + while ((ch = getopt(argc, argv, ":EeC:U:BSHab:c:d:f:l:m:n:s:t:u:v:p:w:")) != -1) { switch(ch) { case 'a': doall = 1; @@ -484,7 +493,7 @@ static void usage(void) { (void)fprintf(stderr, -"usage: limits [-C class|-U user] [-eaSHBE] [-bcdflmnstuvp [val]] [[name=val ...] cmd]\n"); +"usage: limits [-C class|-U user] [-eaSHBE] [-bcdflmnstuvpw [val]] [[name=val ...] cmd]\n"); exit(EXIT_FAILURE); } @@ -556,6 +565,7 @@ resource_num(int which, int ch, const char *str) case RLIMIT_MEMLOCK: case RLIMIT_SBSIZE: case RLIMIT_VMEM: + case RLIMIT_SWAP: errno = 0; res = 0; while (*s) {