Date: Tue, 7 Apr 2009 15:00:51 +0800 From: Sepherosa Ziehau <sepherosa@gmail.com> To: Julian Elischer <julian@elischer.org> Cc: freebsd-net@freebsd.org, Robert Watson <rwatson@freebsd.org>, Ivan Voras <ivoras@freebsd.org> Subject: Re: Advice on a multithreaded netisr patch? Message-ID: <ea7b9c170904070000xd3033fejfc5b249e800dff8b@mail.gmail.com> In-Reply-To: <49DAF447.5020407@elischer.org> References: <gra7mq$ei8$1@ger.gmane.org> <alpine.BSF.2.00.0904051422280.12639@fledge.watson.org> <grac1s$p56$1@ger.gmane.org> <alpine.BSF.2.00.0904051440460.12639@fledge.watson.org> <grappq$tsg$1@ger.gmane.org> <alpine.BSF.2.00.0904052243250.34905@fledge.watson.org> <grbcfg$poe$1@ger.gmane.org> <alpine.BSF.2.00.0904061238250.34905@fledge.watson.org> <ea7b9c170904062209tda44636tb9a18755ec0c5bb3@mail.gmail.com> <49DAF447.5020407@elischer.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Apr 7, 2009 at 2:35 PM, Julian Elischer <julian@elischer.org> wrote: > Sepherosa Ziehau wrote: >> >> On Mon, Apr 6, 2009 at 7:59 PM, Robert Watson <rwatson@freebsd.org> wrote: >>> >>> m_pullup() has to do with mbuf chain memory contiguity during packet >>> processing. The usual usage is something along the following lines: >>> >>> struct whatever *w; >>> >>> m = m_pullup(m, sizeof(*w)); >>> if (m == NULL) >>> return; >>> w = mtod(m, struct whatever *); > > while this is true, m_pullup ALWAYS does things so in fact you > want to always put it in a test to see if it is really needed.. This probably will not be much problem on RX path, drivers always have to set m->m_len, so m->m_len is probably still in cache. > > from memory it is something like: > > if (m->m_len < headerlen && (m = m_pullup(m, headerlen)) == NULL) { > log(LOG_WARNING, > "nglmi: m_pullup failed for %d bytes\n", headerlen); > return (0); > } > header = mtod(m, struct header *); > > >>> >>> m_pullup() here ensures that the first sizeof(*w) bytes of mbuf data are >>> contiguously stored so that the cast of w to m's data will point at a >>> complete structure we can use to interpret packet data. In the common >>> case >>> in the receipt path, m_pullup() should be a no-op, since almost all >>> drivers >>> receive data in a single cluster. >>> >>> However, there are cases where it might not happen, such as loopback >>> traffic >>> where unusual encapsulation is used, leading to a call to M_PREPEND() >>> that >>> inserts a new mbuf on the front of the chain, which is later m_defrag()'d >>> leading to a higher level header crossing a boundary or the like. >>> >>> This issue is almost entirely independent from things like the cache line >>> miss issue, unless you hit the uncommon case of having to do work in >>> m_pullup(), in which case life sucks. >>> >>> It would be useful to use DTrace to profile a number of the workfull >>> m_foo() >>> functions to make sure we're not hitting them in normal workloads, btw. >> >> I highly suspect m_pullup will take any real effect on RX path, given >> how most of drivers allocate the mbuf for RX ring (all RX mbufs should >> be mclusters). >> >> Best Regards, >> sephe >> > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" > -- Live Free or Die
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ea7b9c170904070000xd3033fejfc5b249e800dff8b>