aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/tcp/tcp.c9
-rw-r--r--src/vnet/tcp/tcp.h1
-rw-r--r--src/vnet/tcp/tcp_input.c28
-rw-r--r--src/vnet/tcp/tcp_output.c11
-rw-r--r--src/vnet/tcp/tcp_timer.h1
-rw-r--r--src/vnet/tcp/tcp_types.h2
6 files changed, 10 insertions, 42 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 3703a4aa358..c30a69304bc 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -1064,7 +1064,6 @@ tcp_timer_waitclose_handler (tcp_connection_t * tc)
static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] =
{
tcp_timer_retransmit_handler,
- tcp_timer_delack_handler,
tcp_timer_persist_handler,
tcp_timer_waitclose_handler,
tcp_timer_retransmit_syn_handler,
@@ -1096,6 +1095,13 @@ tcp_dispatch_pending_timers (tcp_worker_ctx_t * wrk)
if (PREDICT_FALSE (!tc))
continue;
+ /* Skip if the timer is not pending. Probably it was reset while
+ * wating for dispatch */
+ if (PREDICT_FALSE (!(tc->pending_timers & (1 << timer_id))))
+ continue;
+
+ tc->pending_timers &= ~(1 << timer_id);
+
/* Skip timer if it was rearmed while pending dispatch */
if (PREDICT_FALSE (tc->timers[timer_id] != TCP_TIMER_HANDLE_INVALID))
continue;
@@ -1241,6 +1247,7 @@ tcp_expired_timers_dispatch (u32 * expired_timers)
TCP_EVT (TCP_EVT_TIMER_POP, connection_index, timer_id);
tc->timers[timer_id] = TCP_TIMER_HANDLE_INVALID;
+ tc->pending_timers |= (1 << timer_id);
}
clib_fifo_add (wrk->pending_timers, expired_timers, n_expired);
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index 5c66412dfea..91783a6e025 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -28,7 +28,6 @@
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;
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index cc373f5b665..bdaa28ec3d0 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1263,26 +1263,6 @@ tcp_session_enqueue_ooo (tcp_connection_t * tc, vlib_buffer_t * b,
return TCP_ERROR_ENQUEUED_OOO;
}
-/**
- * Check if ACK could be delayed. If ack can be delayed, it should return
- * true for a full frame. If we're always acking return 0.
- */
-always_inline int
-tcp_can_delack (tcp_connection_t * tc)
-{
- /* Send ack if ... */
- if (TCP_ALWAYS_ACK
- /* just sent a rcv wnd 0
- || (tc->flags & TCP_CONN_SENT_RCV_WND0) != 0 */
- /* constrained to send ack */
- || (tc->flags & TCP_CONN_SNDACK) != 0
- /* we're almost out of tx wnd */
- || tcp_available_cc_snd_space (tc) < 4 * tc->snd_mss)
- return 0;
-
- return 1;
-}
-
static int
tcp_buffer_discard_bytes (vlib_buffer_t * b, u32 n_bytes_to_drop)
{
@@ -1371,14 +1351,6 @@ in_order:
/* In order data, enqueue. Fifo figures out by itself if any out-of-order
* segments can be enqueued after fifo tail offset changes. */
error = tcp_session_enqueue_data (tc, b, n_data_bytes);
- if (tcp_can_delack (tc))
- {
- if (!tcp_timer_is_active (tc, TCP_TIMER_DELACK))
- tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_DELACK,
- tcp_cfg.delack_time);
- goto done;
- }
-
tcp_program_ack (tc);
done:
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 46c5661f7c1..e9bff5b954a 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -1064,17 +1064,6 @@ tcp_program_retransmit (tcp_connection_t * tc)
}
/**
- * Delayed ack timer handler
- *
- * Sends delayed ACK when timer expires
- */
-void
-tcp_timer_delack_handler (tcp_connection_t * tc)
-{
- tcp_send_ack (tc);
-}
-
-/**
* Send window update ack
*
* Ensures that it will be sent only once, after a zero rwnd has been
diff --git a/src/vnet/tcp/tcp_timer.h b/src/vnet/tcp/tcp_timer.h
index d34fdcb146d..914b5aaeeb7 100644
--- a/src/vnet/tcp/tcp_timer.h
+++ b/src/vnet/tcp/tcp_timer.h
@@ -31,6 +31,7 @@ always_inline void
tcp_timer_reset (tcp_timer_wheel_t * tw, tcp_connection_t * tc, u8 timer_id)
{
ASSERT (tc->c_thread_index == vlib_get_thread_index ());
+ tc->pending_timers &= ~(1 << timer_id);
if (tc->timers[timer_id] == TCP_TIMER_HANDLE_INVALID)
return;
diff --git a/src/vnet/tcp/tcp_types.h b/src/vnet/tcp/tcp_types.h
index 8b599400b8c..3cf4e9e33ef 100644
--- a/src/vnet/tcp/tcp_types.h
+++ b/src/vnet/tcp/tcp_types.h
@@ -62,7 +62,6 @@ typedef enum _tcp_state
/** TCP timers */
#define foreach_tcp_timer \
_(RETRANSMIT, "RETRANSMIT") \
- _(DELACK, "DELAYED ACK") \
_(PERSIST, "PERSIST") \
_(WAITCLOSE, "WAIT CLOSE") \
_(RETRANSMIT_SYN, "RETRANSMIT SYN") \
@@ -281,6 +280,7 @@ typedef struct _tcp_connection
u8 cfg_flags; /**< Connection configuration flags */
u16 flags; /**< Connection flags (see tcp_conn_flags_e) */
u32 timers[TCP_N_TIMERS]; /**< Timer handles into timer wheel */
+ u32 pending_timers; /**< Expired timers not yet handled */
u64 segs_in; /** RFC4022/4898 tcpHCInSegs/tcpEStatsPerfSegsIn */
u64 bytes_in; /** RFC4898 tcpEStatsPerfHCDataOctetsIn */