summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2024-01-04 04:33:29 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2024-01-04 04:33:29 +0000
commit29e9c7bf0110eac1747e6a0d65a1cff5a6857454 (patch)
tree4be5ee78f45054627ba091771d6942e910d30ee5
parent02015f69f6cf7630015f26b349076fe7b9e76de1 (diff)
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.
-rw-r--r--sys/src/9/arm64/trap.c5
-rw-r--r--sys/src/9/bcm/trap.c5
-rw-r--r--sys/src/9/cycv/intr.c10
-rw-r--r--sys/src/9/kw/trap.c10
-rw-r--r--sys/src/9/mt7688/irq.c6
-rw-r--r--sys/src/9/mt7688/trap.c11
-rw-r--r--sys/src/9/mtx/trap.c11
-rw-r--r--sys/src/9/omap/trap.c7
-rw-r--r--sys/src/9/pc/irq.c11
-rw-r--r--sys/src/9/port/proc.c23
-rw-r--r--sys/src/9/ppc/trap.c8
-rw-r--r--sys/src/9/sgi/trap.c15
-rw-r--r--sys/src/9/teg2/trap.c15
-rw-r--r--sys/src/9/zynq/trap.c5
14 files changed, 30 insertions, 112 deletions
diff --git a/sys/src/9/arm64/trap.c b/sys/src/9/arm64/trap.c
index b902a49fc..25de55ccc 100644
--- a/sys/src/9/arm64/trap.c
+++ b/sys/src/9/arm64/trap.c
@@ -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){
diff --git a/sys/src/9/bcm/trap.c b/sys/src/9/bcm/trap.c
index ff90725fc..063eb7036 100644
--- a/sys/src/9/bcm/trap.c
+++ b/sys/src/9/bcm/trap.c
@@ -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();
diff --git a/sys/src/9/cycv/intr.c b/sys/src/9/cycv/intr.c
index 45a68f9ab..2f64ec243 100644
--- a/sys/src/9/cycv/intr.c
+++ b/sys/src/9/cycv/intr.c
@@ -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);
}
diff --git a/sys/src/9/kw/trap.c b/sys/src/9/kw/trap.c
index f17c010ee..f713e7926 100644
--- a/sys/src/9/kw/trap.c
+++ b/sys/src/9/kw/trap.c
@@ -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;
diff --git a/sys/src/9/mt7688/irq.c b/sys/src/9/mt7688/irq.c
index 8d588c2c2..da2d6839a 100644
--- a/sys/src/9/mt7688/irq.c
+++ b/sys/src/9/mt7688/irq.c
@@ -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;
}
diff --git a/sys/src/9/mt7688/trap.c b/sys/src/9/mt7688/trap.c
index 84de8c3d1..c3397aed6 100644
--- a/sys/src/9/mt7688/trap.c
+++ b/sys/src/9/mt7688/trap.c
@@ -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 */
diff --git a/sys/src/9/mtx/trap.c b/sys/src/9/mtx/trap.c
index b9f1cbf4f..acc26a8dd 100644
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -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*
diff --git a/sys/src/9/omap/trap.c b/sys/src/9/omap/trap.c
index 5647fb036..433f9b237 100644
--- a/sys/src/9/omap/trap.c
+++ b/sys/src/9/omap/trap.c
@@ -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 */
diff --git a/sys/src/9/pc/irq.c b/sys/src/9/pc/irq.c
index 7bfee87a4..f61fb8d32 100644
--- a/sys/src/9/pc/irq.c
+++ b/sys/src/9/pc/irq.c
@@ -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;
}
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index 2c267507a..d082a40da 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -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 */
}
/*
diff --git a/sys/src/9/ppc/trap.c b/sys/src/9/ppc/trap.c
index bc4b1b0c5..5d5c2cf79 100644
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -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);
diff --git a/sys/src/9/sgi/trap.c b/sys/src/9/sgi/trap.c
index c580e557f..c5f351bb4 100644
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -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;
}
diff --git a/sys/src/9/teg2/trap.c b/sys/src/9/teg2/trap.c
index af134f8ce..8f7692e82 100644
--- a/sys/src/9/teg2/trap.c
+++ b/sys/src/9/teg2/trap.c
@@ -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);
diff --git a/sys/src/9/zynq/trap.c b/sys/src/9/zynq/trap.c
index 3393fdff0..f9e550eb1 100644
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -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);