misc/96268: TCP socket performance drops by 3000% if packets are
split at the first byte
Jost Boekemeier
jost2345 at users.sourceforge.net
Mon Apr 24 16:20:23 UTC 2006
>Number: 96268
>Category: misc
>Synopsis: TCP socket performance drops by 3000% if packets are split at the first byte
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Apr 24 16:20:22 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Jost Boekemeier
>Release: 6.0
>Organization:
>Environment:
Unknown, should be reproduceable on all FreeBSD kernels
>Description:
See test below. The test is written in java, but it it likely a kernel bug.
The time needed to complete Test#2 is independent of the architecture, for 200 iterations it needs ~20 seconds, for 40 interations ~40 seconds etc.
It is not a configuration problem, for example socket waiting for a timeout, because the similar Test#1 completes in ~1.2 seconds.
>How-To-Repeat:
import java.io.*;
import java.net.*;
import java.util.*;
public class TestServ implements Runnable {
static final int SIZE=8192;
static final int PORT=9767;
private String getID(byte[] b, int n) {
String str = (new String(b, 0, n));
//System.out.println(str);
int idx = str.lastIndexOf("=", 0); idx+=2;
int idx2= str.indexOf("\"", idx);
return str.substring(idx, idx2);
}
public void run() {
try {
doRun();
} catch (Exception e) {
e.printStackTrace();
}
}
public void doRun() throws Exception {
int n;
ServerSocket ss = new ServerSocket(PORT, 1, InetAddress.getByName("127.0.0.1"));
while(true) {
byte[] b = new byte[SIZE];
Socket s = ss.accept();
InputStream in = s.getInputStream();
in.read(b, 0, 1); //options
n = in.read(b, 0, 51);
OutputStream out = s.getOutputStream();
byte[] x = ("<N i=\""+getID(b, n)+"\"/>").getBytes();
out.write(x, 0, x.length);
s.close();
}
}
private static void runTest1() throws Exception {
for(int i=0; i<200; i++) {
Socket s = new Socket("127.0.0.1", PORT);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
out.write(("@<I v=\"0\" m=\"lastException\" p=\"P\" i=\"136070284\"></I>").getBytes());
byte[] b = new byte[1024];
in.read(b);
s.close();
}
}
// same as above, buf send two packets
private static void runTest2() throws Exception {
for(int i=0; i<200; i++) {
Socket s = new Socket("127.0.0.1", PORT);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
out.write('@');
out.write(("<I v=\"0\" m=\"lastException\" p=\"P\" i=\"136070284\"></I>").getBytes());
byte[] b = new byte[1024];
in.read(b);
s.close();
}
}
public static void main(String _s[]) throws Exception {
Thread t = new Thread(new TestServ());
t.start();
Thread.sleep(100);
long T1 = System.currentTimeMillis();
runTest1();
long T2 = System.currentTimeMillis();
runTest2();
long T3 = System.currentTimeMillis();
System.out.println("The following test demonstrates a bug in the FreeBSD 6 kernel:");
System.out.println("Both tests transfer the same amount of data.");
System.out.println("But the second test splits the packet after the first byte.");
System.out.println("Test1: "+(T2-T1));
System.out.println("Test2: "+(T3-T2));
short c = (short)((T3-T2)/(T2-T1));
System.out.println("Test2/Test1: "+c);
if(c>1) {
System.out.println("Test failed");
System.exit(1);
}
System.out.println("Test okay");
System.exit(0);
}
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list