altq_cbq: In restart, release ALTQ serializer to avoid dead lock
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 8 Apr 2009 11:44:31 +0000 (19:44 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 8 Apr 2009 11:45:49 +0000 (19:45 +0800)
sys/net/altq/altq_cbq.c

index c24611b..e4ea2a2 100644 (file)
@@ -555,7 +555,8 @@ static void
 cbqrestart(struct ifaltq *ifq)
 {
        cbq_state_t     *cbqp;
-       struct ifnet    *ifp;
+
+       ALTQ_ASSERT_LOCKED(ifq);
 
        if (!ifq_is_enabled(ifq))
                /* cbq must have been detached */
@@ -565,10 +566,19 @@ cbqrestart(struct ifaltq *ifq)
                /* should not happen */
                return;
 
-       ifp = ifq->altq_ifp;
-       if (ifp->if_start &&
-           cbqp->cbq_qlen > 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
-               (*ifp->if_start)(ifp);
+       if (cbqp->cbq_qlen > 0) {
+               struct ifnet *ifp = ifq->altq_ifp;
+
+               /* Release the altq lock to avoid deadlock */
+               ALTQ_UNLOCK(ifq);
+
+               lwkt_serialize_enter(ifp->if_serializer);
+               if (ifp->if_start && (ifp->if_flags & IFF_OACTIVE) == 0)
+                       (*ifp->if_start)(ifp);
+               lwkt_serialize_exit(ifp->if_serializer);
+
+               ALTQ_LOCK(ifq);
+       }
 }
 
 static void