summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/session_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session/session_node.c')
-rw-r--r--src/vnet/session/session_node.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index 8a96f585499..d2b918a2587 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -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);
}