From e0af7546a542c16efca99fcb796de92b389ef11f Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Mon, 17 Feb 2014 21:36:06 +0000 Subject: The device driver ioctl code can sleep, so calling it from a timeout is *not* a good idea. Instead hand the work off expiring interface addresses off to a taskq. Fixes the "p->p_wchan == NULL" panics seen with usb ethernet adapters. tested by matthieu@ ok mpi@, stsp@ --- sys/netinet6/nd6.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 5795ab88fff..1407769560d 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.110 2014/01/22 13:19:12 mpi Exp $ */ +/* $OpenBSD: nd6.c,v 1.111 2014/02/17 21:36:05 kettenis Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,8 @@ void nd6_llinfo_timer(void *); struct timeout nd6_slowtimo_ch; struct timeout nd6_timer_ch; +struct task nd6_timer_task; +void nd6_timer_work(void *, void *); int fill_drlist(void *, size_t *, size_t); int fill_prlist(void *, size_t *, size_t); @@ -128,6 +131,8 @@ nd6_init(void) /* initialization of the default router list */ TAILQ_INIT(&nd_defrouter); + task_set(&nd6_timer_task, nd6_timer_work, NULL, NULL); + nd6_init_done = 1; /* start timer */ @@ -490,7 +495,7 @@ nd6_llinfo_timer(void *arg) * ND6 timer routine to expire default route list and prefix list */ void -nd6_timer(void *ignored_arg) +nd6_timer_work(void *ignored_arg1, void *ignored_arg2) { int s; struct nd_defrouter *dr, *ndr; @@ -547,6 +552,12 @@ nd6_timer(void *ignored_arg) splx(s); } +void +nd6_timer(void *ignored_arg) +{ + task_add(systq, &nd6_timer_task); +} + /* * Nuke neighbor cache/prefix/default router management table, right before * ifp goes away. -- cgit v1.2.3