network/gif - Correctly clear route cache on destroy.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Mon, 7 Apr 2014 07:37:56 +0000 (09:37 +0200)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Mon, 7 Apr 2014 08:09:59 +0000 (10:09 +0200)
RTFREE() requires that the route is freed in the CPU it belongs to.
Migrating to the target CPU *before* calling it and returning to the
original CPU afterwards seems to do the trick.

Ok: @sephe

sys/net/gif/if_gif.c

index af3b3c6..f9d0a10 100644 (file)
@@ -200,9 +200,22 @@ gif_clone_destroy(struct ifnet *ifp)
 static void
 gif_clear_cache(struct gif_softc *sc)
 {
+       struct rtentry *rt;
+       int origcpu;
        int n;
 
        for (n = 0; n < ncpus; ++n) {
+               rt = sc->gif_ro[n].ro_rt;
+               /*
+                * Routes need to be cleaned up in their CPU so migrate
+                * to it and return to the original CPU after completion.
+                */
+               origcpu = mycpuid;
+               if (rt && rt->rt_cpuid != mycpuid)
+                       lwkt_migratecpu(rt->rt_cpuid);
+               else
+                       origcpu = -1;
+
                if (sc->gif_ro[n].ro_rt) {
                        RTFREE(sc->gif_ro[n].ro_rt);
                        sc->gif_ro[n].ro_rt = NULL;
@@ -213,6 +226,8 @@ gif_clear_cache(struct gif_softc *sc)
                        sc->gif_ro6[n].ro_rt = NULL;
                }
 #endif
+               if (origcpu >= 0)
+                       lwkt_migratecpu(origcpu);
        }
 }