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

Re: [microblaze-uclinux] Heavy packet load and the sigaction..



John,
Not sure this point will be of any use. Only if the signal handler is
registered in the same program that receives huge packets i get into
this problem. If one program receives the packet and other one runs
its own signal handler periodically, i couldn't reproduce the problem.

I have attached the simple(dirty test code pktread.c) running in the
box that reproduced this behaviour. pktblast.c that runs from the PC
simple sends a bunch of udp packet to the box.

(PS: The whole stuff came from one of my program relying on a one sec
signal. Now i have changed the design little bit so as not to use the
signal handler. This is just a temporary fix now so that i can proceed
further.).

Thanx for supporting.
- Prasad


On 11/16/06, Prasad <ndprasad@xxxxxxxxx> wrote:
Yes, this is a regular pattern. As soon as i kill the test code and
re-run it, it comes ok for few secs under heavy load and the first
occurence of calling signal handler in the IRQ context, i start to
observe the signal handler running with the interrupts disabled.

(PS: I used setitimer to start a periodic timer. I tried with both
sigaction/signal to register for  function to capture the SIGALRM.
Both behaves identically)

- prasad


On 11/16/06, John Williams <jwilliams@xxxxxxxxxxxxxx> wrote:
> Hi Prasad,
>
> Prasad wrote:
>
> > ==================================================
> >  /* Signal handler args: */
> >    regs->gpr[GPR_ARG0] = signal; /* Arg 0: signum */
> >    regs->gpr[GPR_ARG1] = &frame->sc; /* arg 1: sigcontext */
> >
> >   __asm__ __volatile__("mfs %0, rmsr; nop;" : "=r" (flags));
> >
> >    printk ("inside do_signal: are 0x%08x\n", flags);
> >    regs->pc = ((unsigned long)ka->sa.sa_handler);
> > ===================================================
> >
> > and the output i got is this when i send  a packet burst..
> > =======================================================
> > inside setup_frame: are 0x000000aa
> > flags are 0x000000a2
> > inside setup_frame: are 0x000000aa
> > flags are 0x000000a2
> > inside setup_frame: are 0x000000aa
> > flags are 0x000000a2
> > inside setup_frame: are 0x000000aa
>
> 0xaa shows BIP and EI are set - setup_frame is called during a syscall (brki)
> context.
>
> > flags are 0x000000a2
> > inside setup_frame: are 0x000000a2
>
> 0xa2 means BIP is not set - we are in IRQ context.
>
> > flags are 0x000000a2
> > inside setup_frame: are 0x000000aa
> > flags are 0x000000a0
> > inside setup_frame: are 0x000000aa
> > flags are 0x000000a0
>
> This is interesting, it's like the first time the sighandler runs after
> setup_frame occurs in IRQ context, it's fine.  Then the next time after
> setup_frame runs in syscall context, the handler runs with interrupts disabled.
>
> Is this a regular pattern?
>
> > I am not sure whether this points to something significant to debug.
> > If so, please let me know what else i can debug.
>
> A useful thing you can do is try to identify any patterns in sequences like
> above.  Unfortunately I won't have any time to look at this until next week at
> the earliest, so the clearer picture you can give me on what's going on, the
> better it will be when I do get to it.
>
> Cheers,
>
> John
>
> ___________________________
> microblaze-uclinux mailing list
> microblaze-uclinux@xxxxxxxxxxxxxx
> Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
> Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/
>
>

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>


unsigned char buf[1000];
unsigned int secs;

int main(int argc, char *argv[])
{
     struct sockaddr_in si_other;
    int s, i, slen=sizeof(si_other);
	int ret;
	unsigned int count = 0;
    fd_set  fdset;
    struct timeval tvout;

	SignalInit ();

    if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
	{
        perror("socket");
		return;
	}

    memset((char *) &si_other, sizeof(si_other), 0);
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(5555);
    si_other.sin_addr.s_addr = htonl(INADDR_ANY);

     if (bind(s, &si_other, sizeof(si_other))==-1)
        perror("bind");
                                                                               
    FD_ZERO(&fdset);

    while (1)
    {

  /* time out is 10 Sec */
    tvout.tv_sec = 10;
    tvout.tv_usec = 0;

     FD_SET(s, &fdset);
     ret = select(s +1, &fdset, (fd_set *)NULL, (fd_set *)NULL,(struct timeval *)&tvout);

    if ((ret = recv(s, buf, sizeof(buf), 0)) == -1)
    {
#if 0
            perror("recv()");
			if (ret != EINTR)
			  exit (1);
#endif
			continue;
    }

	//printf ("receved packets\n");
    if ((ret = sendto(s, buf, sizeof(buf),0, (struct sockaddr *) &si_other, sizeof(si_other))) == -1)
	{
		if (ret != EINTR)
			perror ("send()");
	}
	//printf ("Sending packets\n");

	count++;
	if (!(count % 0x1000))
			printf ("recv %d secs %d\n", ret, secs);
   }

   close (s);
}
 

void alarming (int sig)
{
	int flags;
	unsigned int count;

	__asm__ __volatile__("mfs %0, rmsr; nop;" : "=r" (flags));

	printf ("flags are 0x%08x\n", flags);
	
	secs++;

	for (count=0; count<100000000; count++);
}


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


struct itimerval itimer;

int SignalInit (void)
{
#if 1
   struct sigaction vec;
   struct sigaction ovec;
 
	itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 1;
    itimer.it_interval.tv_usec = itimer.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);

                                                                                     
    vec.sa_handler = alarming;
    sigemptyset(&vec.sa_mask);
    vec.sa_flags = 0;

    if (sigaction(SIGALRM, &vec, &ovec) == -1)
	{
		perror ("sigaction");
		return 1;
	}
	return 0;
#else
   struct sigaction vec;
   struct sigaction ovec;
 
	itimer.it_interval.tv_sec = 1;
    itimer.it_interval.tv_usec = 0;
	itimer.it_value.tv_sec = 1;
	itimer.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
 
    if (SIG_ERR == signal(SIGALRM, alarming)) {
       perror("signal");
        exit(1);
	}

	return 0;
#endif
}


#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>


unsigned char buf[1000];
int main(int argc, char *argv[])
{
     struct sockaddr_in si_other;
    int s, i, slen=sizeof(si_other);

    if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
                perror("socket");

    memset((char *) &si_other, sizeof(si_other), 0);
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(5555);

    if (inet_aton("10.1.2.13", &si_other.sin_addr)==0) {
             printf(stderr, "inet_aton() failed\n");
            exit(1);
    }

    if (connect (s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0)
    {
       perror ("connect");
    }

    while (1)
    {
    if (send(s, buf, sizeof(buf), 0)==-1)
    {
//            perror("sendto()");
    }
   }

     close (s);
}