From 3a3039379c4ae88bfbe7b15ad2c3f92f3e976f57 Mon Sep 17 00:00:00 2001 From: rrs Date: Sun, 15 Feb 2015 13:57:44 +0000 Subject: MFC of r278472 This fixes a bug in the way that the LLE timers for nd6 and arp were being used. They basically would pass in the mutex to the callout_init. Because they used this method to the callout system, it was possible to "stop" the callout. When flushing the table and you stopped the running callout, the callout_stop code would return 1 indicating that it was going to stop the callout (that was about to run on the callout_wheel blocked by the function calling the stop). Now when 1 was returned, it would lower the reference count one extra time for the stopped timer, then a few lines later delete the memory. Of course the callout_wheel was stuck in the lock code and would then crash since it was accessing freed memory. By using callout_init(c, 1) we always get a 0 back and the reference counting bug does not rear its head. We do have to make a few adjustments to the callouts themselves though to make sure it does the proper thing if rescheduled as well as gets the lock. Sponsored by: Netflix Inc. --- sys/netinet6/in6.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sys/netinet6/in6.c') diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 714e33f..6a8a155 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2519,8 +2519,7 @@ in6_lltable_new(const struct sockaddr *l3addr, u_int flags) lle->base.lle_refcnt = 1; lle->base.lle_free = in6_lltable_free; LLE_LOCK_INIT(&lle->base); - callout_init_rw(&lle->base.ln_timer_ch, &lle->base.lle_lock, - CALLOUT_RETURNUNLOCKED); + callout_init(&lle->base.ln_timer_ch, 1); return (&lle->base); } -- cgit v1.1