On Wed, Aug 02, 2017 at 11:24:10AM +0200, Martin Pieuchot wrote:
> 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?
OK bluhm@
> 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);
> }
>
> /*