On Thu, Oct 22, 2015 at 07:42:24PM +0200, Martin Pieuchot wrote: > Now that we have a single refcounting mechanism for route entries, I'd > like to use atomic operations and grab the KERNEL_LOCK only if a CPU is > dropping the last reference on an entry. > > Currently this only matters for MPLS. I intentionally use atomic_* ops > because I'd like to see be able to see if a counter goes negative. > > For symmetry reasons I'm also moving the KERNEL_LOCK() inside rtalloc(). > These two functions are my current targets. > > Comments, oks?
One comment inline... > > Index: sys/net/route.c > =================================================================== > RCS file: /cvs/src/sys/net/route.c,v > retrieving revision 1.258 > diff -u -p -r1.258 route.c > --- sys/net/route.c 22 Oct 2015 17:19:38 -0000 1.258 > +++ sys/net/route.c 22 Oct 2015 17:21:52 -0000 > @@ -215,6 +215,7 @@ rtalloc(struct sockaddr *dst, int flags, > info.rti_info[RTAX_DST] = dst; > > s = splsoftnet(); > + KERNEL_LOCK(); > rt = rtable_match(tableid, dst); > if (rt != NULL) { > if ((rt->rt_flags & RTF_CLONING) && ISSET(flags, RT_RESOLVE)) { > @@ -236,6 +237,7 @@ miss: > if (ISSET(flags, RT_REPORT)) > rt_missmsg(RTM_MISS, &info, 0, NULL, error, tableid); > } > + KERNEL_UNLOCK(); > splx(s); > return (rt); > } > @@ -337,7 +339,7 @@ rtalloc_mpath(struct sockaddr *dst, uint > void > rtref(struct rtentry *rt) > { > - rt->rt_refcnt++; > + atomic_inc_int(&rt->rt_refcnt); > } > > void > @@ -348,14 +350,16 @@ rtfree(struct rtentry *rt) > if (rt == NULL) > return; > > - if (--rt->rt_refcnt <= 0) { > + if (atomic_dec_int_nv(&rt->rt_refcnt) <= 0) { > KASSERT(!ISSET(rt->rt_flags, RTF_UP)); > KASSERT(!RT_ROOT(rt)); > - rttrash--; > + atomic_dec_int(&rttrash); Are you using rttrash for debugging? It's unused anywhere else, and if it's just incrementing and decrementing a counter only used for debugging (or possibly not at all!), it might be better to put it in DEBUG kernels, or just remove it entirely. > if (rt->rt_refcnt < 0) { > printf("rtfree: %p not freed (neg refs)\n", rt); > return; > } > + > + KERNEL_LOCK(); > rt_timer_remove_all(rt); > ifa = rt->rt_ifa; > if (ifa) > @@ -368,6 +372,8 @@ rtfree(struct rtentry *rt) > if (rt->rt_gateway) > free(rt->rt_gateway, M_RTABLE, 0); > free(rt_key(rt), M_RTABLE, 0); > + KERNEL_UNLOCK(); > + > pool_put(&rtentry_pool, rt); > } > } > @@ -773,7 +779,7 @@ rtrequest1(int req, struct rt_addrinfo * > rt->rt_flags &= ~RTF_UP; > if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) > ifa->ifa_rtrequest(RTM_DELETE, rt); > - rttrash++; > + atomic_inc_int(&rttrash); > > if (ret_nrt != NULL) > *ret_nrt = rt; > Index: sys/netmpls/mpls_input.c > =================================================================== > RCS file: /cvs/src/sys/netmpls/mpls_input.c,v > retrieving revision 1.50 > diff -u -p -r1.50 mpls_input.c > --- sys/netmpls/mpls_input.c 23 Sep 2015 08:49:46 -0000 1.50 > +++ sys/netmpls/mpls_input.c 22 Oct 2015 17:21:52 -0000 > @@ -170,9 +170,7 @@ do_v6: > } > } > > - KERNEL_LOCK(); > rt = rtalloc(smplstosa(smpls), RT_REPORT|RT_RESOLVE, 0); > - KERNEL_UNLOCK(); > if (rt == NULL) { > /* no entry for this label */ > #ifdef MPLS_DEBUG > @@ -290,9 +288,7 @@ do_v6: > if (ifp != NULL && rt_mpls->mpls_operation != MPLS_OP_LOCAL) > break; > > - KERNEL_LOCK(); > rtfree(rt); > - KERNEL_UNLOCK(); > rt = NULL; > } > > @@ -323,11 +319,7 @@ do_v6: > (*ifp->if_ll_output)(ifp, m, smplstosa(smpls), rt); > KERNEL_UNLOCK(); > done: > - if (rt) { > - KERNEL_LOCK(); > - rtfree(rt); > - KERNEL_UNLOCK(); > - } > + rtfree(rt); > } > > int > @@ -394,7 +386,7 @@ mpls_do_error(struct mbuf *m, int type, > struct in_ifaddr *ia; > struct icmp *icp; > struct ip *ip; > - int nstk; > + int nstk, error; > > for (nstk = 0; nstk < MPLS_INKERNEL_LOOP_MAX; nstk++) { > if (m->m_len < sizeof(*shim) && > @@ -427,9 +419,7 @@ mpls_do_error(struct mbuf *m, int type, > smpls->smpls_len = sizeof(*smpls); > smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK; > > - KERNEL_LOCK(); > rt = rtalloc(smplstosa(smpls), RT_REPORT|RT_RESOLVE, 0); > - KERNEL_UNLOCK(); > if (rt == NULL) { > /* no entry for this label */ > m_freem(m); > @@ -442,19 +432,16 @@ mpls_do_error(struct mbuf *m, int type, > * less interface we need to find some other IP to > * use as source. > */ > - KERNEL_LOCK(); > rtfree(rt); > - KERNEL_UNLOCK(); > m_freem(m); > return (NULL); > } > - KERNEL_LOCK(); > rtfree(rt); > - if (icmp_reflect(m, NULL, ia)) { > - KERNEL_UNLOCK(); > - return (NULL); > - } > + KERNEL_LOCK(); > + error = icmp_reflect(m, NULL, ia); > KERNEL_UNLOCK(); > + if (error) > + return (NULL); > > ip = mtod(m, struct ip *); > /* stuff to fix up which is normaly done in ip_output */ >