session: allow small pacer bursts
Instead of enforcing a "strict" release of data, which relies on
frequent rescheduling of sessions, allow some pacer coalescing, i.e.,
short bursts, that can minimize load on scheduler/session layer and
potentially leverage tso.
Type: improvement
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I67e38e5b8dc335bd214113b70c68c27ae92bd6da
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index 967ff5d..a7fd85f 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -632,9 +632,9 @@
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 @@
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 @@
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