| 561 | } |
| 562 | |
| 563 | static uint32_t |
| 564 | bbr_timer_start(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) |
| 565 | { |
| 566 | /* |
| 567 | * Start the FR timer, we do this based on getting the first one in |
| 568 | * the rc_tmap. Note that if its NULL we must stop the timer. in all |
| 569 | * events we need to stop the running timer (if its running) before |
| 570 | * starting the new one. |
| 571 | */ |
| 572 | uint32_t thresh, exp, to, srtt, time_since_sent, tstmp_touse; |
| 573 | int32_t idx; |
| 574 | int32_t is_tlp_timer = 0; |
| 575 | struct bbr_sendmap *rsm; |
| 576 | |
| 577 | if (bbr->rc_all_timers_stopped) { |
| 578 | /* All timers have been stopped none are to run */ |
| 579 | return (0); |
| 580 | } |
| 581 | if (bbr->rc_in_persist) { |
| 582 | /* We can't start any timer in persists */ |
| 583 | return (bbr_get_persists_timer_val(tp, bbr)); |
| 584 | } |
| 585 | rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); |
| 586 | if ((rsm == NULL) || |
| 587 | ((tp->t_flags & TF_SACK_PERMIT) == 0) || |
| 588 | (tp->t_state < TCPS_ESTABLISHED)) { |
| 589 | /* Nothing on the send map */ |
| 590 | activate_rxt: |
| 591 | if (SEQ_LT(tp->snd_una, tp->snd_max) || sbavail(&(tp->t_inpcb->inp_socket->so_snd))) { |
| 592 | uint64_t tov; |
| 593 | |
| 594 | time_since_sent = 0; |
| 595 | rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); |
| 596 | if (rsm) { |
| 597 | idx = rsm->r_rtr_cnt - 1; |
| 598 | if (TSTMP_GEQ(rsm->r_tim_lastsent[idx], bbr->r_ctl.rc_tlp_rxt_last_time)) |
| 599 | tstmp_touse = rsm->r_tim_lastsent[idx]; |
| 600 | else |
| 601 | tstmp_touse = bbr->r_ctl.rc_tlp_rxt_last_time; |
| 602 | if (TSTMP_GT(tstmp_touse, cts)) |
| 603 | time_since_sent = cts - tstmp_touse; |
| 604 | } |
| 605 | bbr->r_ctl.rc_hpts_flags |= PACE_TMR_RXT; |
| 606 | if (tp->t_srtt == 0) |
| 607 | tov = BBR_INITIAL_RTO; |
| 608 | else |
| 609 | tov = ((uint64_t)(TICKS_2_USEC(tp->t_srtt) + |
| 610 | ((uint64_t)TICKS_2_USEC(tp->t_rttvar) * (uint64_t)4)) >> TCP_RTT_SHIFT); |
| 611 | if (tp->t_rxtshift) |
| 612 | tov *= tcp_backoff[tp->t_rxtshift]; |
| 613 | if (tov > time_since_sent) |
| 614 | tov -= time_since_sent; |
| 615 | else |
| 616 | tov = bbr->r_ctl.rc_min_to; |
| 617 | TCPT_RANGESET_NOSLOP(to, tov, |
| 618 | (bbr->r_ctl.rc_min_rto_ms * MS_IN_USEC), |
| 619 | (bbr->rc_max_rto_sec * USECS_IN_SECOND)); |
| 620 | bbr_log_timer_var(bbr, 2, cts, 0, srtt, 0, to); |
no test coverage detected