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); }