summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-05-03 07:17:13 +0000
committersephe <sephe@FreeBSD.org>2016-05-03 07:17:13 +0000
commit50eba76e306f52b315e2e304800e2ac27563d1e5 (patch)
tree45a74f9502b2a5aab2e82bc6a51bb083759e6779
parenteed4bd22add2269ccde27996035581801316c610 (diff)
downloadFreeBSD-src-50eba76e306f52b315e2e304800e2ac27563d1e5.zip
FreeBSD-src-50eba76e306f52b315e2e304800e2ac27563d1e5.tar.gz
kern: Add phashinit_flags(), which allows malloc(M_NOWAIT)
It will be used for the upcoming LRO hash table initialization. And probably will be useful in other cases, when M_WAITOK can't be used. Reviewed by: jhb, kib Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6138
-rw-r--r--share/man/man9/hashinit.924
-rw-r--r--sys/kern/subr_hash.c29
-rw-r--r--sys/sys/systm.h2
3 files changed, 46 insertions, 9 deletions
diff --git a/share/man/man9/hashinit.9 b/share/man/man9/hashinit.9
index 65ef10e..5357a95e 100644
--- a/share/man/man9/hashinit.9
+++ b/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 @@ function operates like
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 @@ must be used with one of the following values.
.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
diff --git a/sys/kern/subr_hash.c b/sys/kern/subr_hash.c
index 915f3f7..4d9249f 100644
--- a/sys/kern/subr_hash.c
+++ b/sys/kern/subr_hash.c
@@ -104,16 +104,21 @@ static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531,
#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 @@ phashinit(int elements, struct malloc_type *type, u_long *nentries)
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));
+}
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 34ad5ba..1f05f69 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -189,6 +189,8 @@ void *hashinit_flags(int count, struct malloc_type *type,
#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);
OpenPOWER on IntegriCloud