Augment struct tcpstat with tcps_states[], which is used for book-keeping

the amount of TCP connections by state.  Provides a cheap way to get
connection count without traversing the whole pcb list.

Sponsored by:	Netflix
This commit is contained in:
Gleb Smirnoff 2016-01-27 00:45:46 +00:00
parent 2027d8784f
commit 57a78e3bae
8 changed files with 24 additions and 4 deletions

View File

@ -45,10 +45,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_pcb.h> #include <netinet/in_pcb.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include <netinet/tcp_var.h>
#define TCPSTATES #define TCPSTATES
#include <netinet/tcp_fsm.h> #include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h> #include <netinet/tcp_seq.h>
#include <netinet/tcp_var.h>
#include <netinet/toecore.h> #include <netinet/toecore.h>
#include "common/common.h" #include "common/common.h"

View File

@ -42,10 +42,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_pcb.h> #include <netinet/in_pcb.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_offload.h> #include <netinet/tcp_offload.h>
#define TCPOUTFLAGS #define TCPOUTFLAGS
#include <netinet/tcp_fsm.h> #include <netinet/tcp_fsm.h>
#include <netinet/tcp_var.h>
#include <netinet/toecore.h> #include <netinet/toecore.h>
int registered_toedevs; int registered_toedevs;

View File

@ -1468,6 +1468,7 @@ tcp_close(struct tcpcb *tp)
#endif #endif
in_pcbdrop(inp); in_pcbdrop(inp);
TCPSTAT_INC(tcps_closed); TCPSTAT_INC(tcps_closed);
TCPSTAT_DEC(tcps_states[tp->t_state]);
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL")); KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
so = inp->inp_socket; so = inp->inp_socket;
soisdisconnected(so); soisdisconnected(so);
@ -2910,6 +2911,8 @@ tcp_state_change(struct tcpcb *tp, int newstate)
int pstate = tp->t_state; int pstate = tp->t_state;
#endif #endif
TCPSTAT_DEC(tcps_states[tp->t_state]);
TCPSTAT_INC(tcps_states[newstate]);
tp->t_state = newstate; tp->t_state = newstate;
TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate); TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate);
} }

View File

@ -351,6 +351,7 @@ syncache_insert(struct syncache *sc, struct syncache_head *sch)
SCH_UNLOCK(sch); SCH_UNLOCK(sch);
TCPSTAT_INC(tcps_states[TCPS_SYN_RECEIVED]);
TCPSTAT_INC(tcps_sc_added); TCPSTAT_INC(tcps_sc_added);
} }
@ -364,6 +365,7 @@ syncache_drop(struct syncache *sc, struct syncache_head *sch)
SCH_LOCK_ASSERT(sch); SCH_LOCK_ASSERT(sch);
TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]);
TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash); TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
sch->sch_length--; sch->sch_length--;
@ -992,7 +994,16 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
goto failed; goto failed;
} }
} else { } else {
/* Pull out the entry to unlock the bucket row. */ /*
* Pull out the entry to unlock the bucket row.
*
* NOTE: We must decrease TCPS_SYN_RECEIVED count here, not
* tcp_state_change(). The tcpcb is not existent at this
* moment. A new one will be allocated via syncache_socket->
* sonewconn->tcp_usr_attach in TCPS_CLOSED state, then
* syncache_socket() will change it to TCPS_SYN_RECEIVED.
*/
TCPSTAT_DEC(tcps_states[TCPS_SYN_RECEIVED]);
TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash); TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
sch->sch_length--; sch->sch_length--;
#ifdef TCP_OFFLOAD #ifdef TCP_OFFLOAD

View File

@ -660,6 +660,7 @@ tcp_tw_2msl_stop(struct tcptw *tw, int reuse)
if (!reuse) if (!reuse)
uma_zfree(V_tcptw_zone, tw); uma_zfree(V_tcptw_zone, tw);
TCPSTAT_DEC(tcps_states[TCPS_TIME_WAIT]);
} }
struct tcptw * struct tcptw *

View File

@ -1883,6 +1883,7 @@ tcp_attach(struct socket *so)
tp->t_state = TCPS_CLOSED; tp->t_state = TCPS_CLOSED;
INP_WUNLOCK(inp); INP_WUNLOCK(inp);
INP_INFO_RUNLOCK(&V_tcbinfo); INP_INFO_RUNLOCK(&V_tcbinfo);
TCPSTAT_INC(tcps_states[TCPS_CLOSED]);
return (0); return (0);
} }

View File

@ -34,6 +34,7 @@
#define _NETINET_TCP_VAR_H_ #define _NETINET_TCP_VAR_H_
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#ifdef _KERNEL #ifdef _KERNEL
#include <net/vnet.h> #include <net/vnet.h>
@ -587,6 +588,9 @@ struct tcpstat {
uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */ uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */
uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */ uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */
/* Running connection count. */
uint64_t tcps_states[TCP_NSTATES];
uint64_t _pad[12]; /* 6 UTO, 6 TBD */ uint64_t _pad[12]; /* 6 UTO, 6 TBD */
}; };

View File

@ -59,10 +59,10 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93";
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcpip.h> #include <netinet/tcpip.h>
#include <netinet/tcp_seq.h> #include <netinet/tcp_seq.h>
#include <netinet/tcp_var.h>
#define TCPSTATES #define TCPSTATES
#include <netinet/tcp_fsm.h> #include <netinet/tcp_fsm.h>
#include <netinet/tcp_timer.h> #include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_debug.h> #include <netinet/tcp_debug.h>
#include <netinet/udp.h> #include <netinet/udp.h>
#include <netinet/udp_var.h> #include <netinet/udp_var.h>