mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
kernel: don't sched() for clock interrupt when up->state != Running
When we get a clock interrupt, we should not call sched() when the process is not in "Running" state as it is already committed to call sched() itself. (An example is qlock(), just after the unlock() call). As this is basically the same check as done in preempted(), unify both and add a "clockintr" argument to preempted(). Then most trap handlers just become: preempted(irq()); Also, we do not want to call preempted() for traps, as the trap handler has just setup some machine state to resolve the trap. We can wait for the clock interrupt if we really need the preempt.
This commit is contained in:
parent
02015f69f6
commit
29e9c7bf01
14 changed files with 30 additions and 112 deletions
|
@ -124,10 +124,7 @@ trap(Ureg *ureg)
|
|||
case 0x00: // unknown
|
||||
if(intr == 1){
|
||||
f = fpukenter(ureg);
|
||||
if(!irq(ureg))
|
||||
preempted();
|
||||
else if(up != nil && up->delaysched)
|
||||
sched();
|
||||
preempted(irq(ureg));
|
||||
break;
|
||||
}
|
||||
if(intr == 3){
|
||||
|
|
|
@ -166,10 +166,7 @@ trap(Ureg *ureg)
|
|||
ureg->psr & PsrMask);
|
||||
break;
|
||||
case PsrMirq:
|
||||
if(!irq(ureg))
|
||||
preempted();
|
||||
else if(up != nil && up->delaysched)
|
||||
sched(); /* can cause more traps */
|
||||
preempted(irq(ureg));
|
||||
break;
|
||||
case PsrMabt: /* prefetch fault */
|
||||
x = ifsrget();
|
||||
|
|
|
@ -109,13 +109,5 @@ intr(Ureg *ureg)
|
|||
i->f(ureg, i->arg);
|
||||
mpcore[ICCEOIR] = v;
|
||||
|
||||
if(up != nil){
|
||||
if(irq == TIMERIRQ){
|
||||
if(up->delaysched){
|
||||
splhi();
|
||||
sched();
|
||||
}
|
||||
}else
|
||||
preempted();
|
||||
}
|
||||
preempted(irq == TIMERIRQ);
|
||||
}
|
||||
|
|
|
@ -391,15 +391,9 @@ trap(Ureg *ureg)
|
|||
panic("unknown trap %ld", ureg->type);
|
||||
break;
|
||||
case PsrMirq:
|
||||
ldrexvalid = 0;
|
||||
// splflo(); /* allow fast interrupts */
|
||||
if(!intrs(ureg, Irqlo))
|
||||
preempted();
|
||||
else if(up != nil && up->delaysched){
|
||||
ldrexvalid = 0;
|
||||
sched();
|
||||
}
|
||||
m->intr++;
|
||||
ldrexvalid = 0;
|
||||
preempted(intrs(ureg, Irqlo));
|
||||
break;
|
||||
case PsrMabt: /* prefetch fault */
|
||||
ldrexvalid = 0;
|
||||
|
|
|
@ -221,12 +221,6 @@ intr(Ureg* ur)
|
|||
if(cause != 0)
|
||||
iprint("unhandled interrupts %lux\n", cause);
|
||||
|
||||
|
||||
|
||||
/* preemptive scheduling */
|
||||
if(up != nil && !clockintr)
|
||||
preempted();
|
||||
/* if it was a clockintr, sched will be called at end of trap() */
|
||||
return clockintr;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ kvce(Ureg *ur, int ecode)
|
|||
void
|
||||
trap(Ureg *ur)
|
||||
{
|
||||
int ecode, clockintr, user, cop, x, fpchk;
|
||||
int ecode, user, cop, x, fpchk;
|
||||
ulong fpfcr31;
|
||||
char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
|
||||
static int dumps;
|
||||
|
@ -170,10 +170,9 @@ trap(Ureg *ur)
|
|||
panic("trap: tlb shutdown");
|
||||
ecode = (ur->cause>>2)&EXCMASK;
|
||||
fpchk = 0;
|
||||
clockintr = 0;
|
||||
switch(ecode){
|
||||
case CINT:
|
||||
clockintr = intr(ur);
|
||||
preempted(intr(ur));
|
||||
break;
|
||||
|
||||
case CFPE:
|
||||
|
@ -260,12 +259,6 @@ trap(Ureg *ur)
|
|||
|
||||
splhi();
|
||||
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up && up->delaysched && clockintr){
|
||||
sched();
|
||||
splhi();
|
||||
}
|
||||
|
||||
if(user){
|
||||
notify(ur);
|
||||
/* replicate fpstate to ureg status */
|
||||
|
|
|
@ -223,9 +223,11 @@ trap(Ureg *ureg)
|
|||
switch(ecode) {
|
||||
case CEI:
|
||||
intr(ureg);
|
||||
preempted(0);
|
||||
break;
|
||||
case CDEC:
|
||||
clockintr(ureg);
|
||||
preempted(1);
|
||||
break;
|
||||
case CSYSCALL:
|
||||
if(!user)
|
||||
|
@ -295,12 +297,6 @@ trap(Ureg *ureg)
|
|||
/* restoreureg must execute at high IPL */
|
||||
splhi();
|
||||
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up && up->delaysched && ecode == CDEC){
|
||||
sched();
|
||||
splhi();
|
||||
}
|
||||
|
||||
if(user) {
|
||||
notify(ureg);
|
||||
if(up->fpstate == FPinactive)
|
||||
|
@ -391,9 +387,6 @@ intr(Ureg *ureg)
|
|||
}
|
||||
if(ctl->eoi)
|
||||
ctl->eoi(vno);
|
||||
|
||||
if(up)
|
||||
preempted();
|
||||
}
|
||||
|
||||
char*
|
||||
|
|
|
@ -482,12 +482,7 @@ trap(Ureg *ureg)
|
|||
break;
|
||||
case PsrMirq:
|
||||
ldrexvalid = 0;
|
||||
if(!irq(ureg))
|
||||
preempted();
|
||||
else if(up != nil && up->delaysched){
|
||||
ldrexvalid = 0;
|
||||
sched();
|
||||
}
|
||||
preempted(irq(ureg));
|
||||
m->intr++;
|
||||
break;
|
||||
case PsrMabt: /* prefetch fault */
|
||||
|
|
|
@ -63,16 +63,7 @@ irqhandled(Ureg *ureg, int vno)
|
|||
if(ctl->eoi != nil)
|
||||
(*ctl->eoi)(vno);
|
||||
intrtime(m, vno);
|
||||
|
||||
if(up != nil){
|
||||
if(ctl == vclock){
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up->delaysched)
|
||||
sched();
|
||||
} else {
|
||||
preempted();
|
||||
}
|
||||
}
|
||||
preempted(ctl == vclock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -252,24 +252,23 @@ hzsched(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* here at the end of non-clock interrupts to see if we should preempt the
|
||||
* current process. Returns 1 if preempted, 0 otherwise.
|
||||
* here at the end of interrupts to see if we should preempt the
|
||||
* current process.
|
||||
*/
|
||||
int
|
||||
preempted(void)
|
||||
void
|
||||
preempted(int clockintr)
|
||||
{
|
||||
if(up != nil && up->state == Running)
|
||||
if(up->preempted == 0)
|
||||
if(anyhigher())
|
||||
if(!active.exiting){
|
||||
if(up == nil || up->state != Running || active.exiting)
|
||||
return;
|
||||
if(!clockintr){
|
||||
if(up->preempted || !anyhigher())
|
||||
return;
|
||||
m->readied = nil; /* avoid cooperative scheduling */
|
||||
up->preempted = 1;
|
||||
sched();
|
||||
splhi();
|
||||
up->preempted = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else if(up->delaysched)
|
||||
sched(); /* quantum ended or we held a lock */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -155,9 +155,11 @@ trap(Ureg *ureg)
|
|||
case CEI:
|
||||
m->intr++;
|
||||
intr(ureg);
|
||||
preempted(0);
|
||||
break;
|
||||
case CDEC:
|
||||
clockintr(ureg);
|
||||
preempted(1);
|
||||
break;
|
||||
case CDSI:
|
||||
m->pfault++;
|
||||
|
@ -279,12 +281,6 @@ trap(Ureg *ureg)
|
|||
/* restoreureg must execute at high IPL */
|
||||
splhi();
|
||||
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up && up->delaysched && ecode == CDEC){
|
||||
sched();
|
||||
splhi();
|
||||
}
|
||||
|
||||
if(user) {
|
||||
if (up->fpstate == FPactive && (ureg->srr1 & MSR_FP) == 0){
|
||||
postnote(up, 1, buf, NDebug);
|
||||
|
|
|
@ -155,7 +155,7 @@ kvce(Ureg *ur, int ecode)
|
|||
void
|
||||
trap(Ureg *ur)
|
||||
{
|
||||
int ecode, clockintr, user, cop, x, fpchk;
|
||||
int ecode, user, cop, x, fpchk;
|
||||
ulong fpfcr31;
|
||||
char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
|
||||
static int dumps;
|
||||
|
@ -178,10 +178,9 @@ trap(Ureg *ur)
|
|||
panic("trap: tlb shutdown");
|
||||
ecode = (ur->cause>>2)&EXCMASK;
|
||||
fpchk = 0;
|
||||
clockintr = 0;
|
||||
switch(ecode){
|
||||
case CINT:
|
||||
clockintr = intr(ur);
|
||||
preempted(intr(ur));
|
||||
break;
|
||||
|
||||
case CFPE:
|
||||
|
@ -276,12 +275,6 @@ trap(Ureg *ur)
|
|||
|
||||
splhi();
|
||||
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up && up->delaysched && clockintr){
|
||||
sched();
|
||||
splhi();
|
||||
}
|
||||
|
||||
if(user){
|
||||
notify(ur);
|
||||
/* replicate fpstate to ureg status */
|
||||
|
@ -357,10 +350,6 @@ intr(Ureg *ur)
|
|||
if(cause != 0)
|
||||
iprint("unhandled interrupts %lux\n", cause);
|
||||
|
||||
/* preemptive scheduling */
|
||||
if(up != nil && !clockintr)
|
||||
preempted();
|
||||
/* if it was a clockintr, sched will be called at end of trap() */
|
||||
return clockintr;
|
||||
}
|
||||
|
||||
|
|
|
@ -637,6 +637,7 @@ irq(Ureg* ureg)
|
|||
Intrcpuregs *icp = (Intrcpuregs *)soc.intr;
|
||||
Vctl *v;
|
||||
|
||||
m->intr++;
|
||||
ticks = perfticks();
|
||||
handled = 0;
|
||||
ack = intack(icp);
|
||||
|
@ -814,7 +815,7 @@ datafault(Ureg *ureg, int user)
|
|||
void
|
||||
trap(Ureg *ureg)
|
||||
{
|
||||
int clockintr, user, rem;
|
||||
int user, rem;
|
||||
uintptr va, ifar, ifsr;
|
||||
|
||||
splhi(); /* paranoia */
|
||||
|
@ -841,17 +842,13 @@ trap(Ureg *ureg)
|
|||
else
|
||||
ureg->pc -= 4;
|
||||
|
||||
clockintr = 0; /* if set, may call sched() before return */
|
||||
switch(ureg->type){
|
||||
default:
|
||||
panic("unknown trap; type %#lux, psr mode %#lux", ureg->type,
|
||||
ureg->psr & PsrMask);
|
||||
break;
|
||||
case PsrMirq:
|
||||
m->intr++;
|
||||
clockintr = irq(ureg);
|
||||
if(0 && up && !clockintr)
|
||||
preempted(); /* this causes spurious suicides */
|
||||
preempted(irq(ureg));
|
||||
break;
|
||||
case PsrMabt: /* prefetch (instruction) fault */
|
||||
va = ureg->pc;
|
||||
|
@ -908,12 +905,6 @@ trap(Ureg *ureg)
|
|||
}
|
||||
splhi();
|
||||
|
||||
/* delaysched set because we held a lock or because our quantum ended */
|
||||
if(up && up->delaysched && clockintr){
|
||||
sched(); /* can cause more traps */
|
||||
splhi();
|
||||
}
|
||||
|
||||
if(user){
|
||||
if(up->procctl || up->nnote)
|
||||
notify(ureg);
|
||||
|
|
|
@ -182,10 +182,7 @@ trap(Ureg *ureg)
|
|||
break;
|
||||
case PsrMirq:
|
||||
ureg->pc -= 4;
|
||||
if(!intr(ureg))
|
||||
preempted();
|
||||
else if(up != nil && up->delaysched)
|
||||
sched();
|
||||
preempted(intr(ureg));
|
||||
break;
|
||||
default:
|
||||
iprint("cpu%d: unknown trap type %ulx\n", m->machno, ureg->type);
|
||||
|
|
Loading…
Reference in a new issue