Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_output.c
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
"Incrementor step size of automatic send buffer"); | "Incrementor step size of automatic send buffer"); | ||||
VNET_DEFINE(int, tcp_autosndbuf_max) = 2*1024*1024; | VNET_DEFINE(int, tcp_autosndbuf_max) = 2*1024*1024; | ||||
#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) | #define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) | ||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(tcp_autosndbuf_max), 0, | &VNET_NAME(tcp_autosndbuf_max), 0, | ||||
"Max size of automatic send buffer"); | "Max size of automatic send buffer"); | ||||
VNET_DEFINE(int, tcp_output_enobufs) = 0; | |||||
#define V_tcp_output_enobufs VNET(tcp_output_enobufs) | |||||
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_output_enobufs, CTLFLAG_VNET | CTLFLAG_RW, | |||||
&VNET_NAME(tcp_output_enobufs), 0, | |||||
"number of times ENOBUFS returned"); | |||||
static void inline hhook_run_tcp_est_out(struct tcpcb *tp, | static void inline hhook_run_tcp_est_out(struct tcpcb *tp, | ||||
struct tcphdr *th, struct tcpopt *to, | struct tcphdr *th, struct tcpopt *to, | ||||
long len, int tso); | long len, int tso); | ||||
static void inline cc_after_idle(struct tcpcb *tp); | static void inline cc_after_idle(struct tcpcb *tp); | ||||
/* | /* | ||||
* Wrapper for the TCP established output helper hook. | * Wrapper for the TCP established output helper hook. | ||||
*/ | */ | ||||
Show All 22 Lines | |||||
cc_after_idle(struct tcpcb *tp) | cc_after_idle(struct tcpcb *tp) | ||||
{ | { | ||||
INP_WLOCK_ASSERT(tp->t_inpcb); | INP_WLOCK_ASSERT(tp->t_inpcb); | ||||
if (CC_ALGO(tp)->after_idle != NULL) | if (CC_ALGO(tp)->after_idle != NULL) | ||||
CC_ALGO(tp)->after_idle(tp->ccv); | CC_ALGO(tp)->after_idle(tp->ccv); | ||||
} | } | ||||
static void | |||||
tcp_rexmt_output(struct inpcb *inp) | |||||
{ | |||||
(void) tcp_output(inp->inp_ppcb); | |||||
} | |||||
/* | /* | ||||
* Tcp output routine: figure out what should be sent and send it. | * Tcp output routine: figure out what should be sent and send it. | ||||
*/ | */ | ||||
int | int | ||||
tcp_output(struct tcpcb *tp) | tcp_output(struct tcpcb *tp) | ||||
{ | { | ||||
struct socket *so = tp->t_inpcb->inp_socket; | struct socket *so = tp->t_inpcb->inp_socket; | ||||
long len, recwin, sendwin; | long len, recwin, sendwin; | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
tp->snd_nxt -= len; | tp->snd_nxt -= len; | ||||
} | } | ||||
SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */ | SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */ | ||||
switch (error) { | switch (error) { | ||||
case EPERM: | case EPERM: | ||||
tp->t_softerror = error; | tp->t_softerror = error; | ||||
return (error); | return (error); | ||||
case ENOBUFS: | case ENOBUFS: | ||||
if (!tcp_timer_active(tp, TT_REXMT) && | atomic_add_int(&V_tcp_output_enobufs, 1); | ||||
!tcp_timer_active(tp, TT_PERSIST)) | inp_rexmt_enqueue(tp->t_inpcb, tcp_rexmt_output); | ||||
tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur); | |||||
tp->snd_cwnd = tp->t_maxseg; | |||||
return (0); | return (0); | ||||
case EMSGSIZE: | case EMSGSIZE: | ||||
/* | /* | ||||
* For some reason the interface we used initially | * For some reason the interface we used initially | ||||
* to send segments changed to another or lowered | * to send segments changed to another or lowered | ||||
* its MTU. | * its MTU. | ||||
* If TSO was active we either got an interface | * If TSO was active we either got an interface | ||||
* without TSO capabilits or TSO was turned off. | * without TSO capabilits or TSO was turned off. | ||||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |