session: multiple dgrams per dispatch 14/26614/11
authorFlorin Coras <fcoras@cisco.com>
Mon, 20 Apr 2020 21:07:06 +0000 (21:07 +0000)
committerDave Barach <openvpp@barachs.net>
Wed, 22 Apr 2020 18:19:23 +0000 (18:19 +0000)
Type: improvement

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

src/vnet/session/session_node.c

index 8a96f58..d2b918a 100644 (file)
@@ -611,7 +611,13 @@ session_tx_fifo_chain_tail (vlib_main_t * vm, session_tx_context_t * ctx,
                {
                  u32 offset = hdr->data_length + SESSION_CONN_HDR_LEN;
                  svm_fifo_dequeue_drop (f, offset);
+                 if (ctx->left_to_snd > n_bytes_read)
+                   svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
+                                  (u8 *) & ctx->hdr);
                }
+             else if (ctx->left_to_snd == n_bytes_read)
+               svm_fifo_overwrite_head (ctx->s->tx_fifo, (u8 *) & ctx->hdr,
+                                        sizeof (session_dgram_pre_hdr_t));
            }
          else
            n_bytes_read = svm_fifo_dequeue (ctx->s->tx_fifo,
@@ -690,7 +696,13 @@ session_tx_fill_buffer (vlib_main_t * vm, session_tx_context_t * ctx,
            {
              offset = hdr->data_length + SESSION_CONN_HDR_LEN;
              svm_fifo_dequeue_drop (f, offset);
+             if (ctx->left_to_snd > n_bytes_read)
+               svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
+                              (u8 *) & ctx->hdr);
            }
+         else if (ctx->left_to_snd == n_bytes_read)
+           svm_fifo_overwrite_head (ctx->s->tx_fifo, (u8 *) & ctx->hdr,
+                                    sizeof (session_dgram_pre_hdr_t));
        }
       else
        {
@@ -758,7 +770,10 @@ session_tx_set_dequeue_params (vlib_main_t * vm, session_tx_context_t * ctx,
                               u32 max_segs, u8 peek_data)
 {
   u32 n_bytes_per_buf, n_bytes_per_seg;
+
+  n_bytes_per_buf = vlib_buffer_get_default_data_size (vm);
   ctx->max_dequeue = svm_fifo_max_dequeue_cons (ctx->s->tx_fifo);
+
   if (peek_data)
     {
       /* Offset in rx fifo from where to peek data */
@@ -773,15 +788,49 @@ session_tx_set_dequeue_params (vlib_main_t * vm, session_tx_context_t * ctx,
     {
       if (ctx->transport_vft->transport_options.tx_type == TRANSPORT_TX_DGRAM)
        {
+         u32 len, chain_limit;
+
          if (ctx->max_dequeue <= sizeof (ctx->hdr))
            {
              ctx->max_len_to_snd = 0;
              return;
            }
+
          svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
                         (u8 *) & ctx->hdr);
          ASSERT (ctx->hdr.data_length > ctx->hdr.data_offset);
-         ctx->max_dequeue = ctx->hdr.data_length - ctx->hdr.data_offset;
+         len = ctx->hdr.data_length - ctx->hdr.data_offset;
+
+         /* Process multiple dgrams if smaller than min (buf_space, mss).
+          * This avoids handling multiple dgrams if they require buffer
+          * chains */
+         chain_limit = clib_min (n_bytes_per_buf - TRANSPORT_MAX_HDRS_LEN,
+                                 ctx->sp.snd_mss);
+         if (ctx->hdr.data_length <= chain_limit)
+           {
+             u32 first_dgram_len, dgram_len, offset, max_offset;
+             session_dgram_hdr_t hdr;
+
+             ctx->sp.snd_mss = clib_min (ctx->sp.snd_mss, len);
+             offset = ctx->hdr.data_length + sizeof (session_dgram_hdr_t);
+             first_dgram_len = len;
+             max_offset = clib_min (ctx->max_dequeue, 16 << 10);
+
+             while (offset < max_offset)
+               {
+                 svm_fifo_peek (ctx->s->tx_fifo, offset, sizeof (ctx->hdr),
+                                (u8 *) & hdr);
+                 ASSERT (hdr.data_length > hdr.data_offset);
+                 dgram_len = hdr.data_length - hdr.data_offset;
+                 if (len + dgram_len > ctx->max_dequeue
+                     || first_dgram_len != dgram_len)
+                   break;
+                 len += dgram_len;
+                 offset += sizeof (hdr) + hdr.data_length;
+               }
+           }
+
+         ctx->max_dequeue = len;
        }
     }
   ASSERT (ctx->max_dequeue > 0);
@@ -809,7 +858,6 @@ session_tx_set_dequeue_params (vlib_main_t * vm, session_tx_context_t * ctx,
       ctx->max_len_to_snd = max_segs * ctx->sp.snd_mss;
     }
 
-  n_bytes_per_buf = vlib_buffer_get_default_data_size (vm);
   ASSERT (n_bytes_per_buf > TRANSPORT_MAX_HDRS_LEN);
   if (ctx->n_segs_per_evt > 1)
     {
@@ -1049,11 +1097,6 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
 
   if (!peek_data)
     {
-      /* Fix dgram pre header */
-      if (ctx->transport_vft->transport_options.tx_type == TRANSPORT_TX_DGRAM
-         && ctx->max_len_to_snd < ctx->max_dequeue)
-       svm_fifo_overwrite_head (ctx->s->tx_fifo, (u8 *) & ctx->hdr,
-                                sizeof (session_dgram_pre_hdr_t));
       if (svm_fifo_needs_deq_ntf (ctx->s->tx_fifo, ctx->max_len_to_snd))
        session_dequeue_notify (ctx->s);
     }