mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-12 04:13:55 +00:00
tcp_out rto: delay re-transmission earlier if link writes are deferred.
There is already a guard in tcp_output_segment() for a pbuf still being referenced by the netif driver due to deferred transmission, however the callers are modifying state even when this gives up. It seems cleaner to have the callers guard this case and avoid modifying their state. tcp_rexmit_rto() might better avoid re-transmission of any segments if any of the unacked segments are deferred, to avoid loading the link further if it is struggling to flush its buffered writes. Link level queues can be limited on some devices and need spares for link management.
This commit is contained in:
parent
902d393aef
commit
6a01607004
@ -1523,6 +1523,16 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Give up if any of the segment pbufs are still referenced by the netif
|
||||||
|
driver due to deferred transmission. No point loading the link further if
|
||||||
|
it is struggling to flush its buffered writes. */
|
||||||
|
for (seg = pcb->unacked; seg != NULL; seg = seg->next) {
|
||||||
|
if (seg->p->ref != 1) {
|
||||||
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto busy\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Move all unacked segments to the head of the unsent queue */
|
/* Move all unacked segments to the head of the unsent queue */
|
||||||
for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
|
for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
|
||||||
/* concatenate unsent queue after unacked queue */
|
/* concatenate unsent queue after unacked queue */
|
||||||
@ -1572,9 +1582,17 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seg = pcb->unacked;
|
||||||
|
|
||||||
|
/* Give up if the first segment pbuf is still referenced by the netif driver
|
||||||
|
due to deferred transmission. */
|
||||||
|
if (seg->p->ref != 1) {
|
||||||
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Move the first unacked segment to the unsent queue */
|
/* Move the first unacked segment to the unsent queue */
|
||||||
/* Keep the unsent queue sorted. */
|
/* Keep the unsent queue sorted. */
|
||||||
seg = pcb->unacked;
|
|
||||||
pcb->unacked = seg->next;
|
pcb->unacked = seg->next;
|
||||||
|
|
||||||
cur_seg = &(pcb->unsent);
|
cur_seg = &(pcb->unsent);
|
||||||
@ -1614,6 +1632,13 @@ void
|
|||||||
tcp_rexmit_fast(struct tcp_pcb *pcb)
|
tcp_rexmit_fast(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
|
if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
|
||||||
|
/* Give up if the first segment pbuf is still referenced by the netif driver
|
||||||
|
due to deferred transmission. */
|
||||||
|
if (pcb->unacked->p->ref != 1) {
|
||||||
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_fast busy\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||||
LWIP_DEBUGF(TCP_FR_DEBUG,
|
LWIP_DEBUGF(TCP_FR_DEBUG,
|
||||||
("tcp_receive: dupacks %"U16_F" (%"U32_F
|
("tcp_receive: dupacks %"U16_F" (%"U32_F
|
||||||
|
Loading…
x
Reference in New Issue
Block a user