RE: O(1) scheduler seems to lock up on sched_FIFO and sched_RR ta sks

Perez-Gonzalez, Inaky
2003-06-19T05:52:37Z

[-- Attachment #1: Type: text/plain, Size: 1420 bytes --]

Hi All

I have another test case that is showing this behavior.
It is very similar to George's, however, it is a simplification
of another one using threads that a co-worker, Adam Li found
a few days ago.

Parent (FIFO 5) forks child that sets itself to FIFO 4 and
busy loops, then it sleeps five seconds and kills the child.

Doing SysRq + T after a while shows the parent'd call trace
to be at sys_rt_sigaction+0xd1, that is just inside the final
copy_to_user() in signal.c:sys_rt_sigaction().

Reprioritizing events/0 to FIFO 5+ fixes the inversion.

If I call nanosleep directly (with system() instead of
glibc's sleep(), so I avoid all the rt_sig calls),
I get the parent process always stuck in work_resched+0x5,
in entry.S:work_resched, just after the call to the
scheduler - however, I cannot trace what is happening
inside the scheduler.

My point here is: I am trying to trace where this program
is making use of workqueues inside of the kernel, and I
can find none. The only place where I need to look some
more is inside the timer code, but in a quick glance,
it seems it is not being used, so why is it affected by
the reprioritization of the events/0 thread? George, can
you help me here?

kernel is 2.5.67, SMP and PREEMPT with maxcpus=1; tomorrow
I will try .72 ...

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

[-- Attachment #2: sched-hang.c --]
[-- Type: application/octet-stream, Size: 1056 bytes --]

#include <signal.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <stdio.h>
#include <time.h>

volatile int dummy;
volatile int child_run = 1;

/* #define DPRINTF(a...) fprintf(stderr, a) */
#define DPRINTF(a...) do { } while (0)

void child_signal_handler (int signum)
{
child_run = 0;
}

int main (void)
{
int child;
struct timespec tp = { 5, 0 };
struct sched_param param;
param.sched_priority = 5;
sched_setscheduler (0, SCHED_FIFO, &param);
child = fork();
switch (child)
{
case 0:
DPRINTF("Child starts\n");
signal (SIGTERM, child_signal_handler);
param.sched_priority = 4;
sched_setscheduler (0, SCHED_FIFO, &param);
for (; child_run;)
dummy = dummy + 1;
DPRINTF("Child dies\n");
break;
case -1:
perror ("fork failed");
abort();
break;
default:
/* sleep (5); */
syscall (__NR_nanosleep, &tp, NULL);
kill (child, SIGTERM);
break;
}
return 0;
}