Re: [Fwd: Re: [patch] Real-Time Preemption, -RT-2.6.9-mm1-V0.4]

From: Ingo Molnar
Date: Fri Oct 29 2004 - 03:59:48 EST



* Ingo Molnar <mingo@xxxxxxx> wrote:

> Could the kernel help some more in debugging this? E.g. if the Jackd
> SCHED_FIFO thread (after it has started up) can never legitimately
> reschedule except via poll(), i could try to put in a syscall hack in
> where in the Jackd code you could call say gettimeofday(0,3) to turn
> on 'do not reschedule' mode, and call gettimeofday(0,4) to turn it
> off. If Jackd reschedules while in 'do not reschedule' mode then the
> scheduler code will detect this and will print out the offending
> user-space EIP and a stacktrace. [and will turn off 'do-not schedule'
> mode.]

i've implemented this feature and have put it into -RT-V0.5.5 which can
be downloaded from the usual place:

http://redhat.com/~mingo/realtime-preempt/

i've attached a simple testcase showing how to use it. When running the
testcode on a -V0.5.5 kernel it gives:

saturn:~> ./rt-atomic
testing atomic mode functionality.
ok, kernel supports atomic mode.
atomic mode is now off - doing sleep(), should succeed:
turning atomic mode on.
doing getppid() syscall - should succeed.
doing sleep() syscall - should abort!
User defined signal 1

the kernel sends SIGUSR1 when it detects illegal scheduling. (change the
SIGUSR1 in the patch if you want another signal.)

could someone with more Jackd experience than me add this to the Jackd
code and check whether and where it triggers? I'd suggest to do
something like around the poll() call:

atomic_off();
poll();
atomic_on();

and add an atomic_off() to the Jackd shutdown handler (or any codepath
that is legitimately allowed to schedule).

Ingo

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

#define atomic_on() \
do { \
if (gettimeofday((void *)1,(void *)1)) { \
printf("failed: wrong kernel?\n"); \
abort(); \
} \
} while (0)

#define atomic_off() gettimeofday((void *)1,(void *)0)

int main(void)
{
printf("testing atomic mode functionality.\n");
atomic_on();
atomic_off();
printf("ok, kernel supports atomic mode.\n");

printf("atomic mode is now off - doing sleep(), should succeed:\n");
sleep(1);
printf("turning atomic mode on.\n");
atomic_on();
printf("doing getppid() syscall - should succeed.\n");
getppid();
printf("doing sleep() syscall - should abort!\n");
sleep(1);
printf("huh? got back and no signal?\n");

return 0;
}