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;

Reply via email to