Re: [PATCH 0/4] pending scheduler updates

From: Mike Galbraith
Date: Wed Oct 22 2008 - 06:03:56 EST


On Wed, 2008-10-22 at 11:40 +0200, Ingo Molnar wrote:
> * Srivatsa Vaddagiri <vatsa@xxxxxxxxxx> wrote:
>
> > On Mon, Oct 20, 2008 at 02:05:38PM +0200, Ingo Molnar wrote:
> > >
> > > * Peter Zijlstra <a.p.zijlstra@xxxxxxxxx> wrote:
> > >
> > > > Please apply
> > >
> > > applied these to tip/sched/urgent:
> > >
> > > f9c0b09: sched: revert back to per-rq vruntime
> > > a4c2f00: sched: fair scheduler should not resched rt tasks
> > > ffda12a: sched: optimize group load balancer
> > >
> > > (will wait with 4/4 until you and Mike come to a verdict.)
> >
> > Is there any conclusion on Patch 4/4? It looks sane to me!
>
> Mike?

Your call of course, but I don't think it's a good trade. In testing,
it does serious injury to mysql+oltp peak throughput, and slows down
things which need frequent preemption in order to compete effectively
against hogs. (includes desktop, though that's not heavily tested)

The attached starvation testcase, distilled from real app and posted to
lkml a few years ago, it totally kills. It's a worst case scenario to
be sure, but that worst case is pretty dramatic. I guesstimated it
would take ~12 hours for it to do 10M signals with wakeup preemption so
restricted, vs 43 seconds with preemption as is. To me, that suggests
that anything ultra fast/light will pay through the nose.

It has positive effects too, but IMHO, the bad outweigh the good.

-Mike
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/wait.h>

volatile unsigned long loop = 10000000;

void
handler (int n)
{
if (loop > 0)
--loop;
}

static int
child (void)
{
pid_t ppid = getppid ();

sleep (1);
while (1)
kill (ppid, SIGUSR1);
return 0;
}

int
main (int argc, char **argv)
{
pid_t child_pid;
int r;

loop = argc > 1 ? strtoul (argv[1], NULL, 10) : 10000000;
printf ("expecting to receive %lu signals\n", loop);

if ((child_pid = fork ()) == 0)
exit (child ());

signal (SIGUSR1, handler);
while (loop)
sleep (1);
r = kill (child_pid, SIGTERM);
waitpid (child_pid, NULL, 0);
return 0;
}