From 2f1b9cddbb78f0cc1bbefaec5f9e4ab0fcf3ed48 Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 9 Oct 2013 12:00:38 +0000 Subject: [PATCH] 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) --- sys/netinet/tcp_input.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 0d7eb1933498..9a2ce9eaf771 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) &&