@ -21,7 +21,6 @@
# include "src/core/ext/transport/chttp2/transport/flow_control.h"
# include <inttypes.h>
# include <limits.h>
# include <algorithm>
# include <cmath>
@ -278,45 +277,33 @@ void TransportFlowControl::UpdateSetting(
uint32_t new_desired_value , FlowControlAction * action ,
FlowControlAction & ( FlowControlAction : : * set ) ( FlowControlAction : : Urgency ,
uint32_t ) ) {
if ( IsFlowControlFixesEnabled ( ) ) {
new_desired_value =
Clamp ( new_desired_value , grpc_chttp2_settings_parameters [ id ] . min_value ,
grpc_chttp2_settings_parameters [ id ] . max_value ) ;
if ( new_desired_value ! = * desired_value ) {
if ( grpc_flowctl_trace . enabled ( ) ) {
gpr_log ( GPR_INFO , " [flowctl] UPDATE SETTING %s from % " PRId64 " to %d " ,
grpc_chttp2_settings_parameters [ id ] . name , * desired_value ,
new_desired_value ) ;
}
// Reaching zero can only happen for initial window size, and if it occurs
// we really want to wake up writes and ensure all the queued stream
// window updates are flushed, since stream flow control operates
// differently at zero window size.
FlowControlAction : : Urgency urgency =
FlowControlAction : : Urgency : : QUEUE_UPDATE ;
if ( * desired_value = = 0 | | new_desired_value = = 0 ) {
urgency = FlowControlAction : : Urgency : : UPDATE_IMMEDIATELY ;
}
* desired_value = new_desired_value ;
( action - > * set ) ( urgency , * desired_value ) ;
new_desired_value =
Clamp ( new_desired_value , grpc_chttp2_settings_parameters [ id ] . min_value ,
grpc_chttp2_settings_parameters [ id ] . max_value ) ;
if ( new_desired_value ! = * desired_value ) {
if ( grpc_flowctl_trace . enabled ( ) ) {
gpr_log ( GPR_INFO , " [flowctl] UPDATE SETTING %s from % " PRId64 " to %d " ,
grpc_chttp2_settings_parameters [ id ] . name , * desired_value ,
new_desired_value ) ;
}
} else {
int64_t delta = new_desired_value - * desired_value ;
// TODO(ncteisen): tune thi s
if ( delta ! = 0 & &
( delta < = - * desired_value / 5 | | delta > = * desired_value / 5 ) ) {
* desired_value = new_desired_value ;
( action - > * set ) ( FlowControlAction : : Urgency : : QUEUE_UPDATE ,
static_cast < uint32_t > ( * desired_value ) ) ;
// Reaching zero can only happen for initial window size, and if it occurs
// we really want to wake up writes and ensure all the queued stream
// window updates are flushed, since stream flow control operates
// differently at zero window size.
FlowControlAction : : Urgency urgency =
FlowControlAction : : Urgency : : QUEUE_UPDATE ;
if ( * desired_value = = 0 | | new_desired_value = = 0 ) {
urgency = FlowControlAction : : Urgency : : UPDATE_IMMEDIATELY ;
}
* desired_value = new_desired_value ;
( action - > * set ) ( urgency , * desired_value ) ;
}
}
FlowControlAction TransportFlowControl : : SetAckedInitialWindow ( uint32_t value ) {
acked_init_window_ = value ;
FlowControlAction action ;
if ( IsFlowControlFixesEnabled ( ) & &
acked_init_window_ ! = target_initial_window_size_ ) {
if ( acked_init_window_ ! = target_initial_window_size_ ) {
FlowControlAction : : Urgency urgency =
FlowControlAction : : Urgency : : QUEUE_UPDATE ;
if ( acked_init_window_ = = 0 | | target_initial_window_size_ = = 0 ) {
@ -330,68 +317,31 @@ FlowControlAction TransportFlowControl::SetAckedInitialWindow(uint32_t value) {
FlowControlAction TransportFlowControl : : PeriodicUpdate ( ) {
FlowControlAction action ;
if ( enable_bdp_probe_ ) {
if ( IsFlowControlFixesEnabled ( ) ) {
// get bdp estimate and update initial_window accordingly.
// target might change based on how much memory pressure we are under
// TODO(ncteisen): experiment with setting target to be huge under low
// memory pressure.
uint32_t target = static_cast < uint32_t > ( RoundUpToPowerOf2 (
Clamp ( IsMemoryPressureControllerEnabled ( )
? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp ( )
: pow ( 2 , SmoothLogBdp ( TargetLogBdp ( ) ) ) ,
0.0 , static_cast < double > ( kMaxInitialWindowSize ) ) ) ) ;
if ( target < kMinPositiveInitialWindowSize ) target = 0 ;
if ( g_test_only_transport_target_window_estimates_mocker ! = nullptr ) {
// Hook for simulating unusual flow control situations in tests.
target = g_test_only_transport_target_window_estimates_mocker
- > ComputeNextTargetInitialWindowSizeFromPeriodicUpdate (
target_initial_window_size_ /* current target */ ) ;
}
// Though initial window 'could' drop to 0, we keep the floor at
// kMinInitialWindowSize
UpdateSetting ( GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE ,
& target_initial_window_size_ , target , & action ,
& FlowControlAction : : set_send_initial_window_update ) ;
// we target the max of BDP or bandwidth in microseconds.
UpdateSetting ( GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE , & target_frame_size_ ,
target , & action ,
& FlowControlAction : : set_send_max_frame_size_update ) ;
} else {
// get bdp estimate and update initial_window accordingly.
// target might change based on how much memory pressure we are under
// TODO(ncteisen): experiment with setting target to be huge under low
// memory pressure.
double target = IsMemoryPressureControllerEnabled ( )
? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp ( )
: pow ( 2 , SmoothLogBdp ( TargetLogBdp ( ) ) ) ;
if ( g_test_only_transport_target_window_estimates_mocker ! = nullptr ) {
// Hook for simulating unusual flow control situations in tests.
target = g_test_only_transport_target_window_estimates_mocker
- > ComputeNextTargetInitialWindowSizeFromPeriodicUpdate (
target_initial_window_size_ /* current target */ ) ;
}
// Though initial window 'could' drop to 0, we keep the floor at
// kMinInitialWindowSize
UpdateSetting ( GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE ,
& target_initial_window_size_ ,
static_cast < int32_t > ( Clamp (
target , static_cast < double > ( kMinInitialWindowSize ) ,
static_cast < double > ( kMaxInitialWindowSize ) ) ) ,
& action ,
& FlowControlAction : : set_send_initial_window_update ) ;
// get bandwidth estimate and update max_frame accordingly.
double bw_dbl = bdp_estimator_ . EstimateBandwidth ( ) ;
// we target the max of BDP or bandwidth in microseconds.
UpdateSetting (
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE , & target_frame_size_ ,
static_cast < int32_t > (
Clamp ( std : : max ( static_cast < int32_t > ( Clamp (
bw_dbl , 0.0 , static_cast < double > ( INT_MAX ) ) ) /
1000 ,
static_cast < int32_t > ( target_initial_window_size_ ) ) ,
16384 , 16777215 ) ) ,
& action , & FlowControlAction : : set_send_max_frame_size_update ) ;
// get bdp estimate and update initial_window accordingly.
// target might change based on how much memory pressure we are under
// TODO(ncteisen): experiment with setting target to be huge under low
// memory pressure.
uint32_t target = static_cast < uint32_t > ( RoundUpToPowerOf2 (
Clamp ( IsMemoryPressureControllerEnabled ( )
? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp ( )
: pow ( 2 , SmoothLogBdp ( TargetLogBdp ( ) ) ) ,
0.0 , static_cast < double > ( kMaxInitialWindowSize ) ) ) ) ;
if ( target < kMinPositiveInitialWindowSize ) target = 0 ;
if ( g_test_only_transport_target_window_estimates_mocker ! = nullptr ) {
// Hook for simulating unusual flow control situations in tests.
target = g_test_only_transport_target_window_estimates_mocker
- > ComputeNextTargetInitialWindowSizeFromPeriodicUpdate (
target_initial_window_size_ /* current target */ ) ;
}
// Though initial window 'could' drop to 0, we keep the floor at
// kMinInitialWindowSize
UpdateSetting ( GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE ,
& target_initial_window_size_ , target , & action ,
& FlowControlAction : : set_send_initial_window_update ) ;
// we target the max of BDP or bandwidth in microseconds.
UpdateSetting ( GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE , & target_frame_size_ ,
target , & action ,
& FlowControlAction : : set_send_max_frame_size_update ) ;
if ( IsTcpFrameSizeTuningEnabled ( ) ) {
// Advertise PREFERRED_RECEIVE_CRYPTO_FRAME_SIZE to peer. By advertising