diff options
author | msmith <msmith@FreeBSD.org> | 1999-12-28 23:18:33 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1999-12-28 23:18:33 +0000 |
commit | fe241c25718fbd3870d62981ab0828287a76a1bb (patch) | |
tree | e76c0ae529a42abb1344a4ca93eee77c4a6ee3e0 | |
parent | f9f846550e250ee609ee8c0582f13ae2520680af (diff) | |
download | FreeBSD-src-fe241c25718fbd3870d62981ab0828287a76a1bb.zip FreeBSD-src-fe241c25718fbd3870d62981ab0828287a76a1bb.tar.gz |
Make tcp_drain() actually do something. When invoked (usually as a
desperation measure in low-memory situations), walk the tcpbs and
flush the reassembly queues.
This behaviour is currently controlled by the debug.do_tcpdrain sysctl
(defaults to on).
Submitted by: Bosko Milekic <bmilekic@dsuper.net>
Reviewed by: wollman
-rw-r--r-- | sys/netinet/tcp_subr.c | 29 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 29 |
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index fd3e435..c2cf691 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -100,6 +100,10 @@ static int tcp_tcbhashsize = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD, &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); +static int do_tcpdrain = 1; +SYSCTL_INT(_debug, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0, + "Enable non Net3 compliant tcp_drain"); + SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, &tcbinfo.ipi_count, 0, "Number of active PCBs"); @@ -503,7 +507,32 @@ tcp_close(tp) void tcp_drain() { + if (do_tcpdrain) + { + struct inpcb *inpb; + struct tcpcb *tcpb; + struct mbuf *m, *mq; + + /* + * Walk the tcpbs, if existing, and flush the reassembly queue, + * if there is one... + * XXX: The "Net/3" implementation doesn't imply that the TCP + * reassembly queue should be flushed, but in a situation + * where we're really low on mbufs, this is potentially + * usefull. + */ + for (inpb = tcbinfo.listhead->lh_first; inpb; + inpb = inpb->inp_list.le_next) { + if ((tcpb = intotcpcb(inpb))) { + for (mq = tcpb->t_segq; mq; mq = m) { + m = mq->m_nextpkt; + tcpb->t_segq = m; + m_freem(mq); + } + } + } + } } /* diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index fd3e435..c2cf691 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -100,6 +100,10 @@ static int tcp_tcbhashsize = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD, &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); +static int do_tcpdrain = 1; +SYSCTL_INT(_debug, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0, + "Enable non Net3 compliant tcp_drain"); + SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, &tcbinfo.ipi_count, 0, "Number of active PCBs"); @@ -503,7 +507,32 @@ tcp_close(tp) void tcp_drain() { + if (do_tcpdrain) + { + struct inpcb *inpb; + struct tcpcb *tcpb; + struct mbuf *m, *mq; + + /* + * Walk the tcpbs, if existing, and flush the reassembly queue, + * if there is one... + * XXX: The "Net/3" implementation doesn't imply that the TCP + * reassembly queue should be flushed, but in a situation + * where we're really low on mbufs, this is potentially + * usefull. + */ + for (inpb = tcbinfo.listhead->lh_first; inpb; + inpb = inpb->inp_list.le_next) { + if ((tcpb = intotcpcb(inpb))) { + for (mq = tcpb->t_segq; mq; mq = m) { + m = mq->m_nextpkt; + tcpb->t_segq = m; + m_freem(mq); + } + } + } + } } /* |