pcb table auto resize (Re: diff: add tuning variables to config(8))
Hi, On Tue, 17 Jun 2014 12:48:24 +0900 (JST) YASUOKA Masahiko wrote: > On Mon, 16 Jun 2014 11:35:07 -0600 > Theo de Raadt wrote: >>> > Followings are our kernel variables' default: >>> > >>> > - sb_max: 256K >>> > - tcbhash_size: 128 >>> > - udbhash_size: 128 >>> > >>> > These variables are sometime too small for busy server or gateway. >>> > >>> > I'd like to modify config(8) to customize these variables without >>> > recompiling the kernel. >>> >>> If we go this route, I would rather have a generic command (such as "set >>> ") to change kernel variables. >>> >>> The list of said variables would still be restricted to what a given >>> config(8) knows, to prevent people from tinkering with things they are >>> not supposed to touch. >> >> I quite dislike the direction this is going. >> >> It seems like you have found 3 variables which should auto-tune. >> So why not write kernel code to auto-tune them? > > I didn't notice that way, but auto-tune seems better. > > I modified in_pcbtable to resize automatically if the number of pcb > entries beyonds 75% of the hash size. I'm testing this. I've tested and any problem was not found. As far as my test, this improved relayd's HTTP connection relay rate from 5000 conn/sec to 8000 conn/sec on Core2 Duo. ok? Resize the pcb hashtable automatically. The table size will be doubled when the number of the hash entries reaches 75% of the table size. Index: sys/netinet/in_pcb.c === RCS file: /disk/cvs/openbsd/src/sys/netinet/in_pcb.c,v retrieving revision 1.156 diff -u -p -r1.156 in_pcb.c --- sys/netinet/in_pcb.c4 Jun 2014 13:45:47 - 1.156 +++ sys/netinet/in_pcb.c27 Jun 2014 09:53:27 - @@ -118,6 +118,10 @@ struct baddynamicports baddynamicports; struct pool inpcb_pool; int inpcb_pool_initialized = 0; +int in_pcbresize (struct inpcbtable *, int); + +#defineINPCBHASH_LOADFACTOR(_x)(((_x) * 3) / 4) + #defineINPCBHASH(table, faddr, fport, laddr, lport, rdom) \ &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \ ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)] @@ -144,6 +148,7 @@ in_pcbinit(struct inpcbtable *table, int if (table->inpt_lhashtbl == NULL) panic("in_pcbinit: hashinit failed for lport"); table->inpt_lastport = 0; + table->inpt_count = 0; } /* @@ -191,6 +196,9 @@ in_pcballoc(struct socket *so, struct in inp->inp_seclevel[SL_IPCOMP] = IPSEC_IPCOMP_LEVEL_DEFAULT; inp->inp_rtableid = curproc->p_p->ps_rtableid; s = splnet(); + if (table->inpt_hash != 0 && + table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_hash)) + (void)in_pcbresize(table, (table->inpt_hash + 1) * 2); TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rtableid), inp, inp_lhash); @@ -502,6 +510,7 @@ in_pcbdetach(struct inpcb *inp) LIST_REMOVE(inp, inp_lhash); LIST_REMOVE(inp, inp_hash); TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); + inp->inp_table->inpt_count--; splx(s); pool_put(&inpcb_pool, inp); } @@ -878,6 +887,39 @@ in_pcbrehash(struct inpcb *inp) } #endif /* INET6 */ splx(s); +} + +int +in_pcbresize(struct inpcbtable *table, int hashsize) +{ + u_long nhash, nlhash; + void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl; + struct inpcb *inp0, *inp1; + + ohashtbl = table->inpt_hashtbl; + olhashtbl = table->inpt_lhashtbl; + + nhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nhash); + nlhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nlhash); + if (nhashtbl == NULL || nlhashtbl == NULL) { + if (nhashtbl != NULL) + free(nhashtbl, M_PCB); + if (nlhashtbl != NULL) + free(nlhashtbl, M_PCB); + return (ENOBUFS); + } + table->inpt_hashtbl = nhashtbl; + table->inpt_lhashtbl = nlhashtbl; + table->inpt_hash = nhash; + table->inpt_lhash = nlhash; + + TAILQ_FOREACH_SAFE(inp0, &table->inpt_queue, inp_queue, inp1) { + in_pcbrehash(inp0); + } + free(ohashtbl, M_PCB); + free(olhashtbl, M_PCB); + + return (0); } #ifdef DIAGNOSTIC Index: sys/netinet/in_pcb.h === RCS file: /disk/cvs/openbsd/src/sys/netinet/in_pcb.h,v retrieving revision 1.85 diff -u -p -r1.85 in_pcb.h --- sys/netinet/in_pcb.h18 Apr 2014 10:48:29 - 1.85 +++ sys/netinet/in_pcb.h27 Jun 2014 09:52:26 - @@ -158,6 +158,7 @@ struct inpcbtable { LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl, *inpt_lhashtbl; u_longinpt_hash, inpt_lhash; u_int16_t inpt_lastport; + int inpt_count; }; /* f
Re: diff: add tuning variables to config(8)
Hi, On Tue, 17 Jun 2014 09:43:07 +0200 Claudio Jeker wrote: > On Mon, Jun 16, 2014 at 11:35:07AM -0600, Theo de Raadt wrote: >> > > Followings are our kernel variables' default: >> > > >> > > - sb_max: 256K >> > > - tcbhash_size: 128 >> > > - udbhash_size: 128 >> > > >> > > These variables are sometime too small for busy server or gateway. >> > > >> > > I'd like to modify config(8) to customize these variables without >> > > recompiling the kernel. >> > >> > If we go this route, I would rather have a generic command (such as "set >> > ") to change kernel variables. >> > >> > The list of said variables would still be restricted to what a given >> > config(8) knows, to prevent people from tinkering with things they are >> > not supposed to touch. >> >> >> I quite dislike the direction this is going. >> >> It seems like you have found 3 variables which should auto-tune. >> So why not write kernel code to auto-tune them? > > We could replace the hashes with RB trees. I think that would be better > than having to rehash the list. To tune sb_max we need a way to have > memory limits so that the socket buffers don't consume all the resources > and starve the kernel out of memory. I think resizing the hash tables is better than replacing with RB tree. Hash pros: - faster - not so big - easy to understand and customize(eg. adding lock for parallel) cons: - need rehash when growing up --yasuoka
Re: diff: add tuning variables to config(8)
On Mon, Jun 16, 2014 at 11:35:07AM -0600, Theo de Raadt wrote: > > > Followings are our kernel variables' default: > > > > > > - sb_max: 256K > > > - tcbhash_size: 128 > > > - udbhash_size: 128 > > > > > > These variables are sometime too small for busy server or gateway. > > > > > > I'd like to modify config(8) to customize these variables without > > > recompiling the kernel. > > > > If we go this route, I would rather have a generic command (such as "set > > ") to change kernel variables. > > > > The list of said variables would still be restricted to what a given > > config(8) knows, to prevent people from tinkering with things they are > > not supposed to touch. > > > I quite dislike the direction this is going. > > It seems like you have found 3 variables which should auto-tune. > So why not write kernel code to auto-tune them? > We could replace the hashes with RB trees. I think that would be better than having to rehash the list. To tune sb_max we need a way to have memory limits so that the socket buffers don't consume all the resources and starve the kernel out of memory. I think implementing the RB tree is fairly trivial (I did this once 10 years ago) but resource management is a fair bit more work. -- :wq Claudio
Re: diff: add tuning variables to config(8)
On Mon, 16 Jun 2014 11:35:07 -0600 Theo de Raadt wrote: >> > Followings are our kernel variables' default: >> > >> > - sb_max: 256K >> > - tcbhash_size: 128 >> > - udbhash_size: 128 >> > >> > These variables are sometime too small for busy server or gateway. >> > >> > I'd like to modify config(8) to customize these variables without >> > recompiling the kernel. >> >> If we go this route, I would rather have a generic command (such as "set >> ") to change kernel variables. >> >> The list of said variables would still be restricted to what a given >> config(8) knows, to prevent people from tinkering with things they are >> not supposed to touch. > > I quite dislike the direction this is going. > > It seems like you have found 3 variables which should auto-tune. > So why not write kernel code to auto-tune them? I didn't notice that way, but auto-tune seems better. I modified in_pcbtable to resize automatically if the number of pcb entries beyonds 75% of the hash size. I'm testing this. (currently I have no idea for sb_max.) comments? Index: sys/netinet/in_pcb.c === RCS file: /disk/cvs/openbsd/src/sys/netinet/in_pcb.c,v retrieving revision 1.156 diff -u -p -r1.156 in_pcb.c --- sys/netinet/in_pcb.c4 Jun 2014 13:45:47 - 1.156 +++ sys/netinet/in_pcb.c17 Jun 2014 03:36:35 - @@ -118,6 +118,8 @@ struct baddynamicports baddynamicports; struct pool inpcb_pool; int inpcb_pool_initialized = 0; +int in_pcbresize (struct inpcbtable *, int); + #defineINPCBHASH(table, faddr, fport, laddr, lport, rdom) \ &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \ ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)] @@ -144,6 +146,7 @@ in_pcbinit(struct inpcbtable *table, int if (table->inpt_lhashtbl == NULL) panic("in_pcbinit: hashinit failed for lport"); table->inpt_lastport = 0; + table->inpt_count = 0; } /* @@ -191,6 +194,9 @@ in_pcballoc(struct socket *so, struct in inp->inp_seclevel[SL_IPCOMP] = IPSEC_IPCOMP_LEVEL_DEFAULT; inp->inp_rtableid = curproc->p_p->ps_rtableid; s = splnet(); + if (table->inpt_hash != 0 && + table->inpt_count++ > (table->inpt_hash * 3) / 4) + (void)in_pcbresize(table, (table->inpt_hash + 1) * 2); TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rtableid), inp, inp_lhash); @@ -502,6 +508,7 @@ in_pcbdetach(struct inpcb *inp) LIST_REMOVE(inp, inp_lhash); LIST_REMOVE(inp, inp_hash); TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); + inp->inp_table->inpt_count--; splx(s); pool_put(&inpcb_pool, inp); } @@ -878,6 +885,38 @@ in_pcbrehash(struct inpcb *inp) } #endif /* INET6 */ splx(s); +} + +int +in_pcbresize(struct inpcbtable *table, int hashsize) +{ + u_long nhash, nlhash; + void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl; + struct inpcb *inp0, *inp1; + + ohashtbl = table->inpt_hashtbl; + olhashtbl = table->inpt_lhashtbl; + nhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nhash); + nlhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nlhash); + if (nhashtbl == NULL || nlhashtbl == NULL) { + if (nhashtbl != NULL) + free(nhashtbl, M_PCB); + if (nlhashtbl != NULL) + free(nlhashtbl, M_PCB); + return (ENOBUFS); + } + table->inpt_hashtbl = nhashtbl; + table->inpt_lhashtbl = nlhashtbl; + table->inpt_hash = nhash; + table->inpt_lhash = nlhash; + + TAILQ_FOREACH_SAFE(inp0, &table->inpt_queue, inp_queue, inp1) { + in_pcbrehash(inp0); + } + free(ohashtbl, M_PCB); + free(olhashtbl, M_PCB); + + return (0); } #ifdef DIAGNOSTIC Index: sys/netinet/in_pcb.h === RCS file: /disk/cvs/openbsd/src/sys/netinet/in_pcb.h,v retrieving revision 1.85 diff -u -p -r1.85 in_pcb.h --- sys/netinet/in_pcb.h18 Apr 2014 10:48:29 - 1.85 +++ sys/netinet/in_pcb.h17 Jun 2014 03:36:35 - @@ -158,6 +158,7 @@ struct inpcbtable { LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl, *inpt_lhashtbl; u_longinpt_hash, inpt_lhash; u_int16_t inpt_lastport; + int inpt_count; }; /* flags in inp_flags: */
Re: diff: add tuning variables to config(8)
> > Followings are our kernel variables' default: > > > > - sb_max: 256K > > - tcbhash_size: 128 > > - udbhash_size: 128 > > > > These variables are sometime too small for busy server or gateway. > > > > I'd like to modify config(8) to customize these variables without > > recompiling the kernel. > > If we go this route, I would rather have a generic command (such as "set > ") to change kernel variables. > > The list of said variables would still be restricted to what a given > config(8) knows, to prevent people from tinkering with things they are > not supposed to touch. I quite dislike the direction this is going. It seems like you have found 3 variables which should auto-tune. So why not write kernel code to auto-tune them?
Re: diff: add tuning variables to config(8)
On Monday, June 16, 2014 18:55 CEST, Miod Vallat wrote: > > Followings are our kernel variables' default: > > > > - sb_max: 256K > > - tcbhash_size: 128 > > - udbhash_size: 128 > > > > These variables are sometime too small for busy server or gateway. > > > > I'd like to modify config(8) to customize these variables without > > recompiling the kernel. > > If we go this route, I would rather have a generic command (such as "set > ") to change kernel variables. > > The list of said variables would still be restricted to what a given > config(8) knows, to prevent people from tinkering with things they are > not supposed to touch. at least for sb_max I once sent a patch to tech@ [1] to change it via sysctl, but that was unfortunately rejected ;) So, I'd still find it easier to change the sysctl than a changing it with config(8). But on the other hand, sysctl might be too easy to use for $average user, and making it only accessible via config(8) may prevent whining users. cheers, Sebastian [1 ] https://groups.google.com/forum/#!topic/mailing.openbsd.tech/kMRT8VO2VaA > > Miod >
Re: diff: add tuning variables to config(8)
> Followings are our kernel variables' default: > > - sb_max: 256K > - tcbhash_size: 128 > - udbhash_size: 128 > > These variables are sometime too small for busy server or gateway. > > I'd like to modify config(8) to customize these variables without > recompiling the kernel. If we go this route, I would rather have a generic command (such as "set ") to change kernel variables. The list of said variables would still be restricted to what a given config(8) knows, to prevent people from tinkering with things they are not supposed to touch. Miod
Re: diff: add tuning variables to config(8)
On Mon, 16 Jun 2014 21:28:55 +0900 (JST) YASUOKA Masahiko wrote: > Followings are our kernel variables' default: > > - sb_max: 256K > - tcbhash_size: 128 > - udbhash_size: 128 > > These variables are sometime too small for busy server or gateway. > > I'd like to modify config(8) to customize these variables without > recompiling the kernel. > > Comment or ok? Let me update the diff. Previous diff has some typos. Index: usr.sbin/config/cmd.c === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/cmd.c,v retrieving revision 1.20 diff -u -p -r1.20 cmd.c --- usr.sbin/config/cmd.c 23 Nov 2013 17:38:15 - 1.20 +++ usr.sbin/config/cmd.c 16 Jun 2014 12:25:59 - @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include @@ -61,6 +61,11 @@ cmd_table_t cmd_table[] = { {"bufcachepercent", Xbufcachepct, "[number]", "Show/change BUFCACHEPERCENT"}, {"nkmempg", Xnkmempg, "[number]", "Show/change NKMEMPAGES"}, + {"sb_max", Xsb_max, "[number]", "Show/change sb_max"}, + {"udbhashsize", Xudbhashsize, "[number]", +"Show/change udbhashsize"}, + {"tcbhashsize", Xtcbhashsize, "[number]", +"Show/change tcbhashsize"}, {NULL, NULL,NULL, NULL} }; @@ -313,5 +318,58 @@ int Xnkmempg(cmd_t *cmd) { int_variable_adjust(cmd, I_NKMEMPG, "nkmempages"); + return (CMD_CONT); +} + +int +Xsb_max(cmd_t *cmd) +{ + int_variable_adjust(cmd, I_SB_MAX, "sb_max"); + return (CMD_CONT); +} + +void +pow2_variable_adjust(const cmd_t *cmd, int idx, const char *name) +{ + int i, *v, num; + + if (nl[idx].n_type != 0) { + ukc_mod_kernel = 1; + + v = (int *)adjust((caddr_t)(nl[idx].n_value)); + + if (strlen(cmd->args) == 0) { + printf("%s = %d\n", name, *v); + } else { + if (number(cmd->args, &num) == 0) { +if (!powerof2(num)) { + for (i = 0; num; num = num >> 1) + i++; + num = 1 << i; + printf("Warning: number must be " + "power of 2. Rounded up to %d\n", + num); + } + *v = num; + printf("%s = %d\n", name, num); + } else + printf("Unknown argument\n"); + } + } else + printf("This kernel does not support modification of %s.\n", + name); +} + +int +Xudbhashsize(cmd_t *cmd) +{ + pow2_variable_adjust(cmd, I_UDBHASHSIZE, "udbhashsize"); + return (CMD_CONT); +} + +int +Xtcbhashsize(cmd_t *cmd) +{ + pow2_variable_adjust(cmd, I_TCBHASHSIZE, "tcbhashsize"); return (CMD_CONT); } Index: usr.sbin/config/cmd.h === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/cmd.h,v retrieving revision 1.7 diff -u -p -r1.7 cmd.h --- usr.sbin/config/cmd.h 3 Jun 2003 00:52:35 - 1.7 +++ usr.sbin/config/cmd.h 16 Jun 2014 11:58:37 - @@ -72,6 +72,9 @@ int Xbufcachepct(cmd_t *); int Xnkmempg(cmd_t *); int Xshmseg(cmd_t *); int Xshmmaxpgs(cmd_t *); +int Xsb_max(cmd_t *); +int Xudbhashsize(cmd_t *); +int Xtcbhashsize(cmd_t *); #endif /* _CMD_H */ Index: usr.sbin/config/config.8 === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/config.8,v retrieving revision 1.60 diff -u -p -r1.60 config.8 --- usr.sbin/config/config.820 Jan 2014 01:11:49 - 1.60 +++ usr.sbin/config/config.816 Jun 2014 12:41:49 - @@ -321,6 +321,21 @@ is the number of minutes west of GMT and .Va dst is non-zero if Daylight Saving Time is in effect. Without arguments, displays its current value. +.It Ic sb_max Op Ar number +Change the sb_max value. +Without arguments, displays its current value. +.It Ic tcbhashsize Op Ar number +Change the tcbhashsize value. +Without arguments, displays its current value. +The +.Ar number +should be power of 2, otherwise it will be rounded up forcibly. +.It Ic udbhashsize Op Ar number +Change the udbhashsize value. +Without arguments, displays its current value. +The +.Ar number +should be power of 2, otherwise it will be rounded up forcibly. .El .Sh EXAMPLES (kernel building) Note: Index: usr.sbin/config/ukc.h === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/ukc.h,v retrieving revision 1.12 diff -u -p -r1.12 ukc.h --- usr.sbin/config/ukc.h
diff: add tuning variables to config(8)
Followings are our kernel variables' default: - sb_max: 256K - tcbhash_size: 128 - udbhash_size: 128 These variables are sometime too small for busy server or gateway. I'd like to modify config(8) to customize these variables without recompiling the kernel. Comment or ok? Index: usr.sbin/config/cmd.c === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/cmd.c,v retrieving revision 1.20 diff -u -p -r1.20 cmd.c --- usr.sbin/config/cmd.c 23 Nov 2013 17:38:15 - 1.20 +++ usr.sbin/config/cmd.c 16 Jun 2014 12:25:59 - @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include @@ -61,6 +61,11 @@ cmd_table_t cmd_table[] = { {"bufcachepercent", Xbufcachepct, "[number]", "Show/change BUFCACHEPERCENT"}, {"nkmempg", Xnkmempg, "[number]", "Show/change NKMEMPAGES"}, + {"sb_max", Xsb_max, "[number]", "Show/change sb_max"}, + {"udbhashsize", Xudbhashsize, "[number]", +"Show/change udbhashsize"}, + {"tcbhashsize", Xtcbhashsize, "[number]", +"Show/change tcbhashsize"}, {NULL, NULL,NULL, NULL} }; @@ -313,5 +318,58 @@ int Xnkmempg(cmd_t *cmd) { int_variable_adjust(cmd, I_NKMEMPG, "nkmempages"); + return (CMD_CONT); +} + +int +Xsb_max(cmd_t *cmd) +{ + int_variable_adjust(cmd, I_SB_MAX, "sb_max"); + return (CMD_CONT); +} + +void +pow2_variable_adjust(const cmd_t *cmd, int idx, const char *name) +{ + int i, *v, num; + + if (nl[idx].n_type != 0) { + ukc_mod_kernel = 1; + + v = (int *)adjust((caddr_t)(nl[idx].n_value)); + + if (strlen(cmd->args) == 0) { + printf("%s = %d\n", name, *v); + } else { + if (number(cmd->args, &num) == 0) { +if (!powerof2(num)) { + for (i = 0; num; num = num >> 1) + i++; + num = 1 << i; + printf("Warning: number must be " + "power of 2. Rounded up to %d\n", + num); + } + *v = num; + printf("%s = %d\n", name, num); + } else + printf("Unknown argument\n"); + } + } else + printf("This kernel does not support modification of %s.\n", + name); +} + +int +Xudbhashsize(cmd_t *cmd) +{ + pow2_variable_adjust(cmd, I_UDBHASHSIZE, "udbhashsize"); + return (CMD_CONT); +} + +int +Xtcbhashsize(cmd_t *cmd) +{ + pow2_variable_adjust(cmd, I_TCBHASHSIZE, "tcbhashsize"); return (CMD_CONT); } Index: usr.sbin/config/cmd.h === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/cmd.h,v retrieving revision 1.7 diff -u -p -r1.7 cmd.h --- usr.sbin/config/cmd.h 3 Jun 2003 00:52:35 - 1.7 +++ usr.sbin/config/cmd.h 16 Jun 2014 11:58:37 - @@ -72,6 +72,9 @@ int Xbufcachepct(cmd_t *); int Xnkmempg(cmd_t *); int Xshmseg(cmd_t *); int Xshmmaxpgs(cmd_t *); +int Xsb_max(cmd_t *); +int Xudbhashsize(cmd_t *); +int Xtcbhashsize(cmd_t *); #endif /* _CMD_H */ Index: usr.sbin/config/config.8 === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/config.8,v retrieving revision 1.60 diff -u -p -r1.60 config.8 --- usr.sbin/config/config.820 Jan 2014 01:11:49 - 1.60 +++ usr.sbin/config/config.816 Jun 2014 11:58:37 - @@ -321,6 +321,21 @@ is the number of minutes west of GMT and .Va dst is non-zero if Daylight Saving Time is in effect. Without arguments, displays its current value. +.It Ic sb_max Op Ar number +Change the sb_max value. +Without arguments, displays its current value. +.It Ic tcbhashsize Op Ar number +Change the tcbhashsize value. +Without arguments, displays its current value. +The +.Ar number +should be power of 2, otherwise it will be rounded up forcibly. +.It Ic udbhashsize Op Ar number +Change the tcbhashsize value. +Without arguments, displays its current value. +The +.Ar number +should be power of 2, otherwise it will be rounded up forcibly. .El .Sh EXAMPLES (kernel building) Note: Index: usr.sbin/config/ukc.h === RCS file: /disk/cvs/openbsd/src/usr.sbin/config/ukc.h,v retrieving revision 1.12 diff -u -p -r1.12 ukc.h --- usr.sbin/config/ukc.h 10 Dec 2009 22:07:19 - 1.12 +++ usr.sbin/config/ukc.h 16 Jun 2014 11:58:37 - @@ -48,7 +48,10 @@ #define I_NMBCLUSTERS 1