| 11438 | } |
| 11439 | |
| 11440 | static int32_t |
| 11441 | rack_get_pacing_delay(struct tcp_rack *rack, struct tcpcb *tp, uint32_t len, struct rack_sendmap *rsm, uint32_t segsiz) |
| 11442 | { |
| 11443 | struct rack_sendmap *lrsm; |
| 11444 | int32_t slot = 0; |
| 11445 | int err; |
| 11446 | |
| 11447 | if (rack->rc_always_pace == 0) { |
| 11448 | /* |
| 11449 | * We use the most optimistic possible cwnd/srtt for |
| 11450 | * sending calculations. This will make our |
| 11451 | * calculation anticipate getting more through |
| 11452 | * quicker then possible. But thats ok we don't want |
| 11453 | * the peer to have a gap in data sending. |
| 11454 | */ |
| 11455 | uint32_t srtt, cwnd, tr_perms = 0; |
| 11456 | int32_t reduce = 0; |
| 11457 | |
| 11458 | old_method: |
| 11459 | /* |
| 11460 | * We keep no precise pacing with the old method |
| 11461 | * instead we use the pacer to mitigate bursts. |
| 11462 | */ |
| 11463 | rack->r_ctl.rc_agg_delayed = 0; |
| 11464 | rack->r_early = 0; |
| 11465 | rack->r_late = 0; |
| 11466 | rack->r_ctl.rc_agg_early = 0; |
| 11467 | if (rack->r_ctl.rc_rack_min_rtt) |
| 11468 | srtt = rack->r_ctl.rc_rack_min_rtt; |
| 11469 | else |
| 11470 | srtt = TICKS_2_MSEC((tp->t_srtt >> TCP_RTT_SHIFT)); |
| 11471 | if (rack->r_ctl.rc_rack_largest_cwnd) |
| 11472 | cwnd = rack->r_ctl.rc_rack_largest_cwnd; |
| 11473 | else |
| 11474 | cwnd = rack->r_ctl.cwnd_to_use; |
| 11475 | tr_perms = cwnd / srtt; |
| 11476 | if (tr_perms == 0) { |
| 11477 | tr_perms = ctf_fixed_maxseg(tp); |
| 11478 | } |
| 11479 | /* |
| 11480 | * Calculate how long this will take to drain, if |
| 11481 | * the calculation comes out to zero, thats ok we |
| 11482 | * will use send_a_lot to possibly spin around for |
| 11483 | * more increasing tot_len_this_send to the point |
| 11484 | * that its going to require a pace, or we hit the |
| 11485 | * cwnd. Which in that case we are just waiting for |
| 11486 | * a ACK. |
| 11487 | */ |
| 11488 | slot = len / tr_perms; |
| 11489 | /* Now do we reduce the time so we don't run dry? */ |
| 11490 | if (slot && rack_slot_reduction) { |
| 11491 | reduce = (slot / rack_slot_reduction); |
| 11492 | if (reduce < slot) { |
| 11493 | slot -= reduce; |
| 11494 | } else |
| 11495 | slot = 0; |
| 11496 | } |
| 11497 | slot *= HPTS_USEC_IN_MSEC; |
no test coverage detected