Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Track which process a CPU is running/has last run on by ...
details: https://anonhg.NetBSD.org/src/rev/c1f690200ba3
branches: trunk
changeset: 486939:c1f690200ba3
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed May 31 05:02:31 2000 +0000
description:
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.
diffstat:
sys/kern/init_main.c | 10 +++++---
sys/kern/kern_fork.c | 14 +++++++++++-
sys/kern/kern_ktrace.c | 6 +++-
sys/kern/kern_resource.c | 11 ++++-----
sys/kern/kern_subr.c | 6 +++-
sys/kern/kern_synch.c | 53 +++++++++++++++++++++++++++++++++++++++++------
sys/kern/kern_sysctl.c | 13 +++++------
sys/kern/kern_time.c | 14 +++++++++--
sys/sys/proc.h | 4 ++-
9 files changed, 98 insertions(+), 33 deletions(-)
diffs (truncated from 317 to 300 lines):
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/init_main.c
--- a/sys/kern/init_main.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/init_main.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
*/
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 @@
* 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);
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_fork.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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.
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_ktrace.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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);
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_resource.c
--- a/sys/kern/kern_resource.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_resource.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_subr.c
--- a/sys/kern/kern_subr.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_subr.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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)
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_synch.c
--- a/sys/kern/kern_synch.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_synch.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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();
+ }
}
/*
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_sysctl.c
--- a/sys/kern/kern_sysctl.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_sysctl.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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;
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/kern/kern_time.c
--- a/sys/kern/kern_time.c Wed May 31 04:57:20 2000 +0000
+++ b/sys/kern/kern_time.c Wed May 31 05:02:31 2000 +0000
@@ -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 @@
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 @@
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
diff -r 162a91fc7fb4 -r c1f690200ba3 sys/sys/proc.h
Home |
Main Index |
Thread Index |
Old Index