if (__test_and_clear_bit(ix, &tq->segment_lost))
call->tx_nr_lost--;
if (test_bit(ix, &tq->segment_retransmitted)) { /* Use Rx.serial instead of TCP.ACK.ts_option.echo_reply. */ if (before(call->acks_highest_serial, tq->segment_serial[ix])) return; if (rtt < minmax_get(&call->min_rtt)) return;
}
/* The RACK algorithm requires the segment ACKs to be traversed in *orderofsegmenttransmission-buttheonlythingthisseemsto *matterforisthatRACK.rttissettotherttofthemostrecently *transmittedsegment.Weshouldbeabletoachievethesamebyonly *settingRACK.rttifthexmittimeisgreater.
*/ if (ktime_after(xmit_ts, call->rack_rtt_ts)) {
call->rack_rtt = rtt;
call->rack_rtt_ts = xmit_ts;
}
/* Track the highest sequence number so far ACK'd. This is not *necessarilythesameasack.firstPacket+ack.nAcks-1asthepeer *couldputaNACKinthelastSACKslot.
*/ if (after(seq, call->rack_fack))
call->rack_fack = seq; elseif (before(seq, call->rack_fack) &&
test_bit(ix, &tq->segment_retransmitted))
call->rack_reordering_seen = true;
}
if (after_eq(call->acks_hard_ack, call->tx_transmitted)) return; /* Everything we transmitted has been acked. */
/* There must be no other loss probe still in flight and we need to *havetakenanewRTTsamplesincelastprobeorthestartof *connection.
*/ if (!call->tlp_serial &&
call->tlp_rtt_taken != call->rtt_taken) {
call->tlp_is_retrans = false; if (after(call->send_top, call->tx_transmitted) &&
rxrpc_tx_window_space(call) > 0) { /* Transmit the lowest-sequence unsent DATA */
call->tx_last_serial = 0;
rxrpc_transmit_some_data(call, 1, rxrpc_txdata_tlp_new_data);
call->tlp_serial = call->tx_last_serial;
call->tlp_seq = call->tx_transmitted;
trace_rxrpc_tlp_probe(call, rxrpc_tlp_probe_trace_transmit_new);
in_flight = rxrpc_tx_in_flight(call);
} else { /* Retransmit the highest-sequence DATA sent */
call->tx_last_serial = 0;
rxrpc_resend_tlp(call);
call->tlp_is_retrans = true;
trace_rxrpc_tlp_probe(call, rxrpc_tlp_probe_trace_retransmit);
}
} else {
trace_rxrpc_tlp_probe(call, rxrpc_tlp_probe_trace_busy);
}
if (in_flight != 0) {
ktime_t rto = rxrpc_get_rto_backoff(call, false);
if (!call->tlp_is_retrans) { /* TLP of new data delivered */
trace_rxrpc_tlp_ack(call, summary, rxrpc_tlp_ack_trace_new_data);
call->tlp_serial = 0;
} elseif (summary->ack_reason == RXRPC_ACK_DUPLICATE &&
summary->acked_serial == call->tlp_serial) { /* General Case: Detected packet losses using RACK [7.4.1] */
trace_rxrpc_tlp_ack(call, summary, rxrpc_tlp_ack_trace_dup_acked);
call->tlp_serial = 0;
} elseif (after(call->acks_hard_ack, call->tlp_seq)) { /* Repaired the single loss */
trace_rxrpc_tlp_ack(call, summary, rxrpc_tlp_ack_trace_hard_beyond);
call->tlp_serial = 0; // TODO: Invoke congestion control to react to the loss // event the probe has repaired
} elseif (summary->tlp_probe_acked) {
trace_rxrpc_tlp_ack(call, summary, rxrpc_tlp_ack_trace_acked); /* Special Case: Detected a single loss repaired by the loss *probe[7.4.2]
*/
call->tlp_serial = 0;
} else {
trace_rxrpc_tlp_ack(call, summary, rxrpc_tlp_ack_trace_incomplete);
}
}
switch (mode) { case RXRPC_CALL_RACKTIMER_RACK_REORDER:
rxrpc_rack_detect_loss_and_arm_timer(call, &summary); break; case RXRPC_CALL_RACKTIMER_TLP_PTO:
rxrpc_tlp_send_probe(call); break; case RXRPC_CALL_RACKTIMER_RTO: // Might need to poke the congestion algo in some way
rxrpc_rack_mark_losses_on_rto(call); break; //case RXRPC_CALL_RACKTIMER_ZEROWIN: default:
pr_warn("Unexpected rack timer %u", call->rack_timer_mode);
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.