Date: Sun, 24 Sep 2017 15:12:04 -0700 From: Stephen Hurd <shurd@sasktel.net> To: Hans Petter Selasky <hps@selasky.org> Cc: Stephen Hurd <shurd@FreeBSD.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r323942 - head/sys/net Message-ID: <fd0c5f63-bd99-04b5-590c-74058c759729@sasktel.net> In-Reply-To: <311ab67b-7d37-69aa-8a7b-cbd5350e51c0@sasktel.net> References: <201709230135.v8N1ZE6S063264@repo.freebsd.org> <B28D9879-4ECF-43E4-9A58-51F616CEC4BE@lists.zabbadoz.net> <283397c7-a01e-3776-7ed3-b64d68003d0b@sasktel.net> <6F5DC92C-2CF6-4A33-9663-BFECB7DB65F2@lists.zabbadoz.net> <89d68ff8-84ed-83a6-4e77-9a321babe2fe@sasktel.net> <3601ee57-2bf5-036a-a3d1-a4795847d0ec@selasky.org> <311ab67b-7d37-69aa-8a7b-cbd5350e51c0@sasktel.net>
next in thread | previous in thread | raw e-mail | index | archive | help
Stephen Hurd wrote: > Hans Petter Selasky wrote: >> On 09/24/17 01:46, Stephen Hurd wrote: >>> Basically, it changed from this: >>> >>> foreach (mbuf in rx) { >>> if (lro && tcp_lro_rx(mbuf) == 0) >>> continue; >>> if_input(mbuf) >>> } >>> >>> To this: >>> >>> prev_mbuf = first_mbuf = NULL; >>> foreach (mbuf in rx) { >>> if (lro && tcp_lro_rx(mbuf) == 0) >>> continue; >>> if (prev_mbuf) { >>> prev_mbuf->m_nextpkt = mbuf; >>> prev_mbuf = mbuf; >>> } >>> else { >>> first_mbuf = prev_mbuf = mbuf; >>> } >>> } >>> >>> if (first_mbuf) >>> if_input(first_mbuf); >>> >>> So while before it called if_input() for each separate mbuf that was >>> not LROed, it now builds a chain of mbufs that were not LROed, and >>> makes a single call to if_input() with the whole chain. For cases >>> like packet forwarding where no packets are LROed, performance is >>> better. >>> >> >> Can such a similar logic be applied inside TCP LRO aswell? > > It looks like it would be more complex to do a similar thing in > tcp_lro.c, and I'm not certain it would help much except in cases with > a large number of streams that mostly end up not being coalesced. > Taking a quick look, tcp_lro_flush() would need to be modified to > return an mbuf head and tail, then the caller would need to be > responsible for combining them into a single mbuf chain and calling > if_input(). > > Either that, or an mbuf tail could be passed into tcp_lro_flush(), the > tail modified in there, and an mbuf head returned... that way it would > work something like this: > > The caller would be something like this: > > m_head = m_tail = NULL; > LIST_FOREACH(le, bucket, hash_next) { > head = tcp_lro_flush(lc, le, &m_tail); > if (m_head == NULL) > m_head = head; > } > if (m_head) > if_input(m_head); > > And tcp_lro_flush() would be something like this: > > struct mbuf *tcp_lro_flush(struct lro_ctrl *lc, struct lro_entry *le, > struct mbuf **tail) > { > ... > if (*tail) > *tail->m_next = le->m_head; > *tail = le->m_tail; > ... > return le->m_head; > } > > Hrm, maybe it wouldn't be all that difficult after all. :-) > > I'll be driving across the country later this week, so I don't want to > start poking into LRO then disappear, so if nobody else tries it out > before then, I should take a look in a couple weeks. I've done an initial pass here: https://reviews.freebsd.org/D12487 Feel free to test it out and report findings in the review.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?fd0c5f63-bd99-04b5-590c-74058c759729>