Add more information to the `quic_send_alarm_postponed` QUIC_BUG. PiperOrigin-RevId: 576169564
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc index 513f4d0..d9f48cc 100644 --- a/quiche/quic/core/quic_connection.cc +++ b/quiche/quic/core/quic_connection.cc
@@ -2413,7 +2413,10 @@ if (send_alarm_->deadline() > max_deadline) { QUIC_BUG(quic_send_alarm_postponed) << "previous deadline:" << max_deadline - << ", deadline from CanWrite:" << send_alarm_->deadline(); + << ", deadline from CanWrite:" << send_alarm_->deadline() + << ", last_can_write_reason:" << last_can_write_reason_ + << ", packets_sent_on_last_successful_can_write:" + << packets_sent_on_last_successful_can_write_; QUIC_DVLOG(1) << "Send alarm restored after processing packet."; QUIC_RELOADABLE_FLAG_COUNT_N(quic_no_send_alarm_unless_necessary, 4, 7); // Restore to the previous, earlier deadline. @@ -3227,6 +3230,11 @@ return frames; } +void QuicConnection::RecordLastCanWriteReason(LastCanWriteReason reason) { + last_can_write_reason_ = reason; + packets_sent_on_last_successful_can_write_ = stats_.packets_sent; +} + bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) { if (!connected_) { return false; @@ -3252,6 +3260,9 @@ // Try to coalesce packet, only allow to write when creator is on soft max // packet length. Given the next created packet is going to fill current // coalesced packet, do not check amplification factor. + if (packet_creator_.HasSoftMaxPacketLength()) { + RecordLastCanWriteReason(LAST_CAN_WRITE_REASON_COALESCE_PACKET); + } return packet_creator_.HasSoftMaxPacketLength(); } @@ -3260,6 +3271,7 @@ // 1) firing PTO, // 2) bundling CRYPTO data with ACKs, // 3) coalescing CRYPTO data of higher space. + RecordLastCanWriteReason(LAST_CAN_WRITE_REASON_PENDING_TIMER); return true; } @@ -3282,6 +3294,7 @@ // Allow acks and probing frames to be sent immediately. if (retransmittable == NO_RETRANSMITTABLE_DATA) { + RecordLastCanWriteReason(LAST_CAN_WRITE_REASON_NO_RETRANSMITTABLE_DATA); return true; } // If the send alarm is set, wait for it to fire. @@ -3300,6 +3313,7 @@ if (!delay.IsZero()) { if (delay <= release_time_into_future_) { // Required delay is within pace time into future, send now. + RecordLastCanWriteReason(LAST_CAN_WRITE_REASON_DELAY_WITHIN_RELEASE_TIME); return true; } // Cannot send packet now because delay is too far in the future. @@ -3308,6 +3322,8 @@ << "ms"; return false; } + + RecordLastCanWriteReason(LAST_CAN_WRITE_REASON_NO_DELAY); return true; }
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h index 469e40a..0108c76 100644 --- a/quiche/quic/core/quic_connection.h +++ b/quiche/quic/core/quic_connection.h
@@ -2410,6 +2410,21 @@ // The ECN codepoint of the last packet to be sent to the writer, which // might be different from the next codepoint in per_packet_options_. QuicEcnCodepoint last_ecn_codepoint_sent_ = ECN_NOT_ECT; + + // The reason for the last call to CanWrite with a true return value. + enum LastCanWriteReason : uint8_t { + LAST_CAN_WRITE_REASON_NONE = 0, + LAST_CAN_WRITE_REASON_COALESCE_PACKET, + LAST_CAN_WRITE_REASON_PENDING_TIMER, + LAST_CAN_WRITE_REASON_NO_RETRANSMITTABLE_DATA, + LAST_CAN_WRITE_REASON_DELAY_WITHIN_RELEASE_TIME, + LAST_CAN_WRITE_REASON_NO_DELAY, + }; + void RecordLastCanWriteReason(LastCanWriteReason reason); + // TODO(b/299071230): Delete |packets_sent_on_last_successful_can_write_| and + // |last_can_write_reason_| after debugging. + LastCanWriteReason last_can_write_reason_ = LAST_CAN_WRITE_REASON_NONE; + QuicPacketCount packets_sent_on_last_successful_can_write_ = 0; }; } // namespace quic