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
This commit is contained in:
parent
453130d9bf
commit
f8ce3dfaf1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=298956
@ -25,11 +25,11 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 23, 2016
|
.Dd April 29, 2016
|
||||||
.Dt HASHINIT 9
|
.Dt HASHINIT 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm hashinit , hashinit_flags , hashdestroy , phashinit
|
.Nm hashinit , hashinit_flags , hashdestroy , phashinit , phashinit_flags
|
||||||
.Nd manage kernel hash tables
|
.Nd manage kernel hash tables
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In sys/malloc.h
|
.In sys/malloc.h
|
||||||
@ -45,12 +45,14 @@
|
|||||||
.Fn hashdestroy "void *hashtbl" "struct malloc_type *type" "u_long hashmask"
|
.Fn hashdestroy "void *hashtbl" "struct malloc_type *type" "u_long hashmask"
|
||||||
.Ft "void *"
|
.Ft "void *"
|
||||||
.Fn phashinit "int nelements" "struct malloc_type *type" "u_long *nentries"
|
.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
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Fn hashinit ,
|
.Fn hashinit ,
|
||||||
.Fn hashinit_flags
|
.Fn hashinit_flags ,
|
||||||
and
|
|
||||||
.Fn phashinit
|
.Fn phashinit
|
||||||
|
and
|
||||||
|
.Fn phashinit_flags
|
||||||
functions allocate space for hash tables of size given by the argument
|
functions allocate space for hash tables of size given by the argument
|
||||||
.Fa nelements .
|
.Fa nelements .
|
||||||
.Pp
|
.Pp
|
||||||
@ -71,6 +73,12 @@ function operates like
|
|||||||
but also accepts an additional argument
|
but also accepts an additional argument
|
||||||
.Fa flags
|
.Fa flags
|
||||||
which control various options during allocation.
|
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
|
Allocated hash tables are contiguous arrays of
|
||||||
.Xr LIST_HEAD 3
|
.Xr LIST_HEAD 3
|
||||||
entries, allocated using
|
entries, allocated using
|
||||||
@ -100,13 +108,19 @@ must be used with one of the following values.
|
|||||||
.It Dv HASH_NOWAIT
|
.It Dv HASH_NOWAIT
|
||||||
Any malloc performed by the
|
Any malloc performed by the
|
||||||
.Fn hashinit_flags
|
.Fn hashinit_flags
|
||||||
|
and
|
||||||
|
.Fn phashinit_flags
|
||||||
function will not be allowed to wait, and therefore may fail.
|
function will not be allowed to wait, and therefore may fail.
|
||||||
.It Dv HASH_WAITOK
|
.It Dv HASH_WAITOK
|
||||||
Any malloc performed by
|
Any malloc performed by
|
||||||
.Fn hashinit_flags
|
.Fn hashinit_flags
|
||||||
|
and
|
||||||
|
.Fn phashinit_flags
|
||||||
function is allowed to wait for memory.
|
function is allowed to wait for memory.
|
||||||
This is also the behavior of
|
This is also the behavior of
|
||||||
.Fn hashinit .
|
.Fn hashinit
|
||||||
|
and
|
||||||
|
.Fn phashinit .
|
||||||
.El
|
.El
|
||||||
.Sh IMPLEMENTATION NOTES
|
.Sh IMPLEMENTATION NOTES
|
||||||
The largest prime hash value chosen by
|
The largest prime hash value chosen by
|
||||||
|
@ -104,16 +104,21 @@ static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531,
|
|||||||
#define NPRIMES nitems(primes)
|
#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 *
|
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;
|
long hashsize;
|
||||||
LIST_HEAD(generic, generic) *hashtbl;
|
LIST_HEAD(generic, generic) *hashtbl;
|
||||||
int i;
|
int i, m_flags;
|
||||||
|
|
||||||
KASSERT(elements > 0, ("%s: bad elements", __func__));
|
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;) {
|
for (i = 1, hashsize = primes[1]; hashsize <= elements;) {
|
||||||
i++;
|
i++;
|
||||||
if (i == NPRIMES)
|
if (i == NPRIMES)
|
||||||
@ -121,9 +126,25 @@ phashinit(int elements, struct malloc_type *type, u_long *nentries)
|
|||||||
hashsize = primes[i];
|
hashsize = primes[i];
|
||||||
}
|
}
|
||||||
hashsize = primes[i - 1];
|
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++)
|
for (i = 0; i < hashsize; i++)
|
||||||
LIST_INIT(&hashtbl[i]);
|
LIST_INIT(&hashtbl[i]);
|
||||||
*nentries = hashsize;
|
*nentries = hashsize;
|
||||||
return (hashtbl);
|
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));
|
||||||
|
}
|
||||||
|
@ -189,6 +189,8 @@ void *hashinit_flags(int count, struct malloc_type *type,
|
|||||||
#define HASH_WAITOK 0x00000002
|
#define HASH_WAITOK 0x00000002
|
||||||
|
|
||||||
void *phashinit(int count, struct malloc_type *type, u_long *nentries);
|
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 g_waitidle(void);
|
||||||
|
|
||||||
void panic(const char *, ...) __dead2 __printflike(1, 2);
|
void panic(const char *, ...) __dead2 __printflike(1, 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user