Current-Users archive

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

Re: new if_bge/mii panic



On 13/06/2013 5:29, Masanobu SAITOH wrote:
in6_createmkludge() does:

        mk = malloc(sizeof(*mk), M_IPMADDR, M_ZERO|M_WAITOK);

in6_createmkludge() must not be called under interrupt context.

Indeed.
The attached patch should fix this.

Let me know!

Thanks

Roy
Index: sys/dev/mii/mii_physubr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mii/mii_physubr.c,v
retrieving revision 1.78
diff -u -p -r1.78 mii_physubr.c
--- sys/dev/mii/mii_physubr.c   9 Jun 2013 09:56:17 -0000       1.78
+++ sys/dev/mii/mii_physubr.c   13 Jun 2013 11:17:24 -0000
@@ -436,9 +436,7 @@ mii_phy_statusmsg(struct mii_softc *sc)
 {
        struct mii_data *mii = sc->mii_pdata;
        struct ifnet *ifp = mii->mii_ifp;
-       int s;
 
-       s = splnet();
        if (mii->mii_media_status & IFM_AVALID) {
                if (mii->mii_media_status & IFM_ACTIVE)
                        if_link_state_change(ifp, LINK_STATE_UP);
@@ -446,7 +444,6 @@ mii_phy_statusmsg(struct mii_softc *sc)
                        if_link_state_change(ifp, LINK_STATE_DOWN);
        } else
                if_link_state_change(ifp, LINK_STATE_UNKNOWN);
-       splx(s);
 
        ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
 }
Index: sys/net/if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.263
diff -u -p -r1.263 if.c
--- sys/net/if.c        11 Jun 2013 12:08:29 -0000      1.263
+++ sys/net/if.c        13 Jun 2013 11:17:25 -0000
@@ -1337,10 +1337,13 @@ link_rtrequest(int cmd, struct rtentry *
 void
 if_link_state_change(struct ifnet *ifp, int link_state)
 {
-       int old_link_state;
+       int old_link_state, s;
 
-       if (ifp->if_link_state == link_state)
+       s = splnet();
+       if (ifp->if_link_state == link_state) {
+               splx(s);
                return;
+       }
 
        old_link_state = ifp->if_link_state;
        ifp->if_link_state = link_state;
@@ -1366,7 +1369,7 @@ if_link_state_change(struct ifnet *ifp, 
         */
        if (link_state == LINK_STATE_UP &&
            old_link_state == LINK_STATE_UNKNOWN)
-               in6_if_down(ifp);
+               in6_if_link_down(ifp);
 #endif
 
        /* Notify that the link state has changed. */
@@ -1379,10 +1382,12 @@ if_link_state_change(struct ifnet *ifp, 
 
 #ifdef INET6
        if (link_state == LINK_STATE_DOWN)
-               in6_if_down(ifp);
+               in6_if_link_down(ifp);
        else if (link_state == LINK_STATE_UP)
-               in6_if_up(ifp);
+               in6_if_link_up(ifp);
 #endif
+
+       splx(s);
 }
 
 /*
Index: sys/netinet6/in6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6.c,v
retrieving revision 1.164
diff -u -p -r1.164 in6.c
--- sys/netinet6/in6.c  11 Jun 2013 12:08:29 -0000      1.164
+++ sys/netinet6/in6.c  13 Jun 2013 11:17:25 -0000
@@ -2165,7 +2165,7 @@ in6_ifawithifp(struct ifnet *ifp, struct
  * perform DAD when interface becomes IFF_UP.
  */
 void
-in6_if_up(struct ifnet *ifp)
+in6_if_link_up(struct ifnet *ifp)
 {
        struct ifaddr *ifa;
        struct in6_ifaddr *ia;
@@ -2206,20 +2206,27 @@ in6_if_up(struct ifnet *ifp)
                }
        }
 
+       /* Restore any detached prefixes */
+       pfxlist_onlink_check();
+}
+
+void
+in6_if_up(struct ifnet *ifp)
+{
+
        /*
         * special cases, like 6to4, are handled in in6_ifattach
         */
        in6_ifattach(ifp, NULL);
 
-       /* Restore any detached prefixes */
-       pfxlist_onlink_check();
+       /* interface may not support link state, so bring it up also */
+       in6_if_link_up(ifp);
 }
-
 /*
  * Mark all addresses as detached.
  */
 void
-in6_if_down(struct ifnet *ifp)
+in6_if_link_down(struct ifnet *ifp)
 {
        struct ifaddr *ifa;
        struct in6_ifaddr *ia;
@@ -2254,6 +2261,13 @@ in6_if_down(struct ifnet *ifp)
        pfxlist_onlink_check();
 }
 
+void
+in6_if_down(struct ifnet *ifp)
+{
+
+       in6_if_link_down(ifp);
+}
+
 int
 in6if_do_dad(struct ifnet *ifp)
 {
Index: sys/netinet6/in6.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6.h,v
retrieving revision 1.72
diff -u -p -r1.72 in6.h
--- sys/netinet6/in6.h  11 Jun 2013 12:08:29 -0000      1.72
+++ sys/netinet6/in6.h  13 Jun 2013 11:17:26 -0000
@@ -700,6 +700,8 @@ void        in6_delayed_cksum(struct mbuf *);
 int    in6_localaddr(const struct in6_addr *);
 int    in6_addrscope(const struct in6_addr *);
 struct in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *);
+extern void in6_if_link_up(struct ifnet *);
+extern void in6_if_link_down(struct ifnet *);
 extern void in6_if_up(struct ifnet *);
 extern void in6_if_down(struct ifnet *);
 #ifndef __FreeBSD__


Home | Main Index | Thread Index | Old Index