Module Name: src Committed By: christos Date: Wed Jun 12 14:36:32 UTC 2019
Modified Files: src/sys/net/npf: lpm.c lpm.h npf_tableset.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/lpm.c cvs rdiff -u -r1.2 -r1.3 src/sys/net/npf/lpm.h cvs rdiff -u -r1.29 -r1.30 src/sys/net/npf/npf_tableset.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/npf/lpm.c diff -u src/sys/net/npf/lpm.c:1.5 src/sys/net/npf/lpm.c:1.6 --- src/sys/net/npf/lpm.c:1.5 Sat Sep 29 10:41:36 2018 +++ src/sys/net/npf/lpm.c Wed Jun 12 10:36:32 2019 @@ -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, unsigne 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, unsigne } 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 v 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); Index: src/sys/net/npf/lpm.h diff -u src/sys/net/npf/lpm.h:1.2 src/sys/net/npf/lpm.h:1.3 --- src/sys/net/npf/lpm.h:1.2 Sat Sep 29 10:41:36 2018 +++ src/sys/net/npf/lpm.h Wed Jun 12 10:36:32 2019 @@ -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 *); Index: src/sys/net/npf/npf_tableset.c diff -u src/sys/net/npf/npf_tableset.c:1.29 src/sys/net/npf/npf_tableset.c:1.30 --- src/sys/net/npf/npf_tableset.c:1.29 Sat Jan 19 16:19:32 2019 +++ src/sys/net/npf/npf_tableset.c Wed Jun 12 10:36:32 2019 @@ -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 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 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;