diff options
author | sobomax <sobomax@FreeBSD.org> | 2008-03-16 06:21:30 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2008-03-16 06:21:30 +0000 |
commit | 1560402d31fc795d7c3f43a5af671bc3a1c5993b (patch) | |
tree | abb94b15894e30e305aecbb46933267e61066559 | |
parent | 3da38e35b432b5fa7610547f1a01f367bdae5dbf (diff) | |
download | FreeBSD-src-1560402d31fc795d7c3f43a5af671bc3a1c5993b.zip FreeBSD-src-1560402d31fc795d7c3f43a5af671bc3a1c5993b.tar.gz |
Properly set size of the file_zone to match kern.maxfiles parameter.
Otherwise the parameter is no-op, since zone by default limits number
of descriptors to some 12K entries. Attempt to allocate more ends up
sleeping on zonelimit.
MFC after: 2 weeks
-rw-r--r-- | sys/kern/kern_descrip.c | 39 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 1 | ||||
-rw-r--r-- | sys/sys/eventhandler.h | 1 |
3 files changed, 38 insertions, 3 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 5174c15..683da72 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2801,8 +2801,38 @@ DB_SHOW_COMMAND(files, db_show_files) SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, &maxfilesperproc, 0, "Maximum files allowed open per process"); -SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, - &maxfiles, 0, "Maximum number of files"); +/* + * User has changed the maximum number of files. + * This may require us to change size of the zone. + */ +static int +sysctl_kern_maxfiles(SYSCTL_HANDLER_ARGS) +{ + int error; + int new_maxfiles; + + new_maxfiles = maxfiles; + error = sysctl_handle_int(oidp, &new_maxfiles, sizeof(int), req); + if (error != 0 || req->newptr == NULL) + return (error); + if (new_maxfiles <= 0) { + return (EINVAL); + } + maxfiles = new_maxfiles; + EVENTHANDLER_INVOKE(maxfiles_change); + return (0); +} + +static void +file_zone_change(void *tag) +{ + + uma_zone_set_max(file_zone, maxfiles); +} + +SYSCTL_PROC(_kern, OID_AUTO, maxfiles, CTLTYPE_INT|CTLFLAG_RW, + __DEVOLATILE(int *, &maxfiles), 0, sysctl_kern_maxfiles, "IU", + "Maximum number of files"); SYSCTL_INT(_kern, OID_AUTO, openfiles, CTLFLAG_RD, __DEVOLATILE(int *, &openfiles), 0, "System-wide number of open files"); @@ -2814,10 +2844,13 @@ filelistinit(void *dummy) file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); + uma_zone_set_max(file_zone, maxfiles); + EVENTHANDLER_REGISTER(maxfiles_change, file_zone_change, NULL, + EVENTHANDLER_PRI_FIRST); mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF); } -SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL) +SYSINIT(select, SI_SUB_EVENTHANDLER+1, SI_ORDER_MIDDLE, filelistinit, NULL) /*-------------------------------------------------------------------*/ diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index bbb4f89..5110261 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -222,6 +222,7 @@ sysctl_maxsockets(SYSCTL_HANDLER_ARGS) if (maxsockets > ((maxfiles / 4) * 3)) { maxfiles = (maxsockets * 5) / 4; maxfilesperproc = (maxfiles * 9) / 10; + EVENTHANDLER_INVOKE(maxfiles_change); } EVENTHANDLER_INVOKE(maxsockets_change); } else diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 00d124d..2cd6056 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -207,6 +207,7 @@ EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); typedef void (*uma_zone_chfn)(void *); EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); +EVENTHANDLER_DECLARE(maxfiles_change, uma_zone_chfn); typedef void(*schedtail_fn)(void *, struct proc *); EVENTHANDLER_DECLARE(schedtail, schedtail_fn); |