Date: Sun, 25 Apr 2010 03:49:44 +0000 (UTC) From: Juli Mallett <jmallett@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r207182 - user/jmallett/octeon/sys/mips/cavium/octe Message-ID: <201004250349.o3P3niET036349@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); + } } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004250349.o3P3niET036349>