Keep pacing in bytes per second and reprice outstanding shaper debt
This commit is contained in:
1 parent
b39a861a57
commit
7e413db1e1
3 files changed
+93
-22
No files matched your search
@@ -17,6 +17,7 @@ static struct utun_config cfg;
|
||||
static struct ETCP_CONN* conn;
|
||||
static struct ETCP_LINK *a, *b;
|
||||
static unsigned sends, fail_alloc, fail_send, fail_tx_timer, bbr_calls, saw_cwnd_limited, saw_app_limited;
|
||||
static unsigned fail_shaper_timer;
|
||||
static struct bbr_rate_sample last_sample;
|
||||
static uint32_t last_mss;
|
||||
|
||||
@@ -28,6 +29,7 @@ void* __wrap_uasync_call_soon(struct UASYNC* loop, void* arg, timeout_callback_t
|
||||
|
||||
void* __real_uasync_set_timeout(struct UASYNC*, int, void*, timeout_callback_t, const char*);
|
||||
void* __wrap_uasync_set_timeout(struct UASYNC* loop, int delay, void* arg, timeout_callback_t callback, const char* name) {
|
||||
if (fail_shaper_timer && !strcmp(name, "etcp_shaper")) { fail_shaper_timer--; return NULL; }
|
||||
if (fail_tx_timer && !strcmp(name, "etcp_tx")) { fail_tx_timer--; return NULL; }
|
||||
return __real_uasync_set_timeout(loop, delay, arg, callback, name);
|
||||
}
|
||||
@@ -73,6 +75,7 @@ static void check_accounting(void) {
|
||||
static void setup(void) {
|
||||
memset(&inst, 0, sizeof(inst)); memset(&cfg, 0, sizeof(cfg));
|
||||
sends = fail_alloc = fail_send = fail_tx_timer = bbr_calls = saw_cwnd_limited = saw_app_limited = 0;
|
||||
fail_shaper_timer = 0;
|
||||
ua = uasync_create(); CHECK(ua);
|
||||
inst.ua = ua; inst.node_id = 1; inst.config = &cfg; cfg.global.bbr_max_cwnd = INFLIGHT_LIM_MAX;
|
||||
inst.connections = queue_new(ua, 16, 0, 8, "windows");
|
||||
@@ -296,6 +299,37 @@ static void pacing_reset_close(void) {
|
||||
teardown();
|
||||
}
|
||||
|
||||
/* Смена ставки пересчитывает долг, а не оставляет таймер от прежней скорости. */
|
||||
static void pacing_rate_changes(void) {
|
||||
setup(); b->link_status = 0; conn->rtt_avg_10 = 10000;
|
||||
etcp_loadbalancer_set_pacing_rate(a, 100);
|
||||
enqueue(1000); wait_sends(1); enqueue(500);
|
||||
uint64_t debt = a->shaper_load_time_tb - get_time_tb();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Pacing below 1Kbit/s: rate=%u debt_tb=%llu", a->bbr_pacing_rate, (unsigned long long)debt);
|
||||
CHECK(a->shaper_timer && a->bbr_pacing_rate == 100 && debt >= 99000 && debt <= 103000);
|
||||
etcp_loadbalancer_set_pacing_rate(a, 1000000);
|
||||
CHECK(a->shaper_load_time_tb <= get_time_tb() + 20);
|
||||
wait_sends(2); ack_all(); teardown();
|
||||
|
||||
setup(); b->link_status = 0; conn->rtt_avg_10 = 10000;
|
||||
etcp_loadbalancer_set_pacing_rate(a, 1000000);
|
||||
enqueue(1000); wait_sends(1); enqueue(500);
|
||||
etcp_loadbalancer_set_pacing_rate(a, 100);
|
||||
CHECK(a->shaper_timer && a->shaper_load_time_tb > get_time_tb() + 1000);
|
||||
test_clock_run_for(ua, 200); CHECK(sends == 1 && conn->input_send_q->count == 1);
|
||||
etcp_loadbalancer_set_pacing_rate(a, 0);
|
||||
CHECK(!a->shaper_timer && !a->shaper_sub_nanotime);
|
||||
wait_sends(2); ack_all(); teardown();
|
||||
}
|
||||
|
||||
static void pacing_timer_failure(void) {
|
||||
setup(); CHECK(etcp_conn_ref_take(conn) == 0); b->link_status = 0;
|
||||
etcp_loadbalancer_set_pacing_rate(a, 100); fail_shaper_timer = 1;
|
||||
enqueue(100); uasync_drain_immediate(ua);
|
||||
CHECK(!fail_shaper_timer && conn->state == 2 && !conn->links);
|
||||
etcp_conn_ref_free(conn); teardown();
|
||||
}
|
||||
|
||||
/* Отправитель не превращает pending transport в UP до первого INIT/подтверждения сессии. */
|
||||
static void initial_readiness(void) {
|
||||
setup(); conn->state = 0; conn->initialized = conn->links_up = conn->tx_state = 0;
|
||||
@@ -338,7 +372,7 @@ static void immediate_send(void) {
|
||||
|
||||
/* Подтверждения входящего потока не должны ждать pacing собственного исходящего DATA. */
|
||||
static void ack_without_data_pacing(void) {
|
||||
setup(); b->link_status = 0; a->bandwidth = 1;
|
||||
setup(); b->link_status = 0; etcp_loadbalancer_set_pacing_rate(a, 125);
|
||||
a->shaper_timer = uasync_set_timeout(ua, 1000, a, shaper_ready, "test_shaper"); CHECK(a->shaper_timer);
|
||||
void* timer = a->shaper_timer;
|
||||
uint64_t load = a->shaper_load_time_tb, fraction = a->shaper_sub_nanotime;
|
||||
@@ -418,7 +452,7 @@ int main(void) {
|
||||
void (*cases[])(void) = {selection, boundaries_ack_burst, late_ack_and_migration, lost_ack_and_shrink,
|
||||
grow_and_session, allocation_and_send_failure, removed_link_and_bbr, pacing_reset_close, initial_readiness,
|
||||
config_limits, timer_failure, immediate_send, ack_without_data_pacing, bbr_delivery_clock, bbr_probe_window, tcp_initial_window,
|
||||
retransmission_timeout};
|
||||
retransmission_timeout, pacing_rate_changes, pacing_timer_failure};
|
||||
for (unsigned i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
cases[i](); CHECK(u_get_allocated_count() == baseline);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS ETCP window scenario %u", i);
|
||||
|
||||
Reference in new issue
Block a user