Skip to content

Commit fc034ac

Browse files
committed
Limit pacing rate and quantum for CC bypass
1 parent 03b8e29 commit fc034ac

File tree

3 files changed

+37
-28
lines changed

3 files changed

+37
-28
lines changed

picoquic/picoquic_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ extern "C" {
8585
#define PICOQUIC_CWIN_INITIAL (10 * PICOQUIC_MAX_PACKET_SIZE)
8686
#define PICOQUIC_CWIN_MINIMUM (2 * PICOQUIC_MAX_PACKET_SIZE)
8787

88+
#define PICOQUIC_PRIORITY_BYPASS_MAX_RATE 125000
89+
#define PICOQUIC_PRIORITY_BYPASS_QUANTUM 2560
90+
8891
#define PICOQUIC_DEFAULT_CRYPTO_EPOCH_LENGTH (1<<22)
8992

9093
#define PICOQUIC_DEFAULT_SIMULTANEOUS_LOGS 32
@@ -1453,6 +1456,7 @@ typedef struct st_picoquic_cnx_t {
14531456
uint64_t high_priority_stream_id;
14541457
uint64_t next_stream_id[4];
14551458
uint64_t priority_limit_for_bypass; /* Bypass CC if dtagram or stream priority lower than this, 0 means never */
1459+
picoquic_pacing_t priority_bypass_pacing;
14561460

14571461
/* Repeat queue contains packets with data frames that should be
14581462
* sent according to priority when congestion window opens. */

picoquic/quicctx.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3639,6 +3639,7 @@ picoquic_cnx_t* picoquic_create_cnx(picoquic_quic_t* quic,
36393639
for (int i = 0; i < 4; i++) {
36403640
cnx->next_stream_id[i] = i;
36413641
}
3642+
picoquic_pacing_init(&cnx->priority_bypass_pacing, start_time);
36423643
picoquic_register_path(cnx, cnx->path[0]);
36433644
}
36443645
}
@@ -4781,6 +4782,11 @@ void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantu
47814782
void picoquic_set_priority_limit_for_bypass(picoquic_cnx_t* cnx, uint8_t priority_limit)
47824783
{
47834784
cnx->priority_limit_for_bypass = priority_limit;
4785+
if (priority_limit > 0) {
4786+
picoquic_update_pacing_parameters(&cnx->priority_bypass_pacing,
4787+
PICOQUIC_PRIORITY_BYPASS_MAX_RATE, PICOQUIC_PRIORITY_BYPASS_QUANTUM,
4788+
cnx->path[0]->send_mtu, cnx->path[0]->smoothed_rtt, NULL);
4789+
}
47844790
}
47854791

47864792
void picoquic_set_feedback_loss_notification(picoquic_cnx_t* cnx, unsigned int should_notify)

picoquic/sender.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,7 +2931,7 @@ static uint8_t* picoquic_prepare_datagram_ready(picoquic_cnx_t* cnx, picoquic_pa
29312931
*/
29322932

29332933
static uint8_t* picoquic_prepare_stream_and_datagrams(picoquic_cnx_t* cnx, picoquic_path_t* path_x, uint8_t* bytes_next, uint8_t* bytes_max,
2934-
uint64_t max_priority_allowed,
2934+
uint64_t max_priority_allowed, uint64_t current_time,
29352935
int* more_data, int* is_pure_ack, int* no_data_to_send, int* ret)
29362936
{
29372937
int datagram_sent = 0;
@@ -2950,6 +2950,7 @@ static uint8_t* picoquic_prepare_stream_and_datagrams(picoquic_cnx_t* cnx, picoq
29502950
picoquic_packet_t* first_repeat = picoquic_first_data_repeat_packet(cnx);
29512951
uint64_t current_priority = UINT64_MAX;
29522952
uint64_t stream_priority = UINT64_MAX;
2953+
uint8_t* bytes_before_iteration = bytes_next;
29532954
int something_sent = 0;
29542955
int conflict_found = 0;
29552956

@@ -3030,6 +3031,12 @@ static uint8_t* picoquic_prepare_stream_and_datagrams(picoquic_cnx_t* cnx, picoq
30303031
more_data, is_pure_ack, &datagram_tried_and_failed, &datagram_sent, ret);
30313032
something_sent = datagram_sent;
30323033
}
3034+
3035+
if (current_priority < cnx->priority_limit_for_bypass && bytes_next > bytes_before_iteration) {
3036+
picoquic_update_pacing_data_after_send(&cnx->priority_bypass_pacing, bytes_next - bytes_before_iteration,
3037+
cnx->path[0]->send_mtu, current_time);
3038+
}
3039+
30333040
if (is_first_round) {
30343041
*no_data_to_send = ((first_stream == NULL && first_repeat == NULL) || stream_tried_and_failed) &&
30353042
(!datagram_present || datagram_tried_and_failed);
@@ -3174,25 +3181,13 @@ int picoquic_prepare_packet_almost_ready(picoquic_cnx_t* cnx, picoquic_path_t* p
31743181

31753182
length = bytes_next - bytes;
31763183
if (path_x->cwin < path_x->bytes_in_transit) {
3177-
/* Implementation of experimental API, picoquic_set_priority_limit_for_bypass */
3178-
uint8_t* bytes_next_before_bypass = bytes_next;
3179-
if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1) {
3180-
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3181-
cnx->priority_limit_for_bypass,
3182-
&more_data, &is_pure_ack, &no_data_to_send, &ret);
3183-
}
3184-
if (bytes_next != bytes_next_before_bypass) {
3185-
length = bytes_next - bytes;
3186-
}
3187-
else {
3188-
picoquic_per_ack_state_t ack_state = { 0 };
3189-
cnx->cwin_blocked = 1;
3190-
path_x->last_cwin_blocked_time = current_time;
3191-
if (cnx->congestion_alg != NULL) {
3192-
cnx->congestion_alg->alg_notify(cnx, path_x,
3193-
picoquic_congestion_notification_cwin_blocked,
3194-
&ack_state, current_time);
3195-
}
3184+
picoquic_per_ack_state_t ack_state = { 0 };
3185+
cnx->cwin_blocked = 1;
3186+
path_x->last_cwin_blocked_time = current_time;
3187+
if (cnx->congestion_alg != NULL) {
3188+
cnx->congestion_alg->alg_notify(cnx, path_x,
3189+
picoquic_congestion_notification_cwin_blocked,
3190+
&ack_state, current_time);
31963191
}
31973192
}
31983193
else {
@@ -3234,7 +3229,7 @@ int picoquic_prepare_packet_almost_ready(picoquic_cnx_t* cnx, picoquic_path_t* p
32343229
}
32353230
if (ret == 0) {
32363231
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3237-
UINT64_MAX,
3232+
UINT64_MAX, current_time,
32383233
&more_data, &is_pure_ack, &no_data_to_send, &ret);
32393234
}
32403235
/* TODO: replace this by posting of frame when CWIN estimated */
@@ -3533,9 +3528,11 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t* path_x,
35333528
/* Implementation of experimental API, picoquic_set_priority_limit_for_bypass */
35343529
uint8_t* bytes_next_before_bypass = bytes_next;
35353530
int no_data_to_send = 0;
3536-
if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1) {
3531+
if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1 &&
3532+
picoquic_is_authorized_by_pacing(&cnx->priority_bypass_pacing, current_time, next_wake_time,
3533+
cnx->quic->packet_train_mode, cnx->quic)) {
35373534
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3538-
cnx->priority_limit_for_bypass,
3535+
cnx->priority_limit_for_bypass, current_time,
35393536
&more_data, &is_pure_ack, &no_data_to_send, &ret);
35403537
}
35413538
if (bytes_next != bytes_next_before_bypass) {
@@ -3582,8 +3579,8 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t* path_x,
35823579
bytes_next = picoquic_format_ack_frequency_frame(cnx, bytes_next, bytes_max, &more_data);
35833580
}
35843581
if (ret == 0) {
3585-
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max, UINT64_MAX,
3586-
&more_data, &is_pure_ack, &no_data_to_send, &ret);
3582+
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3583+
UINT64_MAX, current_time, &more_data, &is_pure_ack, &no_data_to_send, &ret);
35873584
}
35883585

35893586
/* TODO: replace this by scheduling of BDP frame when window has been estimated */
@@ -3659,12 +3656,14 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t* path_x,
36593656
}
36603657
} /* end of CC */
36613658
} /* End of pacing */
3662-
else if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1) {
3659+
else if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1 &&
3660+
picoquic_is_authorized_by_pacing(&cnx->priority_bypass_pacing, current_time, next_wake_time,
3661+
cnx->quic->packet_train_mode, cnx->quic)) {
36633662
/* If congestion bypass is implemented, also consider pacing bypass */
36643663
int no_data_to_send = 0;
3665-
3664+
36663665
if ((bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3667-
cnx->priority_limit_for_bypass,
3666+
cnx->priority_limit_for_bypass, current_time,
36683667
&more_data, &is_pure_ack, &no_data_to_send, &ret)) != NULL) {
36693668
length = bytes_next - bytes;
36703669
}

0 commit comments

Comments
 (0)