Avoid LOCKDEBUG pserialize panic by implementing suggestion #1 from
http://mail-index.netbsd.org/current-users/2019/02/24/msg035220.html: Convert the mutex to spin-lock at IPL_NET (but it is excessive) and convert the memory allocations in that code path to KM_NOSLEEP.
This commit is contained in:
parent
3907c7acbb
commit
a80fb12074
|
@ -38,7 +38,7 @@
|
|||
|
||||
#if defined(_KERNEL)
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lpm.c,v 1.5 2018/09/29 14:41:36 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lpm.c,v 1.6 2019/06/12 14:36:32 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -90,6 +90,7 @@ typedef struct {
|
|||
|
||||
struct lpm {
|
||||
uint32_t bitmask[LPM_MAX_WORDS];
|
||||
int flags;
|
||||
void * defvals[2];
|
||||
lpm_hmap_t prefix[LPM_MAX_PREFIX + 1];
|
||||
};
|
||||
|
@ -97,9 +98,11 @@ struct lpm {
|
|||
static const uint32_t zero_address[LPM_MAX_WORDS];
|
||||
|
||||
lpm_t *
|
||||
lpm_create(void)
|
||||
lpm_create(int flags)
|
||||
{
|
||||
return kmem_zalloc(sizeof(lpm_t), KM_SLEEP);
|
||||
lpm_t *lpm = kmem_zalloc(sizeof(*lpm), KM_SLEEP);
|
||||
lpm->flags = flags;
|
||||
return lpm;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -164,7 +167,7 @@ fnv1a_hash(const void *buf, size_t len)
|
|||
}
|
||||
|
||||
static bool
|
||||
hashmap_rehash(lpm_hmap_t *hmap, unsigned size)
|
||||
hashmap_rehash(lpm_hmap_t *hmap, unsigned size, int flags)
|
||||
{
|
||||
lpm_ent_t **bucket;
|
||||
unsigned hashsize;
|
||||
|
@ -172,7 +175,9 @@ hashmap_rehash(lpm_hmap_t *hmap, unsigned size)
|
|||
for (hashsize = 1; hashsize < size; hashsize <<= 1) {
|
||||
continue;
|
||||
}
|
||||
bucket = kmem_zalloc(hashsize * sizeof(lpm_ent_t *), KM_SLEEP);
|
||||
bucket = kmem_zalloc(hashsize * sizeof(lpm_ent_t *), flags);
|
||||
if (bucket == NULL)
|
||||
return false;
|
||||
for (unsigned n = 0; n < hmap->hashsize; n++) {
|
||||
lpm_ent_t *list = hmap->bucket[n];
|
||||
|
||||
|
@ -194,14 +199,14 @@ hashmap_rehash(lpm_hmap_t *hmap, unsigned size)
|
|||
}
|
||||
|
||||
static lpm_ent_t *
|
||||
hashmap_insert(lpm_hmap_t *hmap, const void *key, size_t len)
|
||||
hashmap_insert(lpm_hmap_t *hmap, const void *key, size_t len, int flags)
|
||||
{
|
||||
const unsigned target = hmap->nitems + LPM_HASH_STEP;
|
||||
const size_t entlen = offsetof(lpm_ent_t, key[len]);
|
||||
uint32_t hash, i;
|
||||
lpm_ent_t *entry;
|
||||
|
||||
if (hmap->hashsize < target && !hashmap_rehash(hmap, target)) {
|
||||
if (hmap->hashsize < target && !hashmap_rehash(hmap, target, flags)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -215,7 +220,7 @@ hashmap_insert(lpm_hmap_t *hmap, const void *key, size_t len)
|
|||
entry = entry->next;
|
||||
}
|
||||
|
||||
if ((entry = kmem_alloc(entlen, KM_SLEEP)) != NULL) {
|
||||
if ((entry = kmem_alloc(entlen, flags)) != NULL) {
|
||||
memcpy(entry->key, key, len);
|
||||
entry->next = hmap->bucket[i];
|
||||
entry->len = len;
|
||||
|
@ -326,7 +331,7 @@ lpm_insert(lpm_t *lpm, const void *addr,
|
|||
return 0;
|
||||
}
|
||||
compute_prefix(nwords, addr, preflen, prefix);
|
||||
entry = hashmap_insert(&lpm->prefix[preflen], prefix, len);
|
||||
entry = hashmap_insert(&lpm->prefix[preflen], prefix, len, lpm->flags);
|
||||
if (entry) {
|
||||
const unsigned n = --preflen >> 5;
|
||||
lpm->bitmask[n] |= 0x80000000U >> (preflen & 31);
|
||||
|
|
|
@ -32,7 +32,7 @@ __BEGIN_DECLS
|
|||
typedef struct lpm lpm_t;
|
||||
typedef void (*lpm_dtor_t)(void *, const void *, size_t, void *);
|
||||
|
||||
lpm_t * lpm_create(void);
|
||||
lpm_t * lpm_create(int);
|
||||
void lpm_destroy(lpm_t *);
|
||||
void lpm_clear(lpm_t *, lpm_dtor_t, void *);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.29 2019/01/19 21:19:32 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.30 2019/06/12 14:36:32 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -365,7 +365,7 @@ npf_table_create(const char *name, u_int tid, int type,
|
|||
|
||||
switch (type) {
|
||||
case NPF_TABLE_LPM:
|
||||
t->t_lpm = lpm_create();
|
||||
t->t_lpm = lpm_create(KM_NOSLEEP);
|
||||
if (t->t_lpm == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ npf_table_create(const char *name, u_int tid, int type,
|
|||
default:
|
||||
KASSERT(false);
|
||||
}
|
||||
mutex_init(&t->t_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
mutex_init(&t->t_lock, MUTEX_DEFAULT, IPL_NET);
|
||||
t->t_type = type;
|
||||
t->t_id = tid;
|
||||
return t;
|
||||
|
|
Loading…
Reference in New Issue