bbr->cycle_idx = (bbr->cycle_idx + 1) & (CYCLE_LEN - 1);
        bbr->cycle_mstamp = tp->delivered_mstamp;
-       bbr->pacing_gain = bbr->lt_use_bw ? BBR_UNIT :
-                                           bbr_pacing_gain[bbr->cycle_idx];
 }
 
 /* Gain cycling: cycle pacing gain to converge to fair share of available bw. */
        struct bbr *bbr = inet_csk_ca(sk);
 
        bbr->mode = BBR_STARTUP;
-       bbr->pacing_gain = bbr_high_gain;
-       bbr->cwnd_gain   = bbr_high_gain;
 }
 
 static void bbr_reset_probe_bw_mode(struct sock *sk)
        struct bbr *bbr = inet_csk_ca(sk);
 
        bbr->mode = BBR_PROBE_BW;
-       bbr->pacing_gain = BBR_UNIT;
-       bbr->cwnd_gain = bbr_cwnd_gain;
        bbr->cycle_idx = CYCLE_LEN - 1 - prandom_u32_max(bbr_cycle_rand);
        bbr_advance_cycle_phase(sk);    /* flip to next phase of gain cycle */
 }
 
        if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) {
                bbr->mode = BBR_DRAIN;  /* drain queue we created */
-               bbr->pacing_gain = bbr_drain_gain;      /* pace slow to drain */
-               bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */
                tcp_sk(sk)->snd_ssthresh =
                                bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT);
        }       /* fall through to check if in-flight is already small: */
        if (bbr_probe_rtt_mode_ms > 0 && filter_expired &&
            !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) {
                bbr->mode = BBR_PROBE_RTT;  /* dip, drain queue */
-               bbr->pacing_gain = BBR_UNIT;
-               bbr->cwnd_gain = BBR_UNIT;
                bbr_save_cwnd(sk);  /* note cwnd so we can restore it */
                bbr->probe_rtt_done_stamp = 0;
        }
                bbr->idle_restart = 0;
 }
 
+static void bbr_update_gains(struct sock *sk)
+{
+       struct bbr *bbr = inet_csk_ca(sk);
+
+       switch (bbr->mode) {
+       case BBR_STARTUP:
+               bbr->pacing_gain = bbr_high_gain;
+               bbr->cwnd_gain   = bbr_high_gain;
+               break;
+       case BBR_DRAIN:
+               bbr->pacing_gain = bbr_drain_gain;      /* slow, to drain */
+               bbr->cwnd_gain   = bbr_high_gain;       /* keep cwnd */
+               break;
+       case BBR_PROBE_BW:
+               bbr->pacing_gain = (bbr->lt_use_bw ?
+                                   BBR_UNIT :
+                                   bbr_pacing_gain[bbr->cycle_idx]);
+               bbr->cwnd_gain   = bbr_cwnd_gain;
+               break;
+       case BBR_PROBE_RTT:
+               bbr->pacing_gain = BBR_UNIT;
+               bbr->cwnd_gain   = BBR_UNIT;
+               break;
+       default:
+               WARN_ONCE(1, "BBR bad mode: %u\n", bbr->mode);
+               break;
+       }
+}
+
 static void bbr_update_model(struct sock *sk, const struct rate_sample *rs)
 {
        bbr_update_bw(sk, rs);
        bbr_check_full_bw_reached(sk, rs);
        bbr_check_drain(sk, rs);
        bbr_update_min_rtt(sk, rs);
+       bbr_update_gains(sk);
 }
 
 static void bbr_main(struct sock *sk, const struct rate_sample *rs)