<div dir="ltr">No love? We've been sitting with this patch on top of our iPXE source. It's pretty heinous.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 4, 2014 at 4:02 PM, Steven Haber <span dir="ltr"><<a href="mailto:steven@qumulo.com" target="_blank">steven@qumulo.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<br>
As the subject states, I'm seeing a situation where the TCP window<br>
shrink logic causes a connection to be throttled indefinitely. I am<br>
downloading a ~600MB ISO image from an internal server using iPXE's<br>
HTTP capabilities. Intermittently I will see the download slow to a<br>
crawl. A packet capture shows the receive side decreasing the TCP<br>
window drastically and permanently, from a reasonable size of ~150k<br>
down to 1k. I can send the capture to you if it'd be useful. The<br>
responsible code lives in src/net/tcp.c:tcp_discard. Below is a patch<br>
that remedies the issue. Obviously this is hack. The correct solution<br>
might involve capping the maximum window size decrease per discard,<br>
and adding complimentary window size increase code to the main rx<br>
path. This way slowdowns wouldn't be as severe and we could recover<br>
from them.<br>
<br>
What do you think? Thanks!<br>
<br>
Steven Haber<br>
Software Engineer<br>
Qumulo, Inc.<br>
<br>
<br>
<br>
<br>
<br>
diff --git a/src/net/tcp.c b/src/net/tcp.c<br>
index 987cb63..3c59e46 100644<br>
--- a/src/net/tcp.c<br>
+++ b/src/net/tcp.c<br>
@@ -1331,31 +1331,31 @@ static unsigned int tcp_discard ( void ) {<br>
        struct tcp_rx_queued_header *tcpqhdr;<br>
        uint32_t max_win;<br>
        unsigned int discarded = 0;<br>
<br>
        /* Try to drop one queued RX packet from each connection */<br>
        list_for_each_entry ( tcp, &tcp_conns, list ) {<br>
                list_for_each_entry_reverse ( iobuf, &tcp->rx_queue, list ) {<br>
<br>
                        /* Limit window to prevent future discards */<br>
                        tcpqhdr = iobuf->data;<br>
                        max_win = ( tcpqhdr->seq - tcp->rcv_ack );<br>
                        if ( max_win < tcp->max_rcv_win ) {<br>
                                DBGC ( tcp, "TCP %p reducing maximum window "<br>
                                       "from %d to %d\n",<br>
                                       tcp, tcp->max_rcv_win, max_win );<br>
-                               tcp->max_rcv_win = max_win;<br>
+                               //tcp->max_rcv_win = max_win;<br>
                        }<br>
<br>
                        /* Remove packet from queue */<br>
                        list_del ( &iobuf->list );<br>
                        free_iob ( iobuf );<br>
<br>
                        /* Report discard */<br>
                        discarded++;<br>
                        break;<br>
                }<br>
        }<br>
<br>
        return discarded;<br>
 }<br>
</blockquote></div><br></div>