On 04/11/15(Wed) 10:39, David Gwynne wrote:
> 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?
ok mpi@
>
> 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))) \
>