im working on making the interface send queue mpsafe.

part of that involced deprecating the IFQ_POLL api because it allows the caller 
to get a reference an mbuf that is still on the send queue. this is dangerous 
if another cpu tries to manipulate the send queue. instead code should call 
IFQ_DEQUEUE, which takes it off the queue for the driver to use.

however, blindly changing code from IFQ_POLL to IFQ_DEQUEUE will
cause unwanted packet loss when encapsulation fails in some cases,
such as when the tx ring is already full. to cope, the easiest
solution is to requeue the packet so the next call to the start
routine can try fitting it on the ring again.

this introduces IFQ_PREPEND (cause we currently have IF_PREPEND)
and works on top of both hfsc and priq because i added hfsc_requeue
a while back.

this also converts uses of IF_PREPEND in drivers to IFQ_PREPEND.
this improves the situation a bit if people have decided to use
hfsc on these interfaces.

tests? ok?

Index: arch/vax/if/sgec.c
===================================================================
RCS file: /cvs/src/sys/arch/vax/if/sgec.c,v
retrieving revision 1.30
diff -u -p -r1.30 sgec.c
--- arch/vax/if/sgec.c  27 Oct 2015 15:20:13 -0000      1.30
+++ arch/vax/if/sgec.c  4 Nov 2015 00:26:11 -0000
@@ -399,7 +399,7 @@ zestart(ifp)
                        panic("zestart"); /* XXX */
 
                if ((i + sc->sc_inq) >= (TXDESCS - 1)) {
-                       IF_PREPEND(&sc->sc_if.if_snd, m);
+                       IFQ_PREPEND(&sc->sc_if.if_snd, m);
                        ifp->if_flags |= IFF_OACTIVE;
                        goto out;
                }
Index: dev/pci/if_age.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_age.c,v
retrieving revision 1.29
diff -u -p -r1.29 if_age.c
--- dev/pci/if_age.c    25 Oct 2015 13:04:28 -0000      1.29
+++ dev/pci/if_age.c    4 Nov 2015 00:26:12 -0000
@@ -982,7 +982,7 @@ age_start(struct ifnet *ifp)
                        if (m_head == NULL)
                                ifp->if_oerrors++;
                        else {
-                               IF_PREPEND(&ifp->if_snd, m_head);
+                               IFQ_PREPEND(&ifp->if_snd, m_head);
                                ifp->if_flags |= IFF_OACTIVE;
                        }
                        break;
Index: dev/pci/if_alc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_alc.c,v
retrieving revision 1.35
diff -u -p -r1.35 if_alc.c
--- dev/pci/if_alc.c    25 Oct 2015 13:04:28 -0000      1.35
+++ dev/pci/if_alc.c    4 Nov 2015 00:26:12 -0000
@@ -1390,7 +1390,7 @@ alc_start(struct ifnet *ifp)
                        if (m_head == NULL)
                                ifp->if_oerrors++;
                        else {
-                               IF_PREPEND(&ifp->if_snd, m_head);
+                               IFQ_PREPEND(&ifp->if_snd, m_head);
                                ifp->if_flags |= IFF_OACTIVE;
                        }
                        break;
Index: dev/pci/if_ale.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ale.c,v
retrieving revision 1.40
diff -u -p -r1.40 if_ale.c
--- dev/pci/if_ale.c    25 Oct 2015 13:04:28 -0000      1.40
+++ dev/pci/if_ale.c    4 Nov 2015 00:26:12 -0000
@@ -1018,7 +1018,7 @@ ale_start(struct ifnet *ifp)
                        if (m_head == NULL)
                                ifp->if_oerrors++;
                        else {
-                               IF_PREPEND(&ifp->if_snd, m_head);
+                               IFQ_PREPEND(&ifp->if_snd, m_head);
                                ifp->if_flags |= IFF_OACTIVE;
                        }
                        break;
Index: dev/pci/if_jme.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_jme.c,v
retrieving revision 1.42
diff -u -p -r1.42 if_jme.c
--- dev/pci/if_jme.c    25 Oct 2015 13:04:28 -0000      1.42
+++ dev/pci/if_jme.c    4 Nov 2015 00:26:12 -0000
@@ -1251,7 +1251,7 @@ jme_start(struct ifnet *ifp)
                        if (m_head == NULL)
                                ifp->if_oerrors++;
                        else {
-                               IF_PREPEND(&ifp->if_snd, m_head);
+                               IFQ_PREPEND(&ifp->if_snd, m_head);
                                ifp->if_flags |= IFF_OACTIVE;
                        }
                        break;
Index: dev/pci/if_vr.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.144
diff -u -p -r1.144 if_vr.c
--- dev/pci/if_vr.c     25 Oct 2015 13:04:28 -0000      1.144
+++ dev/pci/if_vr.c     4 Nov 2015 00:26:12 -0000
@@ -1343,7 +1343,7 @@ vr_start(struct ifnet *ifp)
                head_tx = cur_tx;
                if (vr_encap(sc, &cur_tx, m_head)) {
                        /* Rollback, send what we were able to encap. */
-                       IF_PREPEND(&ifp->if_snd, m_head);
+                       IFQ_PREPEND(&ifp->if_snd, m_head);
                        break;
                }
                queued++;
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.51
diff -u -p -r1.51 if_var.h
--- net/if_var.h        25 Oct 2015 11:58:11 -0000      1.51
+++ net/if_var.h        4 Nov 2015 00:26:13 -0000
@@ -358,6 +358,15 @@ do {                                                       
                \
                IF_POLL((ifq), (m));                                    \
 } while (/* CONSTCOND */0)
 
+#define        IFQ_PREPEND(ifq, m)                                             
\
+do {                                                                   \
+       if (HFSC_ENABLED(ifq))                                          \
+               hfsc_requeue(((struct ifqueue *)(ifq)), m);             \
+       else {                                                          \
+               IF_PREPEND((ifq), (m));                                 \
+       }                                                               \
+} while (/* CONSTCOND */0)
+
 #define        IFQ_PURGE(ifq)                                                  
\
 do {                                                                   \
        if (HFSC_ENABLED((ifq)))                                        \

Reply via email to