summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-10-09 12:00:38 +0000
committerglebius <glebius@FreeBSD.org>2013-10-09 12:00:38 +0000
commit2f1b9cddbb78f0cc1bbefaec5f9e4ab0fcf3ed48 (patch)
tree6119b672834a51bda84fad07cfd77fb0fa8f863e /sys/netinet/tcp_input.c
parent0216035e665dc869f340e168960a39630e822232 (diff)
downloadFreeBSD-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/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c7
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) &&
OpenPOWER on IntegriCloud