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

Re: Kernel oops with highly loaded links



jamal wrote:
> 
> Please post your script to see if other people can reproduce the problem.
> Provide details of your test setup.
> 
> cheers
> jamal


Here are the details of my test setup.

Computer A and computer B are conneced via a serial PPP link. Both
computers are running linux 2.2.10 with Diffserv 6.

A ----------------------- B
10.0.0.1                  10.0.0.2

On pc B PPP is started with:
pppd /dev/ttyS0 115200 noauth nopcomp novj passive 10.0.0.2:10.0.0.1
On pc A PPP is started with:
pppd /dev/ttyS0 115200 noauth nopcomp novj 10.0.0.1:10.0.0.2

When the PPP link is established I start the following script. Note that
it's not finished, but this is enough to reproduce the error.
--------------------------------------------------------------
#!/bin/bash
tc qdisc del dev ppp0 root

tc qdisc add dev ppp0 handle 1:0 root cbq bandwidth 115kbit allot 1514
cell 8 avpkt 1000 mpu 64
tc class add dev ppp0 parent 1:0 classid 1:1 cbq bandwidth 115kbit rate
55kbit allot 1514 cell 8 avpkt 1000 weight 2kbit maxburst 20 mpu 64 prio
1
tc class add dev ppp0 parent 1:0 classid 1:2 cbq bandwidth 115kbit rate
55kbit allot 1514 cell 8 avpkt 1000 weight 2kbit maxburst 20 mpu 64 prio
2

tc filter add dev ppp0 parent 1:0 protocol ip prio 1 u32 divisor 1
tc filter add dev ppp0 parent 1:0 protocol ip prio 1 u32 match ip dport
0x9 0xffff flowid 1:1

tc qdisc add dev ppp0 handle 2:0 parent ${NR}1:1 dsmark indices 4
set_tc_index

#tc class change dev ppp0 parent 2:0 classid ${NR}2:1 dsmark mask 0x3
value 0xb8
#tc class change dev ppp0 parent 2:0 classid ${NR}2:2 dsmark mask 0x3
value 0x00

tc -s qdisc
--------------------------------------------------------------

After that I start my "no mercy" traffic generator on PC A. This traffic
generator will send UDP messages to the discard port of PC B and can
generate a lot of traffic to make the link real congested.

udper 10.0.0.2 -t 1 -s 65000

In a short amount of time the system crashes.

I didn't got a system crash with TCP streams, but with the traffic
generator it's easy to crash the system. It was also possible to crash
the system when the traffic generator is running on another host and the
high volume traffic is routed through the PPP link.

cheers
Marco

--------------------------------------------------------------
/*
 * udper.c	Udp traffic generator (works also on IPv6)
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Author:	Marco.van.der.vlugt, <van.der.vlugt@fel.tno.nl>
 */


#include <unistd.h>
#include <stdio.h>

#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdio.h>

#include <sys/signal.h>
#include <sys/time.h>

void sender();

int sock;
long nr_send;
int size = 1000;
char packet[70000];
struct addrinfo *res;
long count = -1;

int
main(argc, argv)
	int argc;
	char **argv;
{
	int ch;
	long time = 1000000;
	char fill = 0;
	char* hostname;
	
	int error;
	struct addrinfo hints;


	struct itimerval t_set;

	struct timeval old_t;
	struct timeval new_t;


	while ((ch = getopt(argc, argv, "t:s:c:f:")) != EOF) {
		switch(ch) {
		case 't':
			time = atol(optarg) * 1000; 
			break;
		case 's':
			size = atol(optarg); 
			break;
		case 'c':
			count = atol(optarg); 
			break;
		case 'f':
			fill = atoi(optarg); 
			break;
		default:
			fprintf(stderr,
			    "usage: udper [-t time] [-s size] [-c count] [-f fill]
hostname\n");
			exit(1);
		}
	}
	
	if(optind < argc)
		hostname = argv[optind];
	else {
		fprintf(stderr,
		    "usage: udper [-t time] [-s size] [-c count] [-f fill]
hostname\n");
		exit(1);
	}
	

	memset(&hints, 0, sizeof(hints));

	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	error = getaddrinfo(hostname, "discard", &hints, &res);
	if (error) {
		perror(gai_strerror(error));
		exit(1);
	}


	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if(sock == -1) {
		perror("socket");
		exit(1);
	}

	memset(packet, fill, sizeof(packet));

	nr_send = 0;

	printf("Sending packets to %s size %d time %d msec\n", hostname, size,
time / 1000);
	printf("Bitrate (only data): %.1e bps\n", size * 1000000.0 / time);
	signal(SIGALRM, sender);

	memset(&t_set, 0, sizeof(t_set));
	t_set.it_interval.tv_usec = time;
	t_set.it_value.tv_usec = time;

	if(setitimer(ITIMER_REAL, &t_set, NULL)) {
		perror("setitimer");
		exit(1);
	}

	while(1) {
		old_t = new_t;
		printf("Send packet: %d\n", nr_send);
	
		while(old_t.tv_sec == new_t.tv_sec) 
			gettimeofday(&new_t, NULL);
	}
	return (0);

}

void sender()
{
	if(sendto(sock, packet, size, 0, res->ai_addr, res->ai_addrlen) == -1)
{
		perror("sendto");
		exit(1);
	}
	nr_send++;

	if((nr_send >= count) && (count != -1))
		exit(0);
}