Module Name:    src
Committed By:   snj
Date:           Sat Jan 13 22:10:55 UTC 2018

Modified Files:
        src/sys/net [netbsd-8]: route.c route.h

Log Message:
Pull up following revision(s) (requested by christos in ticket #496):
        sys/net/route.c: revision 1.202-1.203
        sys/net/route.h: revision 1.117
Use a queue of deferred entries to delete routes instead of a fixed stack
of 10. Otherwise we can overflow in route deletions from the rexmit timer.
--
Don't stomp past the end of the array! need __arraycount not sizeof()
Found by chuq, while debugging the sdf.org crashes
Restructure a bit for readability.


To generate a diff of this commit:
cvs rdiff -u -r1.194.6.3 -r1.194.6.4 src/sys/net/route.c
cvs rdiff -u -r1.112.4.2 -r1.112.4.3 src/sys/net/route.h

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/route.c
diff -u src/sys/net/route.c:1.194.6.3 src/sys/net/route.c:1.194.6.4
--- src/sys/net/route.c:1.194.6.3	Tue Oct 24 08:55:55 2017
+++ src/sys/net/route.c	Sat Jan 13 22:10:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: route.c,v 1.194.6.3 2017/10/24 08:55:55 snj Exp $	*/
+/*	$NetBSD: route.c,v 1.194.6.4 2018/01/13 22:10:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.3 2017/10/24 08:55:55 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.4 2018/01/13 22:10:55 snj Exp $");
 
 #include <sys/param.h>
 #ifdef RTFLUSH_DEBUG
@@ -255,7 +255,7 @@ static struct {
 	struct workqueue	*wq;
 	struct work		wk;
 	kmutex_t		lock;
-	struct rtentry		*queue[10];
+	SLIST_HEAD(, rtentry)	queue;
 } rt_free_global __cacheline_aligned;
 
 /* psref for rtentry */
@@ -458,6 +458,8 @@ rt_init(void)
 #endif
 
 	mutex_init(&rt_free_global.lock, MUTEX_DEFAULT, IPL_SOFTNET);
+	SLIST_INIT(&rt_free_global.queue);
+
 	rt_psref_class = psref_class_create("rtentry", IPL_SOFTNET);
 
 	error = workqueue_create(&rt_free_global.wq, "rt_free",
@@ -686,23 +688,20 @@ _rt_free(struct rtentry *rt)
 static void
 rt_free_work(struct work *wk, void *arg)
 {
-	int i;
-	struct rtentry *rt;
 
-restart:
-	mutex_enter(&rt_free_global.lock);
-	for (i = 0; i < sizeof(rt_free_global.queue); i++) {
-		if (rt_free_global.queue[i] == NULL)
-			continue;
-		rt = rt_free_global.queue[i];
-		rt_free_global.queue[i] = NULL;
-		mutex_exit(&rt_free_global.lock);
+	for (;;) {
+		struct rtentry *rt;
 
+		mutex_enter(&rt_free_global.lock);
+		if ((rt = SLIST_FIRST(&rt_free_global.queue)) == NULL) {
+			mutex_exit(&rt_free_global.lock);
+			return;
+		}
+		SLIST_REMOVE_HEAD(&rt_free_global.queue, rt_free);
+		mutex_exit(&rt_free_global.lock);
 		atomic_dec_uint(&rt->rt_refcnt);
 		_rt_free(rt);
-		goto restart;
 	}
-	mutex_exit(&rt_free_global.lock);
 }
 
 void
@@ -710,23 +709,17 @@ rt_free(struct rtentry *rt)
 {
 
 	KASSERT(rt->rt_refcnt > 0);
-	if (!rt_wait_ok()) {
-		int i;
-		mutex_enter(&rt_free_global.lock);
-		for (i = 0; i < sizeof(rt_free_global.queue); i++) {
-			if (rt_free_global.queue[i] == NULL) {
-				rt_free_global.queue[i] = rt;
-				break;
-			}
-		}
-		KASSERT(i < sizeof(rt_free_global.queue));
-		rt_ref(rt);
-		mutex_exit(&rt_free_global.lock);
-		workqueue_enqueue(rt_free_global.wq, &rt_free_global.wk, NULL);
-	} else {
+	if (rt_wait_ok()) {
 		atomic_dec_uint(&rt->rt_refcnt);
 		_rt_free(rt);
+		return;
 	}
+
+	mutex_enter(&rt_free_global.lock);
+	rt_ref(rt);
+	SLIST_INSERT_HEAD(&rt_free_global.queue, rt, rt_free);
+	mutex_exit(&rt_free_global.lock);
+	workqueue_enqueue(rt_free_global.wq, &rt_free_global.wk, NULL);
 }
 
 #ifdef NET_MPSAFE

Index: src/sys/net/route.h
diff -u src/sys/net/route.h:1.112.4.2 src/sys/net/route.h:1.112.4.3
--- src/sys/net/route.h:1.112.4.2	Tue Oct 24 08:55:55 2017
+++ src/sys/net/route.h	Sat Jan 13 22:10:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: route.h,v 1.112.4.2 2017/10/24 08:55:55 snj Exp $	*/
+/*	$NetBSD: route.h,v 1.112.4.3 2018/01/13 22:10:55 snj Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -124,7 +124,8 @@ struct rtentry {
 	struct	sockaddr *rt_tag;	/* route tagging info */
 #ifdef _KERNEL
 	kcondvar_t rt_cv;
-	struct psref_target	rt_psref;
+	struct psref_target rt_psref;
+	SLIST_ENTRY(rtentry) rt_free;	/* queue of deferred frees */
 #endif
 };
 

Reply via email to