svn commit: r207182 - user/jmallett/octeon/sys/mips/cavium/octe
Juli Mallett
jmallett at FreeBSD.org
Sun Apr 25 03:49:44 UTC 2010
Author: jmallett
Date: Sun Apr 25 03:49:43 2010
New Revision: 207182
URL: http://svn.freebsd.org/changeset/base/207182
Log:
Work around a couple of bugs.
Modified:
user/jmallett/octeon/sys/mips/cavium/octe/octe.c
Modified: user/jmallett/octeon/sys/mips/cavium/octe/octe.c
==============================================================================
--- user/jmallett/octeon/sys/mips/cavium/octe/octe.c Sun Apr 25 01:56:39 2010 (r207181)
+++ user/jmallett/octeon/sys/mips/cavium/octe/octe.c Sun Apr 25 03:49:43 2010 (r207182)
@@ -250,7 +250,7 @@ static void
octe_start(struct ifnet *ifp)
{
cvm_oct_private_t *priv;
- struct mbuf *m;
+ struct mbuf *m, *n;
int error;
priv = ifp->if_softc;
@@ -261,6 +261,31 @@ octe_start(struct ifnet *ifp)
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ /*
+ * XXX
+ *
+ * We may not be able to pass the mbuf up to BPF for one of
+ * two very good reasons:
+ * (1) immediately after our inserting it another CPU may be
+ * kind enough to free it for us.
+ * (2) m_defrag gets called on m and we don't get back the
+ * modified pointer.
+ *
+ * We have some options other than this m_dup route:
+ * (1) use a mutex or spinlock to prevent another CPU from
+ * freeing it. We could lock the tx_free_list's lock,
+ * that would make sense.
+ * (2) get back the new mbuf pointer.
+ * (3) do the defrag here.
+ *
+ * #3 makes sense in the long run when we have code that can
+ * load mbufs into any number of segments, but for now the
+ * transmit code is called with the assumption that it knows
+ * how to defrag mbufs for itself and that it will handle the
+ * failure cases internally.
+ */
+ n = m_dup(m, M_DONTWAIT);
+
if (priv->queue != -1) {
error = cvm_oct_xmit(m, ifp);
} else {
@@ -272,16 +297,17 @@ octe_start(struct ifnet *ifp)
* XXX
* Need to implement freeing and clearing of
* OACTIVE at some point.
- *
- * XXX
- * Incremenet errors? Maybe make xmit functions
- * not free the packets?
*/
+ if (n != NULL)
+ IFQ_DRV_PREPEND(&ifp->if_snd, n);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return;
}
- BPF_MTAP(ifp, m);
+ if (n != NULL) {
+ BPF_MTAP(ifp, n);
+ m_freem(n);
+ }
}
}
More information about the svn-src-user
mailing list