The proper fix should be a call into the scheduler if a task unblocks,
which shouldn't be too hard to add.
I found a simple way of doing this. In schedule.c/domain_wake(), I changed
the following code slightly:
if ( is_idle_task(curr) || (min_time <= now) )
cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
This code causes the scheduler to be run if the current task is the idle
task, or if the current task has already used up its time slice. I changed
this to:
if ( is_idle_task(curr) || (min_time <= now)
|| IS_CAPABLE_PHYSDEV(d) )
cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
This causes the scheduler also to be run if the domain we are waking up is a
device domain.
The stock BVT scheduling code seems to take care of the rest. Since the
device domain tends to run relatively rarely, its virtual time is smaller,
which causes the BVT algorithm to switch to it right away.
This changes the result of my little 'dd' test to be much closer to nominal:
time dd if=/dev/hda5 bs=1024k count=11 of=/dev/null
takes 1.96s with nothing else running.
takes 2.1s with a cpu intensive domain running concurrently
took over 8s without this change.
Maybe not perfect, but way better.
Rob Gardner
HP