Subject: Re: alternate rough SA patch (works on SMP)
To: Stephan Uphoff <ups@stups.com>
From: Christian Limpach <chris@pin.lu>
List: tech-kern
Date: 06/29/2003 02:47:52
Quoting Stephan Uphoff <ups@stups.com>:
> Here are a few comments:
> - ltsleep and therefore also copyout can not be called with SCHED_LOCK
> held.
> - as a target for mi_switch the lwp has to be in memory (l_flag & L_INMEM)
I noticed these two since I sent the patch. Don't we also need the L_INMEM
tests on UP?
> - With your patch a LWP that had been blocked (block upcall received by
> libpthread) can return later to user space without the associated
> unblock upcall or holding the virtual processor.
> This will confuse libpthread.
indeed, I wasn't quite aware of how things should work and my approach was to
fix the effects and not the cause of problems.
One problem seems to be that on MP the scheduler will run an lwp we put on
the runqueues before we get to do the SA housekeeping. I have added per-cpu
runqueues and now pthread/SA works without any additional patches in
kern_sa. There's still some issues with signal handling and occasional
"sa_switch: Not enough stacks".
per-cpu runqueues:
There's now a runqueue for each cpu in addition to the global runqueue. cpu-
switch runs the lwp with the highest priority. The cpu-queue wins over the
global queue if both have lwp's at the same priority.
setrunnable/setrunqueue take an additional argument cpu_id where -1 selects
the global queue and values >= 0 select that cpu. The selected cpu is
recorded in l_schedcpu in struct lwp for use in remrunqueue and to allow easy
rescheduling (setrunqueue(l, l->l_schedcpu)).
- There's no code to set a process' affinity except by setting it's
l_schedcpu from ddb/kgdb.
- Processes with SA enabled have a very strong affinity, this can probably be
relaxed somewhat.
- I have modified cpu_switch only on i386, the code is otherwise MI except
for one use of X86_MAXPROCS in sched.h where we need an MI MAXPROCS.
Comments?
christian
Index: arch/i386/i386/cpu.c
===================================================================
RCS file: /cvs/netbsd/src/sys/arch/i386/i386/cpu.c,v
retrieving revision 1.14
diff -u -b -r1.14 cpu.c
--- arch/i386/i386/cpu.c 25 Apr 2003 21:54:29 -0000 1.14
+++ arch/i386/i386/cpu.c 28 Jun 2003 17:02:19 -0000
@@ -287,6 +287,8 @@
#endif
ci->ci_func = caa->cpu_func;
+ rqinit(ci->ci_cpuid);
+
simple_lock_init(&ci->ci_slock);
#if defined(MULTIPROCESSOR)
Index: arch/i386/i386/genassym.cf
===================================================================
RCS file: /cvs/netbsd/src/sys/arch/i386/i386/genassym.cf,v
retrieving revision 1.37
diff -u -b -r1.37 genassym.cf
--- arch/i386/i386/genassym.cf 4 May 2003 22:01:58 -0000 1.37
+++ arch/i386/i386/genassym.cf 28 Jun 2003 17:02:19 -0000
@@ -281,6 +281,8 @@
define CPU_INFO_IDEPTH offsetof(struct cpu_info, ci_idepth)
define CPU_INFO_ISOURCES offsetof(struct cpu_info, ci_isources)
+define CPU_INFO_CPUID offsetof(struct cpu_info, ci_cpuid)
+
if NIOAPIC > 0
define IOAPIC_SC_REG offsetof(struct ioapic_softc, sc_reg)
define IOAPIC_SC_DATA offsetof(struct ioapic_softc, sc_data)
Index: arch/i386/i386/locore.S
===================================================================
RCS file: /cvs/netbsd/src/sys/arch/i386/i386/locore.S,v
retrieving revision 1.11
diff -u -b -r1.11 locore.S
--- arch/i386/i386/locore.S 26 Jun 2003 16:47:15 -0000 1.11
+++ arch/i386/i386/locore.S 28 Jun 2003 17:02:19 -0000
@@ -1705,9 +1705,19 @@
/* Look for new lwp. */
cli # splhigh doesn't do a cli
+#if !defined(MULTIPROCESSOR)
movl _C_LABEL(sched_whichqs),%ecx
bsfl %ecx,%ebx # find a full q
jnz switch_dequeue
+#else
+ movl CPUVAR(CPUID),%eax
+ incl %eax # select cpu q => eax = cpuid + 1
+
+ movl _C_LABEL(sched_whichqs),%ecx
+ orl _C_LABEL(sched_whichqs)(,%eax,4),%ecx
+ bsfl %ecx,%ebx
+ jnz switch_dequeue # cpu q empty, global q empty
+#endif
/*
* idling: save old context.
@@ -1784,8 +1794,18 @@
sti
call _C_LABEL(uvm_pageidlezero)
cli
+
+#if defined(MULTIPROCESSOR)
+ movl CPUVAR(CPUID),%eax
+ incl %eax
+#endif
+
cmpl $0,_C_LABEL(sched_whichqs)
jnz idle_exit
+#if defined(MULTIPROCESSOR)
+ cmpl $0,_C_LABEL(sched_whichqs)(,%eax,4)
+ jnz idle_exit
+#endif
idle_loop:
/* Try to zero some pages. */
movl _C_LABEL(uvm)+UVM_PAGE_IDLE_ZERO,%ecx
@@ -1796,24 +1816,57 @@
NENTRY(mpidle)
idle_start:
cli
+
+#if defined(MULTIPROCESSOR)
+ movl CPUVAR(CPUID),%eax
+ incl %eax
+#endif
+
cmpl $0,_C_LABEL(sched_whichqs)
+#if defined(MULTIPROCESSOR)
+ jnz idle_exit
+ cmpl $0,_C_LABEL(sched_whichqs)(,%eax,4)
+#endif
jz idle_loop
idle_exit:
movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh
#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
call _C_LABEL(sched_lock_idle)
#endif
+#if !defined(MULTIPROCESSOR)
movl _C_LABEL(sched_whichqs),%ecx
bsfl %ecx,%ebx
jz idle_unlock
+#else
+ movl CPUVAR(CPUID),%eax # XXX
+ incl %eax # XXX # select cpu q => eax = cpuid + 1
+
+ movl _C_LABEL(sched_whichqs),%ecx
+ orl _C_LABEL(sched_whichqs)(,%eax,4),%ecx
+ bsfl %ecx,%ebx
+ jz idle_unlock # cpu q empty, global q empty
+#endif
switch_dequeue:
+#if defined(MULTIPROCESSOR)
+ movl _C_LABEL(sched_whichqs)(,%eax,4),%ecx
+ btl %ebx,%ecx
+ jc 1f
+ xorl %eax,%eax # select global q => clear eax
+1:
+#endif
/*
* we're running at splhigh(), but it's otherwise okay to take
* interrupts here.
*/
sti
+#if !defined(MULTIPROCESSOR)
leal _C_LABEL(sched_qs)(,%ebx,8),%eax # select q
+#else
+ leal _C_LABEL(sched_whichqs)(,%eax,4),%ecx
+ movl _C_LABEL(sched_qs)(,%eax,4),%eax
+ leal (%eax,%ebx,8),%eax
+#endif
movl L_FORW(%eax),%edi # unlink from front of process q
#ifdef DIAGNOSTIC
@@ -1827,8 +1880,14 @@
cmpl %edx,%eax # q empty?
jne 3f
+#if !defined(MULTIPROCESSOR)
btrl %ebx,%ecx # yes, clear to indicate empty
movl %ecx,_C_LABEL(sched_whichqs) # update q status
+#else
+ movl (%ecx),%eax
+ btrl %ebx,%eax # yes, clear to indicate empty
+ movl %eax,(%ecx) # update q status
+#endif
3: /* We just did it. */
xorl %eax,%eax
Index: arch/i386/i386/pmap.c
===================================================================
RCS file: /cvs/netbsd/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.155
diff -u -b -r1.155 pmap.c
--- arch/i386/i386/pmap.c 23 Jun 2003 11:01:20 -0000 1.155
+++ arch/i386/i386/pmap.c 28 Jun 2003 17:02:19 -0000
@@ -2070,7 +2070,7 @@
*zpte = (pa & PG_FRAME) | PG_V | PG_RW; /* map in */
pmap_update_pg((vaddr_t)zerova); /* flush TLB */
for (i = 0, ptr = (int *) zerova; i < PAGE_SIZE / sizeof(int); i++) {
- if (sched_whichqs != 0) {
+ if (RQ_NOTEMPTY()) {
/*
* A process has become ready. Abort now,
Index: compat/mach/mach_thread.c
===================================================================
RCS file: /cvs/netbsd/src/sys/compat/mach/mach_thread.c,v
retrieving revision 1.18
diff -u -b -r1.18 mach_thread.c
--- compat/mach/mach_thread.c 30 Jan 2003 19:14:19 -0000 1.18
+++ compat/mach/mach_thread.c 28 Jun 2003 17:36:00 -0000
@@ -164,7 +164,7 @@
SCHED_LOCK(s);
mctc.mctc_lwp->l_private = 0;
mctc.mctc_lwp->l_stat = LSRUN;
- setrunqueue(mctc.mctc_lwp);
+ setrunqueue(mctc.mctc_lwp, mctc.mctc_lwp->l_schedcpu);
SCHED_UNLOCK(s);
simple_lock(&p->p_lwplock);
p->p_nrlwps++;
Index: kern/init_main.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/init_main.c,v
retrieving revision 1.218
diff -u -b -r1.218 init_main.c
--- kern/init_main.c 19 Mar 2003 11:36:32 -0000 1.218
+++ kern/init_main.c 28 Jun 2003 17:02:19 -0000
@@ -338,7 +338,7 @@
*/
(void)chgproccnt(0, 1);
- rqinit();
+ rqinit(-1);
/* Configure virtual memory system, set vm rlimits. */
uvm_init_limits(p);
Index: kern/kern_exit.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_exit.c,v
retrieving revision 1.115
diff -u -b -r1.115 kern_exit.c
--- kern/kern_exit.c 19 Mar 2003 11:36:33 -0000 1.115
+++ kern/kern_exit.c 28 Jun 2003 17:34:53 -0000
@@ -448,7 +448,8 @@
SCHED_LOCK(s);
while ((l2 = sa_getcachelwp(p)) != 0) {
l2->l_priority = l2->l_usrpri;
- setrunnable(l2);
+ setrunnable(l2, l2->l_cpu ? l2->l_cpu->ci_cpuid :
+ l2->l_schedcpu);
DPRINTF(("%d ", l2->l_lid));
}
DPRINTF(("\n"));
@@ -465,7 +466,8 @@
if ((l2->l_stat == LSSLEEP && (l2->l_flag & L_SINTR)) ||
l2->l_stat == LSSUSPENDED) {
SCHED_LOCK(s);
- setrunnable(l2);
+ setrunnable(l2, l2->l_cpu ? l2->l_cpu->ci_cpuid :
+ l2->l_schedcpu);
SCHED_UNLOCK(s);
DPRINTF(("exit_lwps: Made %d.%d runnable\n",
p->p_pid, l2->l_lid));
Index: kern/kern_fork.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_fork.c,v
retrieving revision 1.107
diff -u -b -r1.107 kern_fork.c
--- kern/kern_fork.c 19 Mar 2003 11:36:33 -0000 1.107
+++ kern/kern_fork.c 28 Jun 2003 17:02:19 -0000
@@ -433,7 +433,7 @@
} else {
p2->p_stat = SACTIVE;
l2->l_stat = LSRUN;
- setrunqueue(l2);
+ setrunqueue(l2, -1);
}
SCHED_UNLOCK(s);
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_lwp.c,v
retrieving revision 1.8
diff -u -b -r1.8 kern_lwp.c
--- kern/kern_lwp.c 23 Jun 2003 11:02:05 -0000 1.8
+++ kern/kern_lwp.c 28 Jun 2003 19:40:51 -0000
@@ -105,7 +105,7 @@
if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0) {
SCHED_LOCK(s);
l2->l_stat = LSRUN;
- setrunqueue(l2);
+ setrunqueue(l2, -1);
SCHED_UNLOCK(s);
simple_lock(&p->p_lwplock);
p->p_nrlwps++;
@@ -278,7 +278,8 @@
if (l->l_wchan == 0) {
/* LWP was runnable before being suspended. */
SCHED_LOCK(s);
- setrunnable(l);
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu);
SCHED_UNLOCK(s);
} else {
/* LWP was sleeping before being suspended. */
@@ -295,6 +296,7 @@
lwpid_t target_lid;
struct lwp *t;
struct proc *p;
+ int s;
p = l->l_proc;
target_lid = SCARG(uap, target);
@@ -312,7 +314,10 @@
if ((t->l_flag & L_SINTR) == 0)
return (EBUSY);
- setrunnable(t);
+ SCHED_LOCK(s);
+ setrunnable(t, (t->l_cpu && (t->l_flag & L_SA)) ?
+ t->l_cpu->ci_cpuid : l->l_schedcpu);
+ SCHED_UNLOCK(s);
return 0;
}
@@ -469,6 +474,8 @@
*/
l2->l_cpu = NULL;
#endif /* ! MULTIPROCESSOR */
+
+ l2->l_schedcpu = -1;
l2->l_flag = inmem ? L_INMEM : 0;
l2->l_flag |= (flags & LWP_DETACHED) ? L_DETACHED : 0;
Index: kern/kern_sa.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_sa.c,v
retrieving revision 1.16
diff -u -b -r1.16 kern_sa.c
--- kern/kern_sa.c 28 May 2003 22:17:20 -0000 1.16
+++ kern/kern_sa.c 28 Jun 2003 17:03:13 -0000
@@ -547,7 +547,7 @@
l->l_flag |= L_SA_BLOCKING;
l2->l_priority = l2->l_usrpri;
- setrunnable(l2);
+ setrunnable(l2, cpu_number());
PRELE(l2); /* Remove the artificial hold-count */
KDASSERT(l2 != l);
@@ -589,7 +589,7 @@
cpu_setfunc(l2, sa_yieldcall, l2);
l2->l_priority = l2->l_usrpri;
- setrunnable(l2);
+ setrunnable(l2, cpu_number());
PRELE(l2); /* Remove the artificial hold-count */
}
Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_sig.c,v
retrieving revision 1.141
diff -u -b -r1.141 kern_sig.c
--- kern/kern_sig.c 20 May 2003 17:42:51 -0000 1.141
+++ kern/kern_sig.c 28 Jun 2003 17:40:28 -0000
@@ -1059,7 +1059,8 @@
if (l->l_priority > PUSER)
l->l_priority = PUSER;
run:
- setrunnable(l); /* XXXSMP: recurse? */
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu); /* XXXSMP: recurse? */
out:
/* XXXSMP: works, but icky */
if (dolock)
@@ -1428,7 +1429,8 @@
cantake = 1;
}
} else {
- setrunnable(l);
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu);
lr = NULL;
cantake = 1;
}
Index: kern/kern_synch.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_synch.c,v
retrieving revision 1.130
diff -u -b -r1.130 kern_synch.c
--- kern/kern_synch.c 26 Jun 2003 02:09:27 -0000 1.130
+++ kern/kern_synch.c 28 Jun 2003 19:37:31 -0000
@@ -101,6 +101,7 @@
#include <sys/sched.h>
#include <sys/sa.h>
#include <sys/savar.h>
+#include <sys/malloc.h>
#include <uvm/uvm_extern.h>
@@ -116,8 +117,17 @@
/*
* The global scheduler state.
*/
+#if !defined(MULTIPROCESSOR)
struct prochd sched_qs[RUNQUE_NQS]; /* run queues */
__volatile u_int32_t sched_whichqs; /* bitmap of non-empty queues */
+#define _cpuindex(x) (x)
+#else
+struct prochd *sched_qs[1+X86_MAXPROCS]; /* run queues */
+__volatile u_int32_t sched_whichqs[1+X86_MAXPROCS]; /* bitmap of non-empty queues */
+MALLOC_DEFINE(M_RQ, "runqueue", "runqueue");
+#define _cpuindex(x) (x)[cpu_id + 1]
+#endif
+
struct slpque sched_slpque[SLPQUE_TABLESIZE]; /* sleep queues */
struct simplelock sched_lock = SIMPLELOCK_INITIALIZER;
@@ -310,7 +320,7 @@
(l->l_priority / PPQ) != (l->l_usrpri / PPQ)) {
remrunqueue(l);
l->l_priority = l->l_usrpri;
- setrunqueue(l);
+ setrunqueue(l, l->l_schedcpu);
} else
l->l_priority = l->l_usrpri;
}
@@ -570,7 +580,8 @@
SCHED_LOCK(s);
if (l->l_wchan) {
if (l->l_stat == LSSLEEP)
- setrunnable(l);
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu);
else
unsleep(l);
l->l_flag |= L_TIMEOUT;
@@ -622,9 +633,11 @@
* XXXSMP See affinity comment in resched_proc().
*/
if (l->l_flag & L_INMEM) {
- setrunqueue(l);
- if (l->l_flag & L_SA)
+ if (l->l_flag & L_SA) {
l->l_proc->p_sa->sa_woken = l;
+ setrunqueue(l, l->l_cpu->ci_cpuid);
+ } else
+ setrunqueue(l, l->l_schedcpu);
KASSERT(l->l_cpu != NULL);
need_resched(l->l_cpu);
} else
@@ -773,7 +786,7 @@
SCHED_LOCK(s);
l->l_priority = l->l_usrpri;
l->l_stat = LSRUN;
- setrunqueue(l);
+ setrunqueue(l, l->l_schedcpu);
l->l_proc->p_stats->p_ru.ru_nvcsw++;
mi_switch(l, NULL);
SCHED_ASSERT_UNLOCKED();
@@ -802,7 +815,7 @@
SCHED_LOCK(s);
l->l_priority = l->l_usrpri;
l->l_stat = LSRUN;
- setrunqueue(l);
+ setrunqueue(l, l->l_schedcpu);
l->l_proc->p_stats->p_ru.ru_nivcsw++;
r = mi_switch(l, NULL);
SCHED_ASSERT_UNLOCKED();
@@ -972,13 +985,20 @@
* to be empty.
*/
void
-rqinit()
+rqinit(int cpu_id)
{
int i;
- for (i = 0; i < RUNQUE_NQS; i++)
- sched_qs[i].ph_link = sched_qs[i].ph_rlink =
- (struct lwp *)&sched_qs[i];
+#if defined(MULTIPROCESSOR)
+ _cpuindex(sched_qs) = malloc(sizeof(struct prochd) * RUNQUE_NQS,
+ M_RQ, M_WAITOK);
+#endif
+
+ for (i = 0; i < RUNQUE_NQS; i++) {
+ _cpuindex(sched_qs)[i].ph_link = _cpuindex(sched_qs)[i].ph_rlink =
+ (struct lwp *)&_cpuindex(sched_qs)[i];
+ }
+ _cpuindex(sched_whichqs) = 0;
}
static __inline void
@@ -1019,7 +1039,7 @@
* and awakening the swapper if it isn't in memory.
*/
void
-setrunnable(struct lwp *l)
+setrunnable(struct lwp *l, int cpu_id)
{
struct proc *p = l->l_proc;
@@ -1054,8 +1074,9 @@
l->l_stat = LSRUN;
p->p_nrlwps++;
- if (l->l_flag & L_INMEM)
- setrunqueue(l);
+ if ((l->l_flag & L_INMEM)) {
+ setrunqueue(l, cpu_id);
+ }
if (l->l_slptime > 1)
updatepri(l);
@@ -1184,35 +1205,41 @@
*/
void
-setrunqueue(struct lwp *l)
+setrunqueue(struct lwp *l, int cpu_id)
{
struct prochd *rq;
struct lwp *prev;
int whichq;
+ SCHED_ASSERT_LOCKED();
+
#ifdef DIAGNOSTIC
if (l->l_back != NULL || l->l_wchan != NULL || l->l_stat != LSRUN)
panic("setrunqueue");
#endif
whichq = l->l_priority / 4;
- sched_whichqs |= (1 << whichq);
- rq = &sched_qs[whichq];
+ _cpuindex(sched_whichqs) |= (1 << whichq);
+ rq = &_cpuindex(sched_qs)[whichq];
prev = rq->ph_rlink;
l->l_forw = (struct lwp *)rq;
rq->ph_rlink = l;
prev->l_forw = l;
l->l_back = prev;
+ l->l_schedcpu = cpu_id;
}
void
remrunqueue(struct lwp *l)
{
struct lwp *prev, *next;
- int whichq;
+ int whichq, cpu_id;
+
+ SCHED_ASSERT_LOCKED();
whichq = l->l_priority / 4;
+ cpu_id = l->l_schedcpu;
#ifdef DIAGNOSTIC
- if (((sched_whichqs & (1 << whichq)) == 0))
+ if (((_cpuindex(sched_whichqs) & (1 << whichq)) == 0))
panic("remrunqueue");
#endif
prev = l->l_back;
@@ -1221,7 +1248,7 @@
prev->l_forw = next;
next->l_back = prev;
if (prev == next)
- sched_whichqs &= ~(1 << whichq);
+ _cpuindex(sched_whichqs) &= ~(1 << whichq);
}
#endif
Index: kern/kern_time.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/kern_time.c,v
retrieving revision 1.70
diff -u -b -r1.70 kern_time.c
--- kern/kern_time.c 28 May 2003 22:27:57 -0000 1.70
+++ kern/kern_time.c 28 Jun 2003 17:35:27 -0000
@@ -1217,7 +1217,9 @@
*/
if ((sa->sa_idle) && (p->p_stat != SSTOP)) {
SCHED_LOCK(s);
- setrunnable(sa->sa_idle);
+ setrunnable(sa->sa_idle, sa->sa_idle->l_cpu ?
+ sa->sa_idle->l_cpu->ci_cpuid :
+ sa->sa_idle->l_schedcpu);
SCHED_UNLOCK(s);
}
pt->pt_poverruns = pt->pt_overruns;
Index: kern/sys_generic.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/sys_generic.c,v
retrieving revision 1.74
diff -u -b -r1.74 sys_generic.c
--- kern/sys_generic.c 28 May 2003 20:02:59 -0000 1.74
+++ kern/sys_generic.c 28 Jun 2003 17:30:49 -0000
@@ -1018,7 +1018,8 @@
SCHED_LOCK(s);
if (l->l_wchan == (caddr_t)&selwait) {
if (l->l_stat == LSSLEEP)
- setrunnable(l);
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu);
else
unsleep(l);
} else if (l->l_flag & L_SELECT)
Index: kern/sys_process.c
===================================================================
RCS file: /cvs/netbsd/src/sys/kern/sys_process.c,v
retrieving revision 1.81
diff -u -b -r1.81 sys_process.c
--- kern/sys_process.c 20 May 2003 18:16:09 -0000 1.81
+++ kern/sys_process.c 28 Jun 2003 17:39:29 -0000
@@ -390,7 +390,8 @@
* get it moving.
*/
if (lr && (t->p_xstat != 0))
- setrunnable(lr);
+ setrunnable(lr, (lr->l_cpu && (lr->l_flag & L_SA)) ?
+ lr->l_cpu->ci_cpuid : lr->l_schedcpu);
SCHED_UNLOCK(s);
} else {
if (SCARG(uap, data) != 0)
Index: miscfs/procfs/procfs_ctl.c
===================================================================
RCS file: /cvs/netbsd/src/sys/miscfs/procfs/procfs_ctl.c,v
retrieving revision 1.24
diff -u -b -r1.24 procfs_ctl.c
--- miscfs/procfs/procfs_ctl.c 18 Jan 2003 09:18:06 -0000 1.24
+++ miscfs/procfs/procfs_ctl.c 28 Jun 2003 17:37:05 -0000
@@ -268,7 +268,8 @@
if (l->l_stat == LSSTOP) {
p->p_xstat = sig;
SCHED_LOCK(s);
- setrunnable(l);
+ setrunnable(l, (l->l_cpu && (l->l_flag & L_SA)) ?
+ l->l_cpu->ci_cpuid : l->l_schedcpu);
SCHED_UNLOCK(s);
} else {
if (sig != 0)
Index: sys/lwp.h
===================================================================
RCS file: /cvs/netbsd/src/sys/sys/lwp.h,v
retrieving revision 1.6
diff -u -b -r1.6 lwp.h
--- sys/lwp.h 4 Feb 2003 13:41:48 -0000 1.6
+++ sys/lwp.h 28 Jun 2003 17:27:19 -0000
@@ -63,6 +63,7 @@
int l_flag;
int l_stat;
lwpid_t l_lid; /* LWP identifier; local to process. */
+ int l_schedcpu;
#define l_startzero l_swtime
u_int l_swtime; /* Time swapped in or out. */
@@ -150,9 +151,9 @@
void remrunqueue (struct lwp *);
#endif
void resetpriority (struct lwp *);
-void setrunnable (struct lwp *);
+void setrunnable (struct lwp *, int);
#ifndef setrunqueue
-void setrunqueue (struct lwp *);
+void setrunqueue (struct lwp *, int);
#endif
#ifndef nextrunqueue
struct lwp *nextrunqueue(void);
Index: sys/proc.h
===================================================================
RCS file: /cvs/netbsd/src/sys/sys/proc.h,v
retrieving revision 1.164
diff -u -b -r1.164 proc.h
--- sys/proc.h 3 Jun 2003 18:50:59 -0000 1.164
+++ sys/proc.h 28 Jun 2003 17:02:19 -0000
@@ -432,7 +432,7 @@
void exit_lwps(struct lwp *l);
int fork1(struct lwp *, int, int, void *, size_t,
void (*)(void *), void *, register_t *, struct proc **);
-void rqinit(void);
+void rqinit(int);
int groupmember(gid_t, const struct ucred *);
int pgid_in_session(struct proc *, pid_t);
#ifndef cpu_idle
Index: sys/sched.h
===================================================================
RCS file: /cvs/netbsd/src/sys/sys/sched.h,v
retrieving revision 1.17
diff -u -b -r1.17 sched.h
--- sys/sched.h 28 Apr 2003 23:16:29 -0000 1.17
+++ sys/sched.h 28 Jun 2003 19:36:44 -0000
@@ -197,9 +197,14 @@
* simply give them meaningful names; the globals are actually declared
* in kern/kern_synch.c.
*/
+#if !defined(MULTIPROCESSOR)
extern struct prochd sched_qs[];
-extern struct slpque sched_slpque[];
extern __volatile u_int32_t sched_whichqs;
+#else
+extern struct prochd *sched_qs[];
+extern __volatile u_int32_t sched_whichqs[];
+#endif
+extern struct slpque sched_slpque[];
#define SLPQUE(ident) (&sched_slpque[SLPQUE_LOOKUP(ident)])
@@ -264,6 +269,12 @@
#define SCHED_UNLOCK(s) splx(s)
#endif /* MULTIPROCESSOR || LOCKDEBUG */
+
+#if defined(MULTIPROCESSOR)
+#define RQ_NOTEMPTY() ((sched_whichqs[0] != 0) || (sched_whichqs[cpu_number() + 1] != 0))
+#else
+#define RQ_NOTEMPTY() (sched_whichqs != 0)
+#endif
#endif /* _KERNEL */
#endif /* _SYS_SCHED_H_ */
Index: uvm/uvm_glue.c
===================================================================
RCS file: /cvs/netbsd/src/sys/uvm/uvm_glue.c,v
retrieving revision 1.64
diff -u -b -r1.64 uvm_glue.c
--- uvm/uvm_glue.c 14 Feb 2003 16:25:12 -0000 1.64
+++ uvm/uvm_glue.c 28 Jun 2003 17:31:51 -0000
@@ -471,7 +471,7 @@
cpu_swapin(l);
SCHED_LOCK(s);
if (l->l_stat == LSRUN)
- setrunqueue(l);
+ setrunqueue(l, l->l_schedcpu);
l->l_flag |= L_INMEM;
SCHED_UNLOCK(s);
l->l_swtime = 0;
Index: uvm/uvm_page.c
===================================================================
RCS file: /cvs/netbsd/src/sys/uvm/uvm_page.c,v
retrieving revision 1.89
diff -u -b -r1.89 uvm_page.c
--- uvm/uvm_page.c 1 Jun 2003 09:26:10 -0000 1.89
+++ uvm/uvm_page.c 28 Jun 2003 17:02:19 -0000
@@ -1429,7 +1429,7 @@
s = uvm_lock_fpageq();
firstbucket = nextbucket;
do {
- if (sched_whichqs != 0) {
+ if (RQ_NOTEMPTY()) {
uvm_unlock_fpageq(s);
return;
}
@@ -1442,7 +1442,7 @@
pgfl = &uvm.page_free[free_list];
while ((pg = TAILQ_FIRST(&pgfl->pgfl_buckets[
nextbucket].pgfl_queues[PGFL_UNKNOWN])) != NULL) {
- if (sched_whichqs != 0) {
+ if (RQ_NOTEMPTY()) {
uvm_unlock_fpageq(s);
return;
}
--
Christian Limpach <chris@pin.lu>