Index: head/share/man/man9/hashinit.9 =================================================================== --- head/share/man/man9/hashinit.9 +++ head/share/man/man9/hashinit.9 @@ -25,11 +25,11 @@ .\" .\" $FreeBSD$ .\" -.Dd January 23, 2016 +.Dd April 29, 2016 .Dt HASHINIT 9 .Os .Sh NAME -.Nm hashinit , hashinit_flags , hashdestroy , phashinit +.Nm hashinit , hashinit_flags , hashdestroy , phashinit , phashinit_flags .Nd manage kernel hash tables .Sh SYNOPSIS .In sys/malloc.h @@ -45,12 +45,14 @@ .Fn hashdestroy "void *hashtbl" "struct malloc_type *type" "u_long hashmask" .Ft "void *" .Fn phashinit "int nelements" "struct malloc_type *type" "u_long *nentries" +.Fn phashinit_flags "int nelements" "struct malloc_type *type" "u_long *nentries" "int flags" .Sh DESCRIPTION The .Fn hashinit , -.Fn hashinit_flags -and +.Fn hashinit_flags , .Fn phashinit +and +.Fn phashinit_flags functions allocate space for hash tables of size given by the argument .Fa nelements . .Pp @@ -71,6 +73,12 @@ but also accepts an additional argument .Fa flags which control various options during allocation. +.Fn phashinit_flags +function operates like +.Fn phashinit +but also accepts an additional argument +.Fa flags +which control various options during allocation. Allocated hash tables are contiguous arrays of .Xr LIST_HEAD 3 entries, allocated using @@ -100,13 +108,19 @@ .It Dv HASH_NOWAIT Any malloc performed by the .Fn hashinit_flags +and +.Fn phashinit_flags function will not be allowed to wait, and therefore may fail. .It Dv HASH_WAITOK Any malloc performed by .Fn hashinit_flags +and +.Fn phashinit_flags function is allowed to wait for memory. This is also the behavior of -.Fn hashinit . +.Fn hashinit +and +.Fn phashinit . .El .Sh IMPLEMENTATION NOTES The largest prime hash value chosen by Index: head/sys/kern/subr_hash.c =================================================================== --- head/sys/kern/subr_hash.c +++ head/sys/kern/subr_hash.c @@ -104,16 +104,21 @@ #define NPRIMES nitems(primes) /* - * General routine to allocate a prime number sized hash table. + * General routine to allocate a prime number sized hash table with control of + * memory flags. */ void * -phashinit(int elements, struct malloc_type *type, u_long *nentries) +phashinit_flags(int elements, struct malloc_type *type, u_long *nentries, int flags) { long hashsize; LIST_HEAD(generic, generic) *hashtbl; - int i; + int i, m_flags; KASSERT(elements > 0, ("%s: bad elements", __func__)); + /* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */ + KASSERT((flags & HASH_WAITOK) ^ (flags & HASH_NOWAIT), + ("Bad flags (0x%x) passed to phashinit_flags", flags)); + for (i = 1, hashsize = primes[1]; hashsize <= elements;) { i++; if (i == NPRIMES) @@ -121,9 +126,25 @@ hashsize = primes[i]; } hashsize = primes[i - 1]; - hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK); + + m_flags = (flags & HASH_NOWAIT) ? M_NOWAIT : M_WAITOK; + hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, m_flags); + if (hashtbl == NULL) + return (NULL); + for (i = 0; i < hashsize; i++) LIST_INIT(&hashtbl[i]); *nentries = hashsize; return (hashtbl); } + +/* + * Allocate and initialize a prime number sized hash table with default flag: + * may sleep. + */ +void * +phashinit(int elements, struct malloc_type *type, u_long *nentries) +{ + + return (phashinit_flags(elements, type, nentries, HASH_WAITOK)); +} Index: head/sys/sys/systm.h =================================================================== --- head/sys/sys/systm.h +++ head/sys/sys/systm.h @@ -189,6 +189,8 @@ #define HASH_WAITOK 0x00000002 void *phashinit(int count, struct malloc_type *type, u_long *nentries); +void *phashinit_flags(int count, struct malloc_type *type, u_long *nentries, + int flags); void g_waitidle(void); void panic(const char *, ...) __dead2 __printflike(1, 2);