[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: TCP wait_for transmit question



On 11 Jul 2012, at 22:06, Balraj Singh wrote:

> This is what the write buffer is supposed to do and it definitely
> improves overall performance.  It allows the app and tcp to not be in
> lock step.  The app can dump a chunk of data to be sent in the write
> buffer, when tcp gets acks that open up the window it has data ready
> to be sent.  This buffer also needed to implement Nagle's algorithm.
> 
> This is what was implemented:
> 
> When the app does a write:
> 
>    if (write buffer is not empty) {
>        if (adding pkt to buffer will make the total bytes buffered
> more than a configured max value) {
>          block till buffer becomes available, then attempt a write again

It's this above logic (blocking until the buffer becomes available) that I was
trying to spot.  The code excerpt from user_buffer.ml is:

    match Lwt_sequence.is_empty t.buffer &&
      (l = mss || not (Window.tx_inflight t.wnd)) with
    | false ->
        t.bufbytes <- Int32.add t.bufbytes l;
        List.iter (fun data -> ignore(Lwt_sequence.add_r data t.buffer)) datav;
        if t.bufbytes < mss then
          return ()
        else
          clear_buffer t

So if the buffer is not empty and we have enough, it clears the buffer.  
However,
where is the check against max_size if the amount of total buffered data 
increases
to a large amount? I can't see any path where the t.writers blocking set is 
appended
to except in the wait_for_* functions.

Haris, was your test case just calling Tcp.Pcb.write continuously and finding 
that
it ran out of memory?

In that case, it may be a regression that is the same problem as the ARP race
condition (the OS.Netif.write is now too asynchronous).

-anil


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.