Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Mar 1999 13:21:14 +0100 (CET)
From:      dockes@cdkit.remcomp.fr
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/10788: TCP performance problem for command/answer application
Message-ID:  <199903251221.NAA07226@y.cdkit.remcomp.fr>

next in thread | raw e-mail | index | archive | help

>Number:         10788
>Category:       kern
>Synopsis:       Undue 400 mS delay in TCP send/receive
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 25 04:30:01 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Jean-Francois Dockes
>Release:        FreeBSD 2.2.8-STABLE i386
>Organization:
CDKIT - SAINT-CLOUD, FRANCE
>Environment:
FreeBSD 2.2.8-STABLE

>Description:

A client-server application working on a TCP connection experiences
400 mS of delay per question/answer. This happens on localhost, or on
2 machines on a fast ethernet segment.

This delay is related to the message/answer sizes. Our standard size
is 104 bytes (both for question and answer). 

The reading side does a recv() for 104 bytes, which returns 100 bytes,
so it repeats for the next 4 bytes.

Each recv() is preceded by a select(). The select() call before the 4
bytes read seems to sleep 200 mS. This happens on both the server and
client side, hence the total 400 mS delay

If the message size is reduced to 100 bytes, no delay is experienced
(yes, it occured to me that 100 is the mbuf data size...)

This problem does not happen under linux or solaris (not sure it might
not happen with different message sizes).

While I understand the idea of avoiding returning too little data from
a read, it seems to me that the hint from the first read (size 104
bytes, equal to the available data) should not be lost by the kernel. 

I first thought that the select() call was the problem because it
didn't know how much data the program actually expected, but, if no
"select()" is used, the second recv() is delayed by the same 200 mS.

>How-To-Repeat:

The description says it all, doesn't it ? Any program which does
select/recv() pairs on 104 bytes messages will experience the problem.

>Fix:
	
	User workarounds: 
		- Set TCP_NODELAY. 
		- Decrease message size below mbuf size

The kernel should not delay a read that requests less than the
available data.

In case a read is fragmented by the kernel, the residual value should
be remembered so that select() can take the hint.

I'm sorry I've not a clue about how this might be done in
practise... I understand that the delay may come from below the
syscall layer, which surely makes things more complicated.


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199903251221.NAA07226>