tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: crash in rn_walktree on reboot/shutdown



On Wed, Oct 28, 2009 at 08:07:08AM +0100, Christoph Egger wrote:
> 
> 
> Hi!
> 
> On NetBSD/i386 -current, I get a crash on every reboot/shutdown.

I occasionally see the same crash as you report, but I have not been
able to replicate it reliably.

IIRC, rn_walktree() walks the binary trie in depth-first order, 0, 1, 2,
...:

       6
       /\
      /  \
     /    \
    /      \
   2        5
  /\        /\
 /  \      /  \
0    1    3    4

and invokes the callback on each *leaf* node.

rn_walktree() precomputes the next leaf before invoking the callback on
the current leaf, because the callback may delete the leaf.

In the if_detach() case, the callback is if_rt_walktree(), which will
delete an leaf/rtentry if it references the ifnet that if_detach() is
destroying.

I suspect that an occasional side-effect of if_rt_walktree() deleting
a leaf is to delete the next leaf that rn_walktree() precomputed.  For
example, rtflushclone() may delete one or more leaves when it calls
rt_walktree() to delete cloned routes.  If the next leaf was deleted,
its pointers rn_l/rn_r/rn_p may not respect the radix_node contract when
rn_walktree() visits; a crash is possible.

What can you do to fix this?  I suggest rewriting if_rt_walktree(), and
the following code in if_detach(), to record as many rtentry's to delete
as will fit in some array, delete them, and repeat until there are no
more rtentry's to delete.

        /* Walk the routing table looking for stragglers. */
        for (i = 0; i <= AF_MAX; i++)
                (void)rt_walktree(i, if_rt_walktree, ifp);

Perhaps rtflushclone() can/should be rewritten in similar fashion?

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933


Home | Main Index | Thread Index | Old Index