diff options
author | glebius <glebius@FreeBSD.org> | 2013-10-09 12:00:38 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-10-09 12:00:38 +0000 |
commit | 2f1b9cddbb78f0cc1bbefaec5f9e4ab0fcf3ed48 (patch) | |
tree | 6119b672834a51bda84fad07cfd77fb0fa8f863e /sys/netinet | |
parent | 0216035e665dc869f340e168960a39630e822232 (diff) | |
download | FreeBSD-src-2f1b9cddbb78f0cc1bbefaec5f9e4ab0fcf3ed48.zip FreeBSD-src-2f1b9cddbb78f0cc1bbefaec5f9e4ab0fcf3ed48.tar.gz |
When processing ACK in tcp_do_segment, use sbcut_locked() instead of
sbdrop_locked() to cut acked mbufs from the socket buffer. Free this
chain a batch manner after the socket buffer lock is dropped.
This measurably reduces contention on socket buffer.
Sponsored by: Netflix
Sponsored by: Nginx, Inc.
Approved by: re (marius)
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp_input.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 0d7eb19..9a2ce9e 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1461,6 +1461,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, u_long tiwin; char *s; struct in_conninfo *inc; + struct mbuf *mfree; struct tcpopt to; #ifdef TCPDEBUG @@ -2718,15 +2719,17 @@ process_ACK: SOCKBUF_LOCK(&so->so_snd); if (acked > so->so_snd.sb_cc) { tp->snd_wnd -= so->so_snd.sb_cc; - sbdrop_locked(&so->so_snd, (int)so->so_snd.sb_cc); + mfree = sbcut_locked(&so->so_snd, + (int)so->so_snd.sb_cc); ourfinisacked = 1; } else { - sbdrop_locked(&so->so_snd, acked); + mfree = sbcut_locked(&so->so_snd, acked); tp->snd_wnd -= acked; ourfinisacked = 0; } /* NB: sowwakeup_locked() does an implicit unlock. */ sowwakeup_locked(so); + m_freem(mfree); /* Detect una wraparound. */ if (!IN_RECOVERY(tp->t_flags) && SEQ_GT(tp->snd_una, tp->snd_recover) && |