this reorders the code so a functioning art_node is inserted into the table instead of an empty node.
if we move art to use srps, an insert will make the node available for lookups immediately. having a functional node in that situation is useful. this includes previous diffz so it can apply and work. ok? Index: rtable.c =================================================================== RCS file: /cvs/src/sys/net/rtable.c,v retrieving revision 1.42 diff -u -p -r1.42 rtable.c --- rtable.c 18 May 2016 03:46:03 -0000 1.42 +++ rtable.c 1 Jun 2016 05:17:51 -0000 @@ -666,6 +666,7 @@ rtable_insert(unsigned int rtableid, str struct art_node *an, *prev; uint8_t *addr; int plen; + unsigned int rt_flags; KERNEL_ASSERT_LOCKED(); @@ -704,18 +705,23 @@ rtable_insert(unsigned int rtableid, str if (an == NULL) return (ENOBUFS); - SRPL_INIT(&an->an_rtlist); + /* prepare for immediate operation if insert succeeds */ + rt_flags = rt->rt_flags; + rt->rt_flags &= ~RTF_MPATH; + rt->rt_dest = dst; + rt->rt_plen = plen; + SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next); prev = art_insert(ar, an, addr, plen); - if (prev == NULL) { + if (prev != an) { + SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, + rt_next); + rt->rt_flags = rt_flags; art_put(an); - return (ESRCH); - } - if (prev == an) { - rt->rt_flags &= ~RTF_MPATH; - } else { - art_put(an); + if (prev == NULL) + return ESRCH; + #ifndef SMALL_KERNEL an = prev; @@ -740,21 +746,16 @@ rtable_insert(unsigned int rtableid, str } } } + + SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next); + + /* Put newly inserted entry at the right place. */ + rtable_mpath_reprio(rtableid, dst, mask, rt->rt_priority, rt); #else return (EEXIST); #endif /* SMALL_KERNEL */ } - rt->rt_dest = dst; - rt->rt_plen = plen; - rtref(rt); - SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next); - -#ifndef SMALL_KERNEL - /* Put newly inserted entry at the right place. */ - rtable_mpath_reprio(rtableid, dst, mask, rt->rt_priority, rt); -#endif /* SMALL_KERNEL */ - return (0); } @@ -813,7 +814,6 @@ rtable_delete(unsigned int rtableid, str KASSERT(rt->rt_refcnt >= 2); SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next); - rtfree(rt); art_put(an); return (0); @@ -899,6 +899,7 @@ rtable_mpath_reprio(unsigned int rtablei KERNEL_ASSERT_LOCKED(); + rtref(rt); /* keep rt alive in between remove and add */ SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next); rt->rt_priority = prio; @@ -931,6 +932,7 @@ rtable_mpath_reprio(unsigned int rtablei } else { SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next); } + rtfree(rt); return (0); } Index: art.c =================================================================== RCS file: /cvs/src/sys/net/art.c,v retrieving revision 1.14 diff -u -p -r1.14 art.c --- art.c 13 Apr 2016 08:04:14 -0000 1.14 +++ art.c 1 Jun 2016 05:17:51 -0000 @@ -803,6 +803,7 @@ art_get(struct sockaddr *dst, uint8_t pl an->an_dst = dst; an->an_plen = plen; + SRPL_INIT(&an->an_rtlist); return (an); }