Track which process a CPU is running/has last run on by adding a
p_cpu member to struct proc. Use this in certain places when accessing scheduler state, etc. For the single-processor case, just initialize p_cpu in fork1() to avoid having to set it in the low-level context switch code on platforms which will never have multiprocessing. While I'm here, comment a few places where there are known issues for the SMP implementation.
This commit is contained in:
parent
65ace9d5d8
commit
956b3ca3b3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: init_main.c,v 1.170 2000/05/28 18:52:32 jhawk Exp $ */
|
||||
/* $NetBSD: init_main.c,v 1.171 2000/05/31 05:02:31 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -197,6 +197,7 @@ main()
|
|||
*/
|
||||
p = &proc0;
|
||||
curproc = p;
|
||||
p->p_cpu = curcpu();
|
||||
/*
|
||||
* Attempt to find console and initialize
|
||||
* in case of early panic or other messages.
|
||||
|
@ -463,11 +464,12 @@ main()
|
|||
* munched in mi_switch() after the time got set.
|
||||
*/
|
||||
proclist_lock_read();
|
||||
s = splclock(); /* so we can read time */
|
||||
s = splhigh(); /* block clock and statclock */
|
||||
for (p = LIST_FIRST(&allproc); p != NULL;
|
||||
p = LIST_NEXT(p, p_list)) {
|
||||
p->p_stats->p_start = curcpu()->ci_schedstate.spc_runtime =
|
||||
mono_time = boottime = time;
|
||||
p->p_stats->p_start = mono_time = boottime = time;
|
||||
if (p->p_cpu != NULL)
|
||||
p->p_cpu->ci_schedstate.spc_runtime = time;
|
||||
p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
|
||||
}
|
||||
splx(s);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_fork.c,v 1.65 2000/05/28 05:49:05 thorpej Exp $ */
|
||||
/* $NetBSD: kern_fork.c,v 1.66 2000/05/31 05:02:32 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
|
@ -41,6 +41,7 @@
|
|||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -273,6 +274,17 @@ again:
|
|||
memcpy(&p2->p_startcopy, &p1->p_startcopy,
|
||||
(unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
|
||||
|
||||
#if !defined(MULTIPROCESSOR)
|
||||
/*
|
||||
* In the single-processor case, all processes will always run
|
||||
* on the same CPU. So, initialize the child's CPU to the parent's
|
||||
* now. In the multiprocessor case, the child's CPU will be
|
||||
* initialized in the low-level context switch code when the
|
||||
* process runs.
|
||||
*/
|
||||
p2->p_cpu = p1->p_cpu;
|
||||
#endif /* ! MULTIPROCESSOR */
|
||||
|
||||
/*
|
||||
* Duplicate sub-structures as needed.
|
||||
* Increase reference counts on shared objects.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_ktrace.c,v 1.45 2000/05/29 22:29:01 sommerfeld Exp $ */
|
||||
/* $NetBSD: kern_ktrace.c,v 1.46 2000/05/31 05:02:32 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -232,7 +232,9 @@ ktrgenio(p, fd, rw, iov, len, error)
|
|||
buflen -= sizeof(struct ktr_genio);
|
||||
|
||||
while (resid > 0) {
|
||||
if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD)
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
KDASSERT(p->p_cpu == curcpu());
|
||||
if (p->p_cpu->ci_schedstate.spc_flags & SPCF_SHOULDYIELD)
|
||||
preempt(NULL);
|
||||
|
||||
cnt = min(iov->iov_len, buflen);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_resource.c,v 1.56 2000/05/26 21:20:30 thorpej Exp $ */
|
||||
/* $NetBSD: kern_resource.c,v 1.57 2000/05/31 05:02:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
|
@ -382,11 +382,10 @@ calcru(p, up, sp, ip)
|
|||
sec = p->p_rtime.tv_sec;
|
||||
usec = p->p_rtime.tv_usec;
|
||||
if (p->p_stat == SONPROC) {
|
||||
/*
|
||||
* XXX curcpu() is wrong -- needs to be the CPU the
|
||||
* XXX process is running on. --thorpej
|
||||
*/
|
||||
struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
|
||||
struct schedstate_percpu *spc;
|
||||
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
spc = &p->p_cpu->ci_schedstate;
|
||||
|
||||
/*
|
||||
* Adjust for the current time slice. This is actually fairly
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_subr.c,v 1.68 2000/05/27 01:43:27 enami Exp $ */
|
||||
/* $NetBSD: kern_subr.c,v 1.69 2000/05/31 05:02:33 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -145,7 +145,9 @@ uiomove(buf, n, uio)
|
|||
switch (uio->uio_segflg) {
|
||||
|
||||
case UIO_USERSPACE:
|
||||
if (curcpu()->ci_schedstate.spc_flags &
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
KDASSERT(p->p_cpu == curcpu());
|
||||
if (p->p_cpu->ci_schedstate.spc_flags &
|
||||
SPCF_SHOULDYIELD)
|
||||
preempt(NULL);
|
||||
if (uio->uio_rw == UIO_READ)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_synch.c,v 1.75 2000/05/27 05:00:48 thorpej Exp $ */
|
||||
/* $NetBSD: kern_synch.c,v 1.76 2000/05/31 05:02:33 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -424,7 +424,9 @@ tsleep(ident, priority, wmesg, timo)
|
|||
asm(".globl bpendtsleep ; bpendtsleep:");
|
||||
#endif
|
||||
resume:
|
||||
curcpu()->ci_schedstate.spc_curpriority = p->p_usrpri;
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
KDASSERT(p->p_cpu == curcpu());
|
||||
p->p_cpu->ci_schedstate.spc_curpriority = p->p_usrpri;
|
||||
splx(s);
|
||||
p->p_flag &= ~P_SINTR;
|
||||
if (p->p_flag & P_TIMEOUT) {
|
||||
|
@ -679,11 +681,16 @@ void
|
|||
mi_switch(p)
|
||||
struct proc *p;
|
||||
{
|
||||
struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
|
||||
struct schedstate_percpu *spc;
|
||||
struct rlimit *rlim;
|
||||
long s, u;
|
||||
struct timeval tv;
|
||||
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
KDASSERT(p->p_cpu == curcpu());
|
||||
|
||||
spc = &p->p_cpu->ci_schedstate;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (p->p_simple_locks) {
|
||||
printf("p->p_simple_locks %d\n", p->p_simple_locks);
|
||||
|
@ -737,11 +744,20 @@ mi_switch(p)
|
|||
spc->spc_flags &= ~SPCF_SWITCHCLEAR;
|
||||
|
||||
/*
|
||||
* Pick a new current process and record its start time.
|
||||
* Pick a new current process and switch to it. When we
|
||||
* run again, we'll return back here.
|
||||
*/
|
||||
uvmexp.swtch++;
|
||||
cpu_switch(p);
|
||||
microtime(&spc->spc_runtime);
|
||||
|
||||
/*
|
||||
* We're running again; record our new start time. We might
|
||||
* be running on a new CPU now, so don't use the cache'd
|
||||
* schedstate_percpu pointer.
|
||||
*/
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
KDASSERT(p->p_cpu == curcpu());
|
||||
microtime(&p->p_cpu->ci_schedstate.spc_runtime);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -803,8 +819,26 @@ setrunnable(p)
|
|||
p->p_slptime = 0;
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
wakeup((caddr_t)&proc0);
|
||||
else if (p->p_priority < curcpu()->ci_schedstate.spc_curpriority)
|
||||
else if (p->p_priority < curcpu()->ci_schedstate.spc_curpriority) {
|
||||
/*
|
||||
* XXXSMP
|
||||
* This is wrong. It will work, but what really
|
||||
* needs to happen is:
|
||||
*
|
||||
* - Need to check if p is higher priority
|
||||
* than the process currently running on
|
||||
* the CPU p last ran on (let p_cpu persist
|
||||
* after a context switch?), and preempt
|
||||
* that one (or, if there is no process
|
||||
* there, simply need_resched() that CPU.
|
||||
*
|
||||
* - Failing that, traverse a list of
|
||||
* available CPUs and need_resched() the
|
||||
* CPU with the lowest priority that's
|
||||
* lower than p's.
|
||||
*/
|
||||
need_resched();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -821,8 +855,13 @@ resetpriority(p)
|
|||
newpriority = PUSER + p->p_estcpu + NICE_WEIGHT * (p->p_nice - NZERO);
|
||||
newpriority = min(newpriority, MAXPRI);
|
||||
p->p_usrpri = newpriority;
|
||||
if (newpriority < curcpu()->ci_schedstate.spc_curpriority)
|
||||
if (newpriority < curcpu()->ci_schedstate.spc_curpriority) {
|
||||
/*
|
||||
* XXXSMP
|
||||
* Same applies as in setrunnable() above.
|
||||
*/
|
||||
need_resched();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sysctl.c,v 1.65 2000/05/27 04:52:36 thorpej Exp $ */
|
||||
/* $NetBSD: kern_sysctl.c,v 1.66 2000/05/31 05:02:34 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -1226,12 +1226,11 @@ fill_kproc2(p, ki)
|
|||
ki->p_pctcpu = p->p_pctcpu;
|
||||
ki->p_swtime = p->p_swtime;
|
||||
ki->p_slptime = p->p_slptime;
|
||||
/*
|
||||
* XXX curcpu() is wrong; should be CPU process is running on.
|
||||
* XXX --thorpej
|
||||
*/
|
||||
ki->p_schedflags = (p->p_stat == SONPROC) ?
|
||||
curcpu()->ci_schedstate.spc_flags : 0;
|
||||
if (p->p_stat == SONPROC) {
|
||||
KDASSERT(p->p_cpu != NULL);
|
||||
ki->p_schedflags = p->p_cpu->ci_schedstate.spc_flags;
|
||||
} else
|
||||
ki->p_schedflags = 0;
|
||||
|
||||
ki->p_uticks = p->p_uticks;
|
||||
ki->p_sticks = p->p_sticks;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_time.c,v 1.46 2000/05/26 21:20:32 thorpej Exp $ */
|
||||
/* $NetBSD: kern_time.c,v 1.47 2000/05/31 05:02:34 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -113,7 +113,7 @@ settime(tv)
|
|||
struct timeval *tv;
|
||||
{
|
||||
struct timeval delta;
|
||||
struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
|
||||
struct cpu_info *ci;
|
||||
int s;
|
||||
|
||||
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
|
||||
|
@ -128,7 +128,15 @@ settime(tv)
|
|||
time = *tv;
|
||||
(void) spllowersoftclock();
|
||||
timeradd(&boottime, &delta, &boottime);
|
||||
timeradd(&spc->spc_runtime, &delta, &spc->spc_runtime);
|
||||
/*
|
||||
* XXXSMP
|
||||
* This is wrong. We should traverse a list of all
|
||||
* CPUs and add the delta to the runtime of those
|
||||
* CPUs which have a process on them.
|
||||
*/
|
||||
ci = curcpu();
|
||||
timeradd(&ci->ci_schedstate.spc_runtime, &delta,
|
||||
&ci->ci_schedstate.spc_runtime);
|
||||
# if defined(NFS) || defined(NFSSERVER)
|
||||
nqnfs_lease_updatetime(delta.tv_sec);
|
||||
# endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: proc.h,v 1.96 2000/05/28 05:49:06 thorpej Exp $ */
|
||||
/* $NetBSD: proc.h,v 1.97 2000/05/31 05:02:36 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1986, 1989, 1991, 1993
|
||||
|
@ -135,6 +135,8 @@ struct proc {
|
|||
|
||||
int p_exitsig; /* signal to sent to parent on exit */
|
||||
int p_flag; /* P_* flags. */
|
||||
struct cpu_info * __volatile p_cpu; /* CPU we're running on if
|
||||
SONPROC */
|
||||
u_char p_unused; /* XXX: used to be emulation flag */
|
||||
char p_stat; /* S* process status. */
|
||||
char p_pad1[2];
|
||||
|
|
Loading…
Reference in New Issue