TCP_N_TIMERS
} tcp_timers_e;
-typedef void (timer_expiration_handler) (u32 index, u32 thread_index);
-
-extern timer_expiration_handler tcp_timer_delack_handler;
-extern timer_expiration_handler tcp_timer_retransmit_handler;
-extern timer_expiration_handler tcp_timer_persist_handler;
-extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
-
#define TCP_TIMER_HANDLE_INVALID ((u32) ~0)
#define TCP_TIMER_TICK 0.1 /**< Timer tick in seconds */
#define tcp_csum_offload(tc) (!((tc)->cfg_flags & TCP_CFG_F_NO_CSUM_OFFLOAD))
+typedef void (timer_expiration_handler) (tcp_connection_t * tc);
+
+extern timer_expiration_handler tcp_timer_delack_handler;
+extern timer_expiration_handler tcp_timer_retransmit_handler;
+extern timer_expiration_handler tcp_timer_persist_handler;
+extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
+
always_inline void
tcp_cong_recovery_off (tcp_connection_t * tc)
{
u8 next, error;
} tcp_lookup_dispatch_t;
+#define foreach_tcp_wrk_stat \
+ _(timer_expirations, u64, "timer expirations") \
+ _(rxt_segs, u64, "segments retransmitted") \
+ _(tr_events, u32, "timer retransmit events") \
+ _(to_closewait, u32, "timeout close-wait") \
+ _(to_closewait2, u32, "timeout close-wait w/data") \
+ _(to_finwait1, u32, "timeout fin-wait-1") \
+ _(to_finwait2, u32, "timeout fin-wait-2") \
+ _(to_lastack, u32, "timeout last-ack") \
+ _(to_closing, u32, "timeout closing") \
+ _(tr_abort, u32, "timer retransmit abort") \
+ _(rst_unread, u32, "reset on close due to unread data") \
+
+typedef struct tcp_wrk_stats_
+{
+#define _(name, type, str) type name;
+ foreach_tcp_wrk_stat
+#undef _
+} tcp_wrk_stats_t;
+
+typedef struct tcp_free_req_
+{
+ clib_time_type_t free_time;
+ u32 connection_index;
+} tcp_cleanup_req_t;
+
typedef struct tcp_worker_ctx_
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
/** worker time */
u32 time_now;
+ /* Max timers to be handled per dispatch loop */
+ u32 max_timers_per_loop;
+
/** tx frames for ip 4/6 lookup nodes */
vlib_frame_t *ip_lookup_tx_frames[2];
/** tx buffer free list */
u32 *tx_buffers;
+ /* Fifo of pending timer expirations */
+ u32 *pending_timers;
+
+ /* fifo of pending free requests */
+ tcp_cleanup_req_t *pending_cleanups;
+
/** worker timer wheel */
tw_timer_wheel_16t_2w_512sl_t timer_wheel;
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
+
+ tcp_wrk_stats_t stats;
} tcp_worker_ctx_t;
+#define tcp_worker_stats_inc(_ti,_stat,_val) \
+ tcp_main.wrk_ctx[_ti].stats._stat += _val
+
+#define tcp_workerp_stats_inc(_wrk,_stat,_val) \
+ _wrk->stats._stat += _val
+
typedef struct tcp_iss_seed_
{
u64 first;
/** Timer ticks to wait in closing for fin ack */
u16 closing_time;
- /** Timer ticks to wait before cleaning up the connection */
- u16 cleanup_time;
+ /** Time to wait (sec) before cleaning up the connection */
+ f32 cleanup_time;
/** Number of preallocated connections */
u32 preallocated_connections;
void tcp_send_ack (tcp_connection_t * tc);
void tcp_update_burst_snd_vars (tcp_connection_t * tc);
void tcp_update_rto (tcp_connection_t * tc);
-void tcp_flush_frames_to_output (tcp_worker_ctx_t * wrk);
void tcp_send_window_update_ack (tcp_connection_t * tc);
void tcp_program_ack (tcp_connection_t * tc);
void tcp_connection_tx_pacer_update (tcp_connection_t * tc);
void tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window,
u32 start_bucket);
+void tcp_program_cleanup (tcp_worker_ctx_t * wrk, tcp_connection_t * tc);
always_inline void
tcp_cc_rcv_ack (tcp_connection_t * tc, tcp_rate_sample_t * rs)
always_inline void
tcp_persist_timer_reset (tcp_connection_t * tc)
{
+ if (transport_connection_is_descheduled (&tc->connection))
+ transport_connection_reschedule (&tc->connection);
tcp_timer_reset (tc, TCP_TIMER_PERSIST);
}