aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/session/session_node.c3
-rw-r--r--src/vnet/session/transport.c35
-rw-r--r--src/vnet/session/transport.h1
-rw-r--r--src/vnet/session/transport_types.h8
-rw-r--r--src/vppinfra/clib.h8
5 files changed, 36 insertions, 19 deletions
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index 8a350d4549f..12080122c8e 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -1037,7 +1037,8 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
return SESSION_TX_NO_BUFFERS;
}
- transport_connection_update_tx_bytes (ctx->tc, ctx->max_len_to_snd);
+ if (transport_connection_is_tx_paced (ctx->tc))
+ transport_connection_tx_pacer_update_bytes (ctx->tc, ctx->max_len_to_snd);
ctx->left_to_snd = ctx->max_len_to_snd;
n_left = ctx->n_segs_per_evt;
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index 967ff5d9cba..a7fd85f5f2e 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -632,9 +632,9 @@ format_transport_pacer (u8 * s, va_list * args)
now = transport_us_time_now (thread_index);
diff = now - pacer->last_update;
- s = format (s, "rate %lu bucket %lu t/p %.3f last_update %U idle %u",
+ s = format (s, "rate %lu bucket %lu t/p %.3f last_update %U burst %u",
pacer->bytes_per_sec, pacer->bucket, pacer->tokens_per_period,
- format_clib_us_time, diff, pacer->idle_timeout_us);
+ format_clib_us_time, diff, pacer->max_burst);
return s;
}
@@ -644,26 +644,18 @@ spacer_max_burst (spacer_t * pacer, clib_us_time_t time_now)
u64 n_periods = (time_now - pacer->last_update);
u64 inc;
- if (PREDICT_FALSE (n_periods > pacer->idle_timeout_us))
- {
- pacer->last_update = time_now;
- pacer->bucket = TRANSPORT_PACER_MIN_BURST;
- return TRANSPORT_PACER_MIN_BURST;
- }
-
if ((inc = (f32) n_periods * pacer->tokens_per_period) > 10)
{
pacer->last_update = time_now;
- pacer->bucket = clib_min (pacer->bucket + inc, pacer->bytes_per_sec);
+ pacer->bucket = clib_min (pacer->bucket + inc, pacer->max_burst);
}
- return clib_min (pacer->bucket, TRANSPORT_PACER_MAX_BURST);
+ return pacer->bucket > 0 ? pacer->max_burst : 0;
}
static inline void
spacer_update_bucket (spacer_t * pacer, u32 bytes)
{
- ASSERT (pacer->bucket >= bytes);
pacer->bucket -= bytes;
}
@@ -671,11 +663,26 @@ static inline void
spacer_set_pace_rate (spacer_t * pacer, u64 rate_bytes_per_sec,
clib_us_time_t rtt)
{
+ clib_us_time_t max_time;
+
ASSERT (rate_bytes_per_sec != 0);
pacer->bytes_per_sec = rate_bytes_per_sec;
pacer->tokens_per_period = rate_bytes_per_sec * CLIB_US_TIME_PERIOD;
- pacer->idle_timeout_us = clib_max (rtt * TRANSPORT_PACER_IDLE_FACTOR,
- TRANSPORT_PACER_MIN_IDLE);
+
+ /* Allow a min number of bursts per rtt, if their size is acceptable. Goal
+ * is to spread the sending of data over the rtt but to also allow for some
+ * coalescing that can potentially
+ * 1) reduce load on session layer by reducing scheduling frequency for a
+ * session and
+ * 2) optimize sending when tso if available
+ *
+ * Max "time-length" of a burst cannot be less than 1us or more than 1ms.
+ */
+ max_time = rtt / TRANSPORT_PACER_BURSTS_PER_RTT;
+ max_time = clib_clamp (max_time, 1 /* 1us */ , 1000 /* 1ms */ );
+ pacer->max_burst = (rate_bytes_per_sec * max_time) * CLIB_US_TIME_PERIOD;
+ pacer->max_burst = clib_clamp (pacer->max_burst, TRANSPORT_PACER_MIN_BURST,
+ TRANSPORT_PACER_MAX_BURST);
}
static inline u64
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index c8d4e27be66..9a9b89fc9fd 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -23,6 +23,7 @@
#define TRANSPORT_PACER_MIN_BURST TRANSPORT_PACER_MIN_MSS
#define TRANSPORT_PACER_MAX_BURST (43 * TRANSPORT_PACER_MIN_MSS)
#define TRANSPORT_PACER_MAX_BURST_PKTS 43
+#define TRANSPORT_PACER_BURSTS_PER_RTT 20
#define TRANSPORT_PACER_MIN_IDLE 100
#define TRANSPORT_PACER_IDLE_FACTOR 0.05
diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h
index ab34d9f3397..2caafea0fbe 100644
--- a/src/vnet/session/transport_types.h
+++ b/src/vnet/session/transport_types.h
@@ -65,10 +65,10 @@ typedef enum transport_connection_flags_
typedef struct _spacer
{
u64 bytes_per_sec;
- u64 bucket;
+ i64 bucket;
clib_us_time_t last_update;
f32 tokens_per_period;
- u32 idle_timeout_us;
+ u32 max_burst;
} spacer_t;
#define TRANSPORT_CONN_ID_LEN 44
@@ -146,8 +146,8 @@ typedef struct _transport_connection
#define c_stats connection.stats
#define c_pacer connection.pacer
#define c_flags connection.flags
-#define s_ho_handle pacer.bucket
-#define c_s_ho_handle connection.pacer.bucket
+#define s_ho_handle pacer.bytes_per_sec
+#define c_s_ho_handle connection.pacer.bytes_per_sec
} transport_connection_t;
STATIC_ASSERT (STRUCT_OFFSET_OF (transport_connection_t, s_index)
diff --git a/src/vppinfra/clib.h b/src/vppinfra/clib.h
index 9474350c6da..22377c61440 100644
--- a/src/vppinfra/clib.h
+++ b/src/vppinfra/clib.h
@@ -332,6 +332,14 @@ extract_bits (uword x, int start, int count)
_x < _y ? _x : _y; \
})
+#define clib_clamp(x,lo,hi) \
+({ \
+ __typeof__ (x) _x = (x); \
+ __typeof__ (lo) _lo = (lo); \
+ __typeof__ (hi) _hi = (hi); \
+ _x < _lo ? _lo : (_x > _hi ? _hi : _x); \
+})
+
#define clib_abs(x) \
({ \
__typeof__ (x) _x = (x); \