* Collect new round-trip time estimate * and update averages and current timeout. */
| 3554 | * and update averages and current timeout. |
| 3555 | */ |
| 3556 | void |
| 3557 | tcp_xmit_timer(struct tcpcb *tp, int rtt) |
| 3558 | { |
| 3559 | int delta; |
| 3560 | |
| 3561 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 3562 | |
| 3563 | TCPSTAT_INC(tcps_rttupdated); |
| 3564 | tp->t_rttupdated++; |
| 3565 | #ifdef STATS |
| 3566 | stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, |
| 3567 | imax(0, rtt * 1000 / hz)); |
| 3568 | #endif |
| 3569 | if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { |
| 3570 | /* |
| 3571 | * srtt is stored as fixed point with 5 bits after the |
| 3572 | * binary point (i.e., scaled by 8). The following magic |
| 3573 | * is equivalent to the smoothing algorithm in rfc793 with |
| 3574 | * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed |
| 3575 | * point). Adjust rtt to origin 0. |
| 3576 | */ |
| 3577 | delta = ((rtt - 1) << TCP_DELTA_SHIFT) |
| 3578 | - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); |
| 3579 | |
| 3580 | if ((tp->t_srtt += delta) <= 0) |
| 3581 | tp->t_srtt = 1; |
| 3582 | |
| 3583 | /* |
| 3584 | * We accumulate a smoothed rtt variance (actually, a |
| 3585 | * smoothed mean difference), then set the retransmit |
| 3586 | * timer to smoothed rtt + 4 times the smoothed variance. |
| 3587 | * rttvar is stored as fixed point with 4 bits after the |
| 3588 | * binary point (scaled by 16). The following is |
| 3589 | * equivalent to rfc793 smoothing with an alpha of .75 |
| 3590 | * (rttvar = rttvar*3/4 + |delta| / 4). This replaces |
| 3591 | * rfc793's wired-in beta. |
| 3592 | */ |
| 3593 | if (delta < 0) |
| 3594 | delta = -delta; |
| 3595 | delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); |
| 3596 | if ((tp->t_rttvar += delta) <= 0) |
| 3597 | tp->t_rttvar = 1; |
| 3598 | if (tp->t_rttbest > tp->t_srtt + tp->t_rttvar) |
| 3599 | tp->t_rttbest = tp->t_srtt + tp->t_rttvar; |
| 3600 | } else { |
| 3601 | /* |
| 3602 | * No rtt measurement yet - use the unsmoothed rtt. |
| 3603 | * Set the variance to half the rtt (so our first |
| 3604 | * retransmit happens at 3*rtt). |
| 3605 | */ |
| 3606 | tp->t_srtt = rtt << TCP_RTT_SHIFT; |
| 3607 | tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); |
| 3608 | tp->t_rttbest = tp->t_srtt + tp->t_rttvar; |
| 3609 | } |
| 3610 | tp->t_rtttime = 0; |
| 3611 | tp->t_rxtshift = 0; |
| 3612 | |
| 3613 | /* |
no test coverage detected