Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_timer.c
Show First 20 Lines • Show All 536 Lines • ▼ Show 20 Lines | tcp_timer_rexmt(struct tcpcb *tp) | ||||
int rexmt; | int rexmt; | ||||
bool isipv6, rv; | bool isipv6, rv; | ||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); | TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); | ||||
CURVNET_SET(inp->inp_vnet); | CURVNET_SET(inp->inp_vnet); | ||||
tcp_free_sackholes(tp); | tcp_free_sackholes(tp); | ||||
TCP_LOG_EVENT(tp, NULL, NULL, NULL, TCP_LOG_RTO, 0, 0, NULL, false); | |||||
if (tp->t_fb->tfb_tcp_rexmit_tmr) { | if (tp->t_fb->tfb_tcp_rexmit_tmr) { | ||||
/* The stack has a timer action too. */ | /* The stack has a timer action too. */ | ||||
(*tp->t_fb->tfb_tcp_rexmit_tmr)(tp); | (*tp->t_fb->tfb_tcp_rexmit_tmr)(tp); | ||||
} | } | ||||
/* | /* | ||||
* Retransmission timer went off. Message has not | * Retransmission timer went off. Message has not | ||||
* been acked within retransmit interval. Back off | * been acked within retransmit interval. Back off | ||||
* to a longer retransmit interval and retransmit one segment. | * to a longer retransmit interval and retransmit one segment. | ||||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | #endif | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
rv = tcp_output_locked(tp); | rv = tcp_output_locked(tp); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
return (rv); | return (rv); | ||||
} | } | ||||
static void | |||||
tcp_bblog_timer(struct tcpcb *tp, tt_which which, tt_what what, uint32_t ticks) | |||||
{ | |||||
struct tcp_log_buffer *lgb; | |||||
uint64_t ms; | |||||
INP_WLOCK_ASSERT(tptoinpcb(tp)); | |||||
if (tp->t_logstate != TCP_LOG_STATE_OFF) | |||||
lgb = tcp_log_event_(tp, NULL, NULL, NULL, TCP_LOG_RTO, 0, 0, | |||||
NULL, false, NULL, NULL, 0, NULL); | |||||
else | |||||
lgb = NULL; | |||||
if (lgb != NULL) { | |||||
lgb->tlb_flex1 = (what << 8) | which; | |||||
if (what == TT_STARTING) { | |||||
/* Convert ticks to ms and store it in tlb_flex2. */ | |||||
if (hz == 1000) | |||||
lgb->tlb_flex2 = ticks; | |||||
else { | |||||
ms = (((uint64_t)ticks * 1000) + (hz - 1)) / hz; | |||||
if (ms > UINT32_MAX) | |||||
lgb->tlb_flex2 = UINT32_MAX; | |||||
else | |||||
lgb->tlb_flex2 = (uint32_t)ms; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static inline tt_which | static inline tt_which | ||||
tcp_timer_next(struct tcpcb *tp, sbintime_t *precision) | tcp_timer_next(struct tcpcb *tp, sbintime_t *precision) | ||||
{ | { | ||||
tt_which i, rv; | tt_which i, rv; | ||||
sbintime_t after, before; | sbintime_t after, before; | ||||
for (i = 0, rv = TT_N, after = before = SBT_MAX; i < TT_N; i++) { | for (i = 0, rv = TT_N, after = before = SBT_MAX; i < TT_N; i++) { | ||||
if (tp->t_timers[i] < after) { | if (tp->t_timers[i] < after) { | ||||
Show All 10 Lines | |||||
static void | static void | ||||
tcp_timer_enter(void *xtp) | tcp_timer_enter(void *xtp) | ||||
{ | { | ||||
struct tcpcb *tp = xtp; | struct tcpcb *tp = xtp; | ||||
struct inpcb *inp = tptoinpcb(tp); | struct inpcb *inp = tptoinpcb(tp); | ||||
sbintime_t precision; | sbintime_t precision; | ||||
tt_which which; | tt_which which; | ||||
bool tp_valid; | |||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
MPASS((curthread->td_pflags & TDP_INTCPCALLOUT) == 0); | MPASS((curthread->td_pflags & TDP_INTCPCALLOUT) == 0); | ||||
curthread->td_pflags |= TDP_INTCPCALLOUT; | curthread->td_pflags |= TDP_INTCPCALLOUT; | ||||
which = tcp_timer_next(tp, NULL); | which = tcp_timer_next(tp, NULL); | ||||
MPASS(which < TT_N); | MPASS(which < TT_N); | ||||
tp->t_timers[which] = SBT_MAX; | tp->t_timers[which] = SBT_MAX; | ||||
tp->t_precisions[which] = 0; | tp->t_precisions[which] = 0; | ||||
if (tcp_timersw[which](tp)) { | tcp_bblog_timer(tp, which, TT_PROCESSING, 0); | ||||
tp_valid = tcp_timersw[which](tp); | |||||
if (tp_valid) { | |||||
tcp_bblog_timer(tp, which, TT_PROCESSED, 0); | |||||
if ((which = tcp_timer_next(tp, &precision)) != TT_N) { | if ((which = tcp_timer_next(tp, &precision)) != TT_N) { | ||||
callout_reset_sbt_on(&tp->t_callout, | callout_reset_sbt_on(&tp->t_callout, | ||||
tp->t_timers[which], precision, tcp_timer_enter, | tp->t_timers[which], precision, tcp_timer_enter, | ||||
tp, inp_to_cpuid(inp), C_ABSOLUTE); | tp, inp_to_cpuid(inp), C_ABSOLUTE); | ||||
} | } | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
} | } | ||||
curthread->td_pflags &= ~TDP_INTCPCALLOUT; | curthread->td_pflags &= ~TDP_INTCPCALLOUT; | ||||
} | } | ||||
/* | /* | ||||
* Activate or stop (delta == 0) a TCP timer. | * Activate or stop (delta == 0) a TCP timer. | ||||
*/ | */ | ||||
void | void | ||||
tcp_timer_activate(struct tcpcb *tp, tt_which which, u_int delta) | tcp_timer_activate(struct tcpcb *tp, tt_which which, u_int delta) | ||||
{ | { | ||||
struct inpcb *inp = tptoinpcb(tp); | struct inpcb *inp = tptoinpcb(tp); | ||||
sbintime_t precision; | sbintime_t precision; | ||||
tt_what what; | |||||
#ifdef TCP_OFFLOAD | #ifdef TCP_OFFLOAD | ||||
if (tp->t_flags & TF_TOE) | if (tp->t_flags & TF_TOE) | ||||
return; | return; | ||||
#endif | #endif | ||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
if (delta > 0) | if (delta > 0) { | ||||
what = TT_STARTING; | |||||
callout_when(tick_sbt * delta, 0, C_HARDCLOCK, | callout_when(tick_sbt * delta, 0, C_HARDCLOCK, | ||||
&tp->t_timers[which], &tp->t_precisions[which]); | &tp->t_timers[which], &tp->t_precisions[which]); | ||||
else | } else { | ||||
what = TT_STOPPING; | |||||
tp->t_timers[which] = SBT_MAX; | tp->t_timers[which] = SBT_MAX; | ||||
} | |||||
tcp_bblog_timer(tp, which, what, delta); | |||||
if ((which = tcp_timer_next(tp, &precision)) != TT_N) | if ((which = tcp_timer_next(tp, &precision)) != TT_N) | ||||
callout_reset_sbt_on(&tp->t_callout, tp->t_timers[which], | callout_reset_sbt_on(&tp->t_callout, tp->t_timers[which], | ||||
precision, tcp_timer_enter, tp, inp_to_cpuid(inp), | precision, tcp_timer_enter, tp, inp_to_cpuid(inp), | ||||
C_ABSOLUTE); | C_ABSOLUTE); | ||||
else | else | ||||
callout_stop(&tp->t_callout); | callout_stop(&tp->t_callout); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |