Module Name:    src
Committed By:   ozaki-r
Date:           Wed Sep  9 01:26:50 UTC 2015

Modified Files:
        src/sys/net: if_llatbl.c

Log Message:
Fix race condition on la_rt between lltable_free and other places touching la_rt

We have to touch la_rt always with holding softnet_lock. And we have to
use callout_halt with softnet_lock instead of callout_stop for
la_timer (arptimer) because arptimer holds softnet_lock inside it.

This fix may solve a kernel panic christos@ encountered.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/net/if_llatbl.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/if_llatbl.c
diff -u src/sys/net/if_llatbl.c:1.3 src/sys/net/if_llatbl.c:1.4
--- src/sys/net/if_llatbl.c:1.3	Mon Aug 31 12:57:45 2015
+++ src/sys/net/if_llatbl.c	Wed Sep  9 01:26:50 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_llatbl.c,v 1.3 2015/08/31 12:57:45 pooka Exp $	*/
+/*	$NetBSD: if_llatbl.c,v 1.4 2015/09/09 01:26:50 ozaki-r Exp $	*/
 /*
  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
@@ -42,6 +42,7 @@
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
 #include <sys/socket.h>
+#include <sys/socketvar.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -370,8 +371,9 @@ lltable_free(struct lltable *llt)
 	llentries_unlink(llt, &dchain);
 	IF_AFDATA_WUNLOCK(llt->llt_ifp);
 
+	mutex_enter(softnet_lock);
 	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
-		if (callout_stop(&lle->la_timer))
+		if (callout_halt(&lle->la_timer, softnet_lock))
 			LLE_REMREF(lle);
 #if defined(__NetBSD__)
 		/* XXX should have callback? */
@@ -380,6 +382,7 @@ lltable_free(struct lltable *llt)
 #endif
 		llentry_free(lle);
 	}
+	mutex_exit(softnet_lock);
 
 	llt->llt_free_tbl(llt);
 }

Reply via email to