tcp: track buffer alloc failures 23/27223/3
authorFlorin Coras <fcoras@cisco.com>
Fri, 22 May 2020 21:51:30 +0000 (21:51 +0000)
committerDave Barach <openvpp@barachs.net>
Sun, 24 May 2020 17:34:32 +0000 (17:34 +0000)
Reported as part of "show tcp stats"

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I499ab4e41d13aaf1a0d060e37f09087e63d09567

src/vnet/tcp/tcp.h
src/vnet/tcp/tcp_output.c

index f4cc2c8..5c66412 100644 (file)
@@ -58,6 +58,7 @@ typedef struct _tcp_lookup_dispatch
   _(to_closing, u32, "timeout closing")                                \
   _(tr_abort, u32, "timer retransmit abort")                   \
   _(rst_unread, u32, "reset on close due to unread data")      \
+  _(no_buffer, u32, "out of buffers")                          \
 
 typedef struct tcp_wrk_stats_
 {
index 6bcca31..afc6520 100644 (file)
@@ -669,7 +669,10 @@ tcp_send_reset_w_pkt (tcp_connection_t * tc, vlib_buffer_t * pkt,
   fib_protocol_t fib_proto;
 
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
-    return;
+    {
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
+      return;
+    }
 
   b = vlib_get_buffer (vm, bi);
   sw_if_index = vnet_buffer (pkt)->sw_if_index[VLIB_RX];
@@ -750,7 +753,10 @@ tcp_send_reset (tcp_connection_t * tc)
   u8 flags;
 
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
-    return;
+    {
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
+      return;
+    }
   b = vlib_get_buffer (vm, bi);
   tcp_init_buffer (vm, b);
 
@@ -812,6 +818,7 @@ tcp_send_syn (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
 
@@ -842,6 +849,7 @@ tcp_send_synack (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
 
@@ -878,6 +886,7 @@ tcp_send_fin (tcp_connection_t * tc)
       else
        /* Make sure retransmit retries a fin not data */
        tc->flags |= TCP_CONN_FINSNT;
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
 
@@ -1018,6 +1027,7 @@ tcp_send_ack (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       tcp_update_rcv_wnd (tc);
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
   b = vlib_get_buffer (vm, bi);
@@ -1127,7 +1137,10 @@ tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
   if (PREDICT_TRUE (seg_size <= bytes_per_buffer))
     {
       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
-       return 0;
+       {
+         tcp_worker_stats_inc (wrk, no_buffer, 1);
+         return 0;
+       }
       *b = vlib_get_buffer (vm, bi);
       data = tcp_init_buffer (vm, *b);
       n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
@@ -1154,6 +1167,7 @@ tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
        {
          if (n_bufs)
            vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
+         tcp_worker_stats_inc (wrk, no_buffer, 1);
          return 0;
        }
 
@@ -1415,6 +1429,7 @@ tcp_timer_retransmit_handler (tcp_connection_t * tc)
       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
        {
          tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+         tcp_worker_stats_inc (wrk, no_buffer, 1);
          return;
        }
 
@@ -1478,6 +1493,7 @@ tcp_timer_retransmit_syn_handler (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
 
@@ -1545,6 +1561,7 @@ tcp_timer_persist_handler (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       tcp_persist_timer_set (&wrk->timer_wheel, tc);
+      tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }