Florian killed the default router and prefix lists from the kernel. So
nd6_timer() is now only doing address expiration based on pltime/vltime.
Diff below renames the function and kill outdated comments to reflect
the reality.
Now, this timer wakes a task every second. And even if there's nothing
to do the task tries to grab the NET_LOCK(). Being scheduled on `systq'
this task creates contention with the `softnettq' and any userland
program trying to grab the lock. So this diff also moves this task to
the `softnettq'.
ok?
Index: netinet6/nd6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.211
diff -u -p -r1.211 nd6.c
--- netinet6/nd6.c 12 Jul 2017 16:53:58 -0000 1.211
+++ netinet6/nd6.c 2 Aug 2017 09:18:13 -0000
@@ -90,15 +90,15 @@ int nd6_inuse, nd6_allocated;
int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
void nd6_slowtimo(void *);
-void nd6_timer_work(void *);
-void nd6_timer(void *);
+void nd6_expire(void *);
+void nd6_expire_timer(void *);
void nd6_invalidate(struct rtentry *);
struct llinfo_nd6 *nd6_free(struct rtentry *, int);
void nd6_llinfo_timer(void *);
struct timeout nd6_slowtimo_ch;
-struct timeout nd6_timer_ch;
-struct task nd6_timer_task;
+struct timeout nd6_expire_timeout;
+struct task nd6_expire_task;
void
nd6_init(void)
@@ -114,17 +114,15 @@ nd6_init(void)
pool_init(&nd6_pool, sizeof(struct llinfo_nd6), 0,
IPL_SOFTNET, 0, "nd6", NULL);
- /* initialization of the default router list */
-
- task_set(&nd6_timer_task, nd6_timer_work, NULL);
+ task_set(&nd6_expire_task, nd6_expire, NULL);
nd6_init_done = 1;
/* start timer */
timeout_set_proc(&nd6_slowtimo_ch, nd6_slowtimo, NULL);
timeout_add_sec(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL);
- timeout_set(&nd6_timer_ch, nd6_timer, NULL);
- timeout_add_sec(&nd6_timer_ch, nd6_prune);
+ timeout_set(&nd6_expire_timeout, nd6_expire_timer, NULL);
+ timeout_add_sec(&nd6_expire_timeout, nd6_prune);
}
@@ -420,24 +418,19 @@ nd6_llinfo_timer(void *arg)
}
/*
- * ND6 timer routine to expire default route list and prefix list
+ * Expire interface addresses.
*/
void
-nd6_timer_work(void *null)
+nd6_expire(void *unused)
{
struct ifnet *ifp;
int s;
+ KERNEL_LOCK();
NET_LOCK(s);
- timeout_add_sec(&nd6_timer_ch, nd6_prune);
+ timeout_add_sec(&nd6_expire_timeout, nd6_prune);
- /*
- * expire interface addresses.
- * in the past the loop was inside prefix expiry processing.
- * However, from a stricter spec-conformance standpoint, we should
- * rather separate address lifetimes and prefix lifetimes.
- */
TAILQ_FOREACH(ifp, &ifnet, if_list) {
struct ifaddr *ifa, *nifa;
struct in6_ifaddr *ia6;
@@ -462,12 +455,13 @@ nd6_timer_work(void *null)
}
NET_UNLOCK(s);
+ KERNEL_UNLOCK();
}
void
-nd6_timer(void *ignored_arg)
+nd6_expire_timer(void *unused)
{
- task_add(systq, &nd6_timer_task);
+ task_add(softnettq, &nd6_expire_task);
}
/*