lkml.org 
[lkml]   [2003]   [Sep]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectBug in linux-2.6.0-test4 ?
Date
Hi all

I have an annoying problem with a network server (TCP sockets)

On some stress situation, LowMemory goes close to 0, and the whole machine
freezes.

When the sockets receive a lot of data, and the server is busy, the TCP
stack just can use too many buffers (in LowMem).

TCP stack uses "size-4096" buffers to store the datas, even if only one byte
is coming from the network.

I tried to change /proc/sys/net/ipv4/tcp_mem, without results.
# echo "1000 10000 15000" >/proc/sys/net/ipv4/tcp_mem
You can reproduce the problem with the test program attached.

# gcc -o crash crash.c
# ulimit -n 20000
# ./crash listen 8888 &
# ./crash call 127.0.0.1:8888 &
grep "size-4096 " /proc/slabinfo
size-4096 40015 40015 4096 1 1 : tunables 24 12 0 : slabdata
40015 40015 0

(thats is 160 Mo, far more than the limit given in
/proc/sys/net/ipv4/tcp_mem)

grep TCP /proc/net/sockstat
TCP: inuse 39996 orphan 0 tw 0 alloc 39997 mem 79986

What is the unit of 'mem' field ? Unless it is 2Ko, the numbers are wrong.

How may I ask the kernel NOT to use more than 'X Mo' to store TCP messages
?

Thanks

Eric Dumazet

/*
* Program to freeze a linux box, by using all the LOWMEM
* A bug on the tcp stack may be the reason
* Use at your own risk !!
*/
/* Principles :
A listener accepts incoming tcp sockets, write 40 bytes, and does nothing
with them (no reading)
A writer establish TCP sockets, sends some data (40 bytes), no more
reading/writing
*/
#include <stdio.h>
# include <sys/socket.h>
# include <netinet/tcp.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <string.h>
/*
* Usage :
* crash listen port
* crash call IP:port
*/
void usage(int code)
{
fprintf(stderr, "Usages :\n") ;
fprintf(stderr, " crash listen port\n") ;
fprintf(stderr, " crash call IP:port\n") ;
exit(code) ;
}
const char some_data[40] = "some data.... just some data" ;
void do_listener(const char *string)
{
int port = atoi(string) ;
struct sockaddr_in host, from ;
int fdlisten ;
unsigned int total ;
socklen_t fromlen ;
memset(&host,0, sizeof(host));
host.sin_family = AF_INET;
host.sin_port = htons(port);
fdlisten = socket(AF_INET, SOCK_STREAM, 0) ;
if (bind(fdlisten, (struct sockaddr *)&host, sizeof(host)) == -1) {
perror("bind") ;
return ;
}
listen(fdlisten, 10) ;
for (total=0;;total++) {
int nfd ;
fromlen = sizeof(from) ;
nfd = accept(fdlisten, (struct sockaddr *)&from, &fromlen) ;
if (nfd == -1) break ;
write(nfd, some_data, sizeof(some_data)) ;
}
printf("total=%u\n", total) ;
pause() ;
}
void do_caller(const char *string)
{
union {
int i ;
char c[4] ;
} u ;
struct sockaddr_in dest;
int a1, a2, a3, a4, port ;
unsigned int total ;
sscanf(string, "%d.%d.%d.%d:%d", &a1, &a2, &a3, &a4, &port) ;
u.c[0] = a1 ; u.c[1] = a2 ; u.c[2] = a3 ; u.c[3] = a4 ;
for (total=0;;total++) {
int fd ;
memset(&dest, 0, sizeof(dest)) ;
dest.sin_family = AF_INET ;
dest.sin_port = htons(port) ;
dest.sin_addr.s_addr = u.i ;
fd = socket(AF_INET, SOCK_STREAM, 0) ;
if (fd == -1) break ;
if (connect(fd, (struct sockaddr *)&dest, sizeof(dest)) == -1) {
perror("connect") ;
break ;
}
write(fd, some_data, sizeof(some_data)) ;
}
printf("total=%u\n", total) ;
pause() ;
}
int main(int argc, char *argv[])
{
int listener ;
int caller ;
if (argc != 3) {
usage(1);
}
listener = !strcmp(argv[1], "listen") ;
caller = !strcmp(argv[1], "call") ;
if (listener) {
do_listener(argv[2]) ;
}
else if (caller) {
do_caller(argv[2]) ;
}
else usage(2) ;
return 0 ;
}
/********************************************************************//*
* Program to freeze a linux box, by using all the LOWMEM
* A bug on the tcp stack may be the reason
* Use at your own risk !!
*/
/* Principles :
A listener accepts incoming tcp sockets, write 40 bytes, and does nothing with them (no reading)
A writer establish TCP sockets, sends some data (40 bytes), no more reading/writing
*/
#include <stdio.h>
# include <sys/socket.h>
# include <netinet/tcp.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <string.h>
/*
* Usage :
* crash listen port
* crash call IP:port
*/
void usage(int code)
{
fprintf(stderr, "Usages :\n") ;
fprintf(stderr, " crash listen port\n") ;
fprintf(stderr, " crash call IP:port\n") ;
exit(code) ;
}
const char some_data[40] = "some data.... just some data" ;
void do_listener(const char *string)
{
int port = atoi(string) ;
struct sockaddr_in host, from ;
int fdlisten ;
unsigned int total ;
socklen_t fromlen ;
memset(&host,0, sizeof(host));
host.sin_family = AF_INET;
host.sin_port = htons(port);
fdlisten = socket(AF_INET, SOCK_STREAM, 0) ;
if (bind(fdlisten, (struct sockaddr *)&host, sizeof(host)) == -1) {
perror("bind") ;
return ;
}
listen(fdlisten, 10) ;
for (total=0;;total++) {
int nfd ;
fromlen = sizeof(from) ;
nfd = accept(fdlisten, (struct sockaddr *)&from, &fromlen) ;
if (nfd == -1) break ;
write(nfd, some_data, sizeof(some_data)) ;
}
printf("total=%u\n", total) ;
pause() ;
}
void do_caller(const char *string)
{
union {
int i ;
char c[4] ;
} u ;
struct sockaddr_in dest;
int a1, a2, a3, a4, port ;
unsigned int total ;
sscanf(string, "%d.%d.%d.%d:%d", &a1, &a2, &a3, &a4, &port) ;
u.c[0] = a1 ; u.c[1] = a2 ; u.c[2] = a3 ; u.c[3] = a4 ;
for (total=0;;total++) {
int fd ;
memset(&dest, 0, sizeof(dest)) ;
dest.sin_family = AF_INET ;
dest.sin_port = htons(port) ;
dest.sin_addr.s_addr = u.i ;
fd = socket(AF_INET, SOCK_STREAM, 0) ;
if (fd == -1) break ;
if (connect(fd, (struct sockaddr *)&dest, sizeof(dest)) == -1) {
perror("connect") ;
break ;
}
write(fd, some_data, sizeof(some_data)) ;
}
printf("total=%u\n", total) ;
pause() ;
}
int main(int argc, char *argv[])
{
int listener ;
int caller ;
if (argc != 3) {
usage(1);
}
listener = !strcmp(argv[1], "listen") ;
caller = !strcmp(argv[1], "call") ;
if (listener) {
do_listener(argv[2]) ;
}
else if (caller) {
do_caller(argv[2]) ;
}
else usage(2) ;
return 0 ;
}
/********************************************************************/
\
 
 \ /
  Last update: 2005-03-22 13:48    [from the cache]
©2003-2011 Jasper Spaans. Advertise on this site