Scheduler diff needs wide testing.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Scheduler diff needs wide testing.

Artur Grabowski
Hi,

We're working on a rather large change to how we do context switching
in the kernel and the diff is getting almost ready to get into the
tree. I'd like to have some wider testing on this since it's a quite
a bit of brain surgery on all architectures.

Right now only arm is missing from the diff, so if you have arm machines
you can't test, everyone else should be able to run this. This is
of course -current we're talking about.

What needs to be tested is primarily that everything works and nothing
crashes, but also I'd like people to watch for weird scheduler behavior.
Music not playing, X being slow, top showing weird numbers, stuff like
that.

Please mail me positive test results privately and cc the list if
something loks wrong.

//art

Index: arch/alpha/alpha/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/genassym.cf,v
retrieving revision 1.10
diff -u -r1.10 genassym.cf
--- arch/alpha/alpha/genassym.cf 28 May 2007 23:10:10 -0000 1.10
+++ arch/alpha/alpha/genassym.cf 25 Sep 2007 09:53:36 -0000
@@ -103,17 +103,12 @@
 
 # Important offsets into the proc struct & associated constants
 struct proc
-member p_forw
-member p_back
 member p_addr
 member p_vmspace
 member p_stat
 member P_MD_FLAGS p_md.md_flags
 member P_MD_PCBPADDR p_md.md_pcbpaddr
 member p_cpu
-struct prochd
-member ph_link
-member ph_rlink
 
 export SONPROC
 
Index: arch/alpha/alpha/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/locore.s,v
retrieving revision 1.30
diff -u -r1.30 locore.s
--- arch/alpha/alpha/locore.s 28 May 2007 23:10:10 -0000 1.30
+++ arch/alpha/alpha/locore.s 25 Sep 2007 09:53:37 -0000
@@ -716,123 +716,38 @@
 
 /**************************************************************************/
 
-IMPORT(whichqs, 4)
-
-/*
- * When no processes are on the runq, cpu_switch branches to idle
- * to wait for something to come ready.
- * Note: this is really a part of cpu_switch() but defined here for kernel
- * profiling.
- */
-LEAF(idle, 0)
- br pv, 1f
-1: LDGP(pv)
- /* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
- GET_CURPROC
- stq zero, 0(v0) /* curproc <- NULL for stats */
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_unlock_idle) /* release sched_lock */
-#endif
- mov zero, a0 /* enable all interrupts */
- call_pal PAL_OSF1_swpipl
-2: ldl t0, whichqs /* look for non-empty queue */
- beq t0, 2b
- ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
- call_pal PAL_OSF1_swpipl
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_lock_idle) /* acquire sched_lock */
-#endif
- jmp zero, cpu_switch_queuescan /* jump back into the fire */
- END(idle)
-
 /*
- * cpu_switch()
- * Find the highest priority process and resume it.
+ * cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
  */
-LEAF(cpu_switch, 0)
+LEAF(cpu_switchto, 2)
  LDGP(pv)
- /*
- * do an inline savectx(), to save old context
- * Note: GET_CURPROC clobbers v0, t0, t8...t11.
- */
- GET_CURPROC
- ldq a0, 0(v0)
- ldq a1, P_ADDR(a0)
- /* NOTE: ksp is stored by the swpctx */
- stq s0, U_PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
- stq s1, U_PCB_CONTEXT+(1 * 8)(a1)
- stq s2, U_PCB_CONTEXT+(2 * 8)(a1)
- stq s3, U_PCB_CONTEXT+(3 * 8)(a1)
- stq s4, U_PCB_CONTEXT+(4 * 8)(a1)
- stq s5, U_PCB_CONTEXT+(5 * 8)(a1)
- stq s6, U_PCB_CONTEXT+(6 * 8)(a1)
- stq ra, U_PCB_CONTEXT+(7 * 8)(a1) /* store ra */
- call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
- stq v0, U_PCB_CONTEXT+(8 * 8)(a1) /* store ps, for ipl */
-
- mov a0, s0 /* save old curproc */
- mov a1, s1 /* save old U-area */
-
-cpu_switch_queuescan:
- br pv, 1f
-1: LDGP(pv)
- ldl t0, whichqs /* look for non-empty queue */
- beq t0, idle /* and if none, go idle */
- mov t0, t3 /* t3 = saved whichqs */
- mov zero, t2 /* t2 = lowest bit set */
- blbs t0, 3f /* if low bit set, done! */
-
-2: srl t0, 1, t0 /* try next bit */
- addq t2, 1, t2
- blbc t0, 2b /* if clear, try again */
-
-3: /*
- * Remove process from queue
- */
- lda t1, qs /* get queues */
- sll t2, 4, t0 /* queue head is 16 bytes */
- addq t1, t0, t0 /* t0 = qp = &qs[firstbit] */
-
- ldq t4, PH_LINK(t0) /* t4 = p = highest pri proc */
- bne t4, 4f /* make sure p != NULL */
- PANIC("cpu_switch",Lcpu_switch_pmsg) /* nothing in queue! */
-
-4:
- ldq t5, P_FORW(t4) /* t5 = p->p_forw */
- stq t5, PH_LINK(t0) /* qp->ph_link = p->p_forw */
- stq t0, P_BACK(t5) /* p->p_forw->p_back = qp */
- stq zero, P_BACK(t4) /* firewall: p->p_back = NULL */
- cmpeq t0, t5, t0 /* see if queue is empty */
- beq t0, 5f /* nope, it's not! */
-
- ldiq t0, 1 /* compute bit in whichqs */
- sll t0, t2, t0
- xor t3, t0, t3 /* clear bit in whichqs */
- stl t3, whichqs
 
-5:
- mov t4, s2 /* save new proc */
- ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
  /*
- * Done mucking with the run queues, release the
- * scheduler lock, but keep interrupts out.
+ * Don't bother saving the old context if oldproc is NULL.
  */
- CALL(sched_unlock_idle)
-#endif
+ beq a0, 1f
 
  /*
- * Check to see if we're switching to ourself.  If we are,
- * don't bother loading the new context.
- *
- * Note that even if we re-enter cpu_switch() from idle(),
- * s0 will still contain the old curproc value because any
- * users of that register between then and now must have
- * saved it.  Also note that switch_exit() ensures that
- * s0 is clear before jumping here to find a new process.
+ * do an inline savectx(), to save old context
  */
- cmpeq s0, s2, t0 /* oldproc == newproc? */
- bne t0, 7f /* Yes!  Skip! */
+ call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
+ ldq t0, P_ADDR(a0)
+ /* NOTE: ksp is stored by the swpctx */
+ stq s0, U_PCB_CONTEXT+(0 * 8)(t0) /* store s0 - s6 */
+ stq s1, U_PCB_CONTEXT+(1 * 8)(t0)
+ stq s2, U_PCB_CONTEXT+(2 * 8)(t0)
+ stq s3, U_PCB_CONTEXT+(3 * 8)(t0)
+ stq s4, U_PCB_CONTEXT+(4 * 8)(t0)
+ stq s5, U_PCB_CONTEXT+(5 * 8)(t0)
+ stq s6, U_PCB_CONTEXT+(6 * 8)(t0)
+ stq ra, U_PCB_CONTEXT+(7 * 8)(t0) /* store ra */
+ stq v0, U_PCB_CONTEXT+(8 * 8)(t0) /* store ps, for ipl */
+
+1:
+ mov a0, s0 /* save old proc */
+ mov a1, s2 /* save new proc */
+ ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
 
  /*
  * Deactivate the old address space before activating the
@@ -842,18 +757,18 @@
  * do this after we activate, then we might end up
  * incorrectly marking the pmap inactive!
  *
- * We don't deactivate if we came here from switch_exit
+ * We don't deactivate if we came here from sched_exit
  * (old pmap no longer exists; vmspace has been freed).
  * oldproc will be NULL in this case.  We have actually
  * taken care of calling pmap_deactivate() in cpu_exit(),
  * before the vmspace went away.
  */
- beq s0, 6f
+ beq s0, 2f
 
  mov s0, a0 /* pmap_deactivate(oldproc) */
  CALL(pmap_deactivate)
 
-6: /*
+2: /*
  * Activate the new process's address space and perform
  * the actual context swap.
  */
@@ -864,7 +779,7 @@
  mov s3, a0 /* swap the context */
  SWITCH_CONTEXT
 
-7: /*
+ /*
  * Now that the switch is done, update curproc and other
  * globals.  We must do this even if switching to ourselves
  * because we might have re-entered cpu_switch() from idle(),
@@ -911,7 +826,7 @@
 
  ldiq v0, 1 /* possible ret to savectx() */
  RET
- END(cpu_switch)
+ END(cpu_switchto)
 
 #ifndef SMALL_KERNEL
  /*
@@ -926,6 +841,18 @@
 EXPORT(__bwx_switch3)
 #endif
 
+LEAF(cpu_idle_enter, 0)
+ RET
+ END(cpu_idle_enter)
+
+LEAF(cpu_idle_cycle, 0)
+ RET
+ END(cpu_idle_cycle)
+
+LEAF(cpu_idle_leave, 0)
+ RET
+ END(cpu_idle_leave)
+
 /*
  * switch_trampoline()
  *
@@ -944,46 +871,6 @@
  mov s2, a0
  jmp zero, (pv)
  END(switch_trampoline)
-
-/*
- * switch_exit(struct proc *p)
- * Make a the named process exit.  Partially switch to our idle thread
- * (we don't update curproc or restore registers), and jump into the middle
- * of cpu_switch to switch into a few process.  The process reaper will
- * free the dead process's VM resources.  MUST BE CALLED AT SPLHIGH.
- */
-LEAF(switch_exit, 1)
- LDGP(pv)
-
- /* save the exiting proc pointer */
- mov a0, s2
-
- /* Switch to our idle stack. */
- GET_IDLE_PCB(a0) /* clobbers v0, t0, t8-t11 */
- SWITCH_CONTEXT
-
- /*
- * Now running as idle thread, except for the value of 'curproc' and
- * the saved regs.
- */
-
- /* Schedule the vmspace and stack to be freed. */
- mov s2, a0
- CALL(exit2)
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- CALL(sched_lock_idle) /* acquire sched_lock */
-#endif
-
- /*
- * Now jump back into the middle of cpu_switch().  Note that
- * we must clear s0 to guarantee that the check for switching
- * to ourselves in cpu_switch() will fail.  This is safe since
- * s0 will be restored when a new process is resumed.
- */
- mov zero, s0
- jmp zero, cpu_switch_queuescan
- END(switch_exit)
 
 /**************************************************************************/
 
Index: arch/alpha/alpha/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.112
diff -u -r1.112 machdep.c
--- arch/alpha/alpha/machdep.c 15 Sep 2007 10:10:37 -0000 1.112
+++ arch/alpha/alpha/machdep.c 25 Sep 2007 09:53:37 -0000
@@ -1874,66 +1874,6 @@
 }
 
 /*
- * The following primitives manipulate the run queues.  _whichqs tells which
- * of the 32 queues _qs have processes in them.  Setrunqueue puts processes
- * into queues, Remrunqueue removes them from queues.  The running process is
- * on no queue, other processes are on a queue related to p->p_priority,
- * divided by 4 actually to shrink the 0-127 range of priorities into the 32
- * available queues.
- */
-/*
- * setrunqueue(p)
- * proc *p;
- *
- * Call should be made at splclock(), and p->p_stat should be SRUN.
- */
-
-/* XXXART - grmble */
-#define sched_qs qs
-#define sched_whichqs whichqs
-
-void
-setrunqueue(p)
- struct proc *p;
-{
- int bit;
-
- /* firewall: p->p_back must be NULL */
- if (p->p_back != NULL)
- panic("setrunqueue");
-
- bit = p->p_priority >> 2;
- sched_whichqs |= (1 << bit);
- p->p_forw = (struct proc *)&sched_qs[bit];
- p->p_back = sched_qs[bit].ph_rlink;
- p->p_back->p_forw = p;
- sched_qs[bit].ph_rlink = p;
-}
-
-/*
- * remrunqueue(p)
- *
- * Call should be made at splclock().
- */
-void
-remrunqueue(p)
- struct proc *p;
-{
- int bit;
-
- bit = p->p_priority >> 2;
- if ((sched_whichqs & (1 << bit)) == 0)
- panic("remrunqueue");
-
- p->p_back->p_forw = p->p_forw;
- p->p_forw->p_back = p->p_back;
- p->p_back = NULL; /* for firewall checking. */
-
- if ((struct proc *)&sched_qs[bit] == sched_qs[bit].ph_link)
- sched_whichqs &= ~(1 << bit);
-}
-
-/*
  * Wait "n" microseconds.
  */
 void
Index: arch/alpha/alpha/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/vm_machdep.c,v
retrieving revision 1.34
diff -u -r1.34 vm_machdep.c
--- arch/alpha/alpha/vm_machdep.c 3 Sep 2007 01:24:22 -0000 1.34
+++ arch/alpha/alpha/vm_machdep.c 25 Sep 2007 09:53:38 -0000
@@ -114,9 +114,7 @@
  * vmspace's context until the switch to proc0 in switch_exit().
  */
  pmap_deactivate(p);
-
- (void) splhigh();
- switch_exit(p);
+ sched_exit(p);
  /* NOTREACHED */
 }
 
Index: arch/amd64/amd64/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v
retrieving revision 1.14
diff -u -r1.14 cpu.c
--- arch/amd64/amd64/cpu.c 17 Sep 2007 15:34:38 -0000 1.14
+++ arch/amd64/amd64/cpu.c 25 Sep 2007 09:53:38 -0000
@@ -345,6 +345,7 @@
 #if defined(MULTIPROCESSOR)
  cpu_intr_init(ci);
  gdt_alloc_cpu(ci);
+ sched_init_cpu(ci);
  cpu_start_secondary(ci);
  ncpus++;
  if (ci->ci_flags & CPUF_PRESENT) {
@@ -540,6 +541,9 @@
 
  microuptime(&ci->ci_schedstate.spc_runtime);
  splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 
 #if defined(DDB)
Index: arch/amd64/amd64/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/genassym.cf,v
retrieving revision 1.14
diff -u -r1.14 genassym.cf
--- arch/amd64/amd64/genassym.cf 1 Jun 2007 21:01:51 -0000 1.14
+++ arch/amd64/amd64/genassym.cf 25 Sep 2007 09:53:38 -0000
@@ -33,8 +33,6 @@
 
 struct proc
 member p_addr
-member p_back
-member p_forw
 member p_priority
 member p_stat
 member p_wchan
Index: arch/amd64/amd64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/locore.S,v
retrieving revision 1.23
diff -u -r1.23 locore.S
--- arch/amd64/amd64/locore.S 12 Sep 2007 18:18:27 -0000 1.23
+++ arch/amd64/amd64/locore.S 25 Sep 2007 09:53:39 -0000
@@ -723,13 +723,8 @@
  * actually to shrink the 0-127 range of priorities into the 32 available
  * queues.
  */
- .globl _C_LABEL(whichqs),_C_LABEL(qs)
  .globl _C_LABEL(uvmexp),_C_LABEL(panic)
 
-#if NAPM > 0
- .globl _C_LABEL(apm_cpu_idle),_C_LABEL(apm_cpu_busy)
-#endif
-
 #ifdef DIAGNOSTIC
 NENTRY(switch_error1)
  movabsq $1f,%rdi
@@ -749,12 +744,10 @@
 #endif /* DIAGNOSTIC */
 
 /*
- * int cpu_switch(struct proc *)
- * Find a runnable process and switch to it.  Wait if necessary.  If the new
- * proc is the same as the old one, we short-circuit the context save and
- * restore.
+ * int cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
  */
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
  pushq %rbx
  pushq %rbp
  pushq %r12
@@ -762,163 +755,12 @@
  pushq %r14
  pushq %r15
 
- movq %rdi,%r13
-
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- * This also insures that schedcpu() will move the old proc to
- * the correct queue if it happens to get called from the spllower()
- * below and changes the priority.  (See corresponding comment in
- * userret()).
- */
- movq $0,CPUVAR(CURPROC)
-
-
- /*
- * First phase: find new proc.
- *
- * Registers:
- *   %rax - queue head, scratch, then zero
- *   %r8 - queue number
- *   %ecx - cached value of whichqs
- *   %rdx - next process in queue
- *   %r13 - old proc
- *   %r12 - new proc
- */
-
- /* Look for new proc. */
- cli # splhigh doesn't do a cli
- movl _C_LABEL(whichqs)(%rip),%ecx
- bsfl %ecx,%r8d # find a full q
- jnz switch_dequeue
-
- /*
- * idling: save old context
- *
- * Registers:
- * %rax, %rcx - scratch
- * %r13 - old proc, then old pcb
- * %r12 - idle pcb
- */
-
- /* old proc still in %rdi */
- call _C_LABEL(pmap_deactivate)
-
- movq P_ADDR(%r13),%r13
-
- /* Save stack pointers */
-
- movq %rsp,PCB_RSP(%r13)
- movq %rbp,PCB_RBP(%r13)
-
- /* Find idle PCB for this CPU */
-#ifndef MULTIPROCESSOR
- leaq _C_LABEL(proc0)(%rip),%rcx
- movq P_ADDR(%rcx),%r12
- movl P_MD_TSS_SEL(%rcx),%edx
-#else
- movq CPUVAR(IDLE_PCB),%r12
- movl CPUVAR(IDLE_TSS_SEL),%edx
-#endif
- movq $0,CPUVAR(CURPROC)
-
- /* Restore the idle context (avoid interrupts) */
- cli
-
- /* Restore stack pointers. */
- movq PCB_RSP(%r12),%rsp
- movq PCB_RBP(%r12),%rbp
-
- /* Switch address space. */
- movq PCB_CR3(%r12),%rcx
- movq %rcx,%cr3
-
-#ifdef MULTIPROCESSOR
- movq CPUVAR(GDT),%rax
-#else
- movq _C_LABEL(gdtstore)(%rip),%rax
-#endif
-
- /* Switch TSS. Reset "task busy" flag before */
- andl $~0x0200,4(%rax,%rdx, 1)
- ltr %dx
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%r12),%ecx
- movq %rcx,%cr0
-
- SET_CURPCB(%r12)
-
- xorq %r13,%r13
- sti
-idle_unlock:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)      
- call _C_LABEL(sched_unlock_idle)
-#endif
- /* Interrupts are okay again. */
- movl $IPL_NONE,%edi
- call _C_LABEL(Xspllower)
- jmp idle_start
-idle_zero:
- sti
- call _C_LABEL(uvm_pageidlezero)
- cli
- cmpl $0,_C_LABEL(whichqs)(%rip)
- jnz idle_exit
-idle_loop:
-#if NPCTR > 0
- incq _C_LABEL(pctr_idlcnt)
-#endif
- /* Try to zero some pages. */
- movl _C_LABEL(uvm)+UVM_PAGE_IDLE_ZERO(%rip),%ecx
- testl %ecx,%ecx
- jnz idle_zero
- sti
- hlt
-NENTRY(mpidle)
-idle_start:
- cli
- cmpl $0,_C_LABEL(whichqs)(%rip)
- jz idle_loop
-idle_exit:
- movl $IPL_HIGH,CPUVAR(ILEVEL)
- sti
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)      
- call _C_LABEL(sched_lock_idle)
-#endif
-switch_search:
- movl _C_LABEL(whichqs)(%rip),%ecx
- bsfl %ecx,%r8d
- jz idle_unlock
-
-switch_dequeue:
-
- sti
- movq %r8,%r9
-
- shlq $4, %r9
- leaq _C_LABEL(qs)(%rip),%rax
- addq %r9,%rax
- /* movq (%rax),%rax */
-
- movq P_FORW(%rax),%r12 # unlink from front of process q
-#ifdef DIAGNOSTIC
- cmpq %r12,%rax # linked to self (i.e. nothing queued)?
- je _C_LABEL(switch_error1) # not possible
-#endif /* DIAGNOSTIC */
- movq P_FORW(%r12),%rdx
- movq %rdx,P_FORW(%rax)
- movq %rax,P_BACK(%rdx)
-
- cmpq %rdx,%rax # q empty?
- jne 3f
-
- btrl %r8d,%ecx # yes, clear to indicate empty
- movl %ecx,_C_LABEL(whichqs)(%rip) # update q status
+ movq %rdi, %r13
+ movq %rsi, %r12
 
-3: /* We just did it. */
  xorq %rax,%rax
  movl %eax,CPUVAR(RESCHED)
+
 switch_resume:
 #ifdef DIAGNOSTIC
  cmpq %rax,P_WCHAN(%r12)
@@ -927,24 +769,16 @@
  jne _C_LABEL(switch_error3)
 #endif
 
- /* Isolate proc.  XXX Is this necessary? */
- movq %rax,P_BACK(%r12)
-
  /* Record new proc. */
  movb $SONPROC,P_STAT(%r12) # p->p_stat = SONPROC
  SET_CURPROC(%r12,%rcx)
 
- /* Skip context switch if same proc. */
- xorl %ebx,%ebx
- cmpq %r12,%r13
- je switch_return
-
  /* If old proc exited, don't bother. */
  testq %r13,%r13
  jz switch_exited
 
  /*
- * Second phase: save old context.
+ * Save old context.
  *
  * Registers:
  *   %rax, %rcx - scratch
@@ -963,7 +797,7 @@
 
 switch_exited:
  /*
- * Third phase: restore saved context.
+ * Restore saved context.
  *
  * Registers:
  *   %rax, %rcx, %rdx - scratch
@@ -1020,15 +854,13 @@
  sti
 
 switch_return:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)    
- call _C_LABEL(sched_unlock_idle)
-#endif
 
+#if 0
+ /* Violation of lock ordering, since we're holding the sched_lock */
  movl $IPL_NONE,%edi
  call _C_LABEL(Xspllower)
  movl $IPL_HIGH,CPUVAR(ILEVEL)
-
- movl %ebx,%eax
+#endif
 
  popq %r15
  popq %r14
@@ -1038,87 +870,16 @@
  popq %rbx
  ret
 
-ENTRY(cpu_switchto)
- pushq %rbx
- pushq %rbp
- pushq %r12
- pushq %r13
- pushq %r14
- pushq %r15
-
- movq %rdi,%r13
- movq %rsi,%r12
-
- movq $0,CPUVAR(CURPROC)
-
- xorq %rax,%rax
- jmp switch_resume
-
-
-/*
- * void switch_exit(struct proc *l, void (*exit)(struct proc *));
- * Switch to proc0's saved context and deallocate the address space and kernel
- * stack for p.  Then jump into cpu_switch(), as if we were in proc0 all along.
- */
- .globl _C_LABEL(proc0)
-ENTRY(switch_exit)
-#ifdef MULTIPROCESSOR
- movq CPUVAR(IDLE_PCB),%r8
- movl CPUVAR(IDLE_TSS_SEL),%edx
-#else
- leaq _C_LABEL(proc0)(%rip),%r9
- movq P_ADDR(%r9),%r8
- movl P_MD_TSS_SEL(%r9),%edx
-#endif
-
- /* In case we fault... */
- movq $0,CPUVAR(CURPROC)
-
- cli
-
- /* Restore stack pointers. */
- movq PCB_RSP(%r8),%rsp
- movq PCB_RBP(%r8),%rbp
-
- /* Load TSS info. */
-#ifdef MULTIPROCESSOR
- movq CPUVAR(GDT),%rax
-#else
- movq _C_LABEL(gdtstore)(%rip),%rax
-#endif
-
- /* Switch address space. */
- movq PCB_CR3(%r8),%rcx
- movq %rcx,%cr3
-
- /* Switch TSS. */
- andl $~0x0200,4-SEL_KPL(%rax,%rdx,1)
- ltr %dx
-
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%r8),%ecx
- movq %rcx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%r8)
-
- /* Interrupts are okay again. */
- sti
+ENTRY(cpu_idle_enter)
+ ret
 
- /*
- * Schedule the dead process's vmspace and stack to be freed.
- * {lpw_}exit2(l). Function still in %rsi (2nd arg), proc in
- * %rdi (first arg).
- */
+ENTRY(cpu_idle_cycle)
+ hlt
+ ret
 
- call *%rsi
+ENTRY(cpu_idle_leave)
+ ret
 
- /* Jump into cpu_switch() with the right state. */
- xorq %r13,%r13
- movq %r13, CPUVAR(CURPROC)
- jmp switch_search
 
 /*
  * savectx(struct pcb *pcb);
Index: arch/amd64/amd64/mptramp.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/mptramp.S,v
retrieving revision 1.3
diff -u -r1.3 mptramp.S
--- arch/amd64/amd64/mptramp.S 26 Jul 2005 08:38:29 -0000 1.3
+++ arch/amd64/amd64/mptramp.S 25 Sep 2007 09:53:39 -0000
@@ -235,5 +235,4 @@
  movl    PCB_CR0(%rsi),%eax
  movq    %rax,%cr0
  call _C_LABEL(cpu_hatch)
- xorq %r13,%r13
- jmp _C_LABEL(mpidle)
+ /* NOTREACHED */
Index: arch/amd64/amd64/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/vm_machdep.c,v
retrieving revision 1.10
diff -u -r1.10 vm_machdep.c
--- arch/amd64/amd64/vm_machdep.c 27 May 2007 20:59:25 -0000 1.10
+++ arch/amd64/amd64/vm_machdep.c 25 Sep 2007 09:53:39 -0000
@@ -169,12 +169,8 @@
  if (p->p_md.md_flags & MDP_USEDMTRR)
  mtrr_clean(p);
 
- /*
- * No need to do user LDT cleanup here; it's handled in
- * pmap_destroy().
- */
-
- switch_exit(p, exit2);
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.34
diff -u -r1.34 files.amd64
--- arch/amd64/conf/files.amd64 12 Sep 2007 18:18:27 -0000 1.34
+++ arch/amd64/conf/files.amd64 25 Sep 2007 09:53:39 -0000
@@ -18,7 +18,6 @@
 file arch/amd64/amd64/trap.c
 file arch/amd64/amd64/vm_machdep.c
 file arch/amd64/amd64/fpu.c
-file arch/amd64/amd64/Locore.c
 file arch/amd64/amd64/softintr.c
 file arch/amd64/amd64/i8259.c
 file arch/amd64/amd64/cacheinfo.c
Index: arch/aviion/aviion/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/aviion/aviion/locore.S,v
retrieving revision 1.3
diff -u -r1.3 locore.S
--- arch/aviion/aviion/locore.S 20 May 2006 22:40:43 -0000 1.3
+++ arch/aviion/aviion/locore.S 25 Sep 2007 09:53:39 -0000
@@ -343,14 +343,6 @@
  bsr.n _C_LABEL(secondary_main)
  addu r31, r3, USIZE /* switch to idle stack */
 
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_idle)
-
 #endif /* MULTIPROCESSOR */
 
 /*
Index: arch/aviion/aviion/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/aviion/aviion/machdep.c,v
retrieving revision 1.10
diff -u -r1.10 machdep.c
--- arch/aviion/aviion/machdep.c 6 Jun 2007 17:15:11 -0000 1.10
+++ arch/aviion/aviion/machdep.c 25 Sep 2007 09:53:40 -0000
@@ -225,8 +225,6 @@
 {
  caddr_t v;
  int sz, i;
- vsize_t size;
- int base, residual;
  vaddr_t minaddr, maxaddr;
 
  /*
@@ -605,19 +603,18 @@
 secondary_main()
 {
  struct cpu_info *ci = curcpu();
+ int s;
 
  cpu_configuration_print(0);
+ sched_init_cpu(ci);
  ncpus++;
  __cpu_simple_unlock(&cpu_mutex);
 
  microuptime(&ci->ci_schedstate.spc_runtime);
  ci->ci_curproc = NULL;
 
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 
 #endif /* MULTIPROCESSOR */
Index: arch/hp300/hp300/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/hp300/hp300/locore.s,v
retrieving revision 1.60
diff -u -r1.60 locore.s
--- arch/hp300/hp300/locore.s 15 May 2007 13:46:22 -0000 1.60
+++ arch/hp300/hp300/locore.s 25 Sep 2007 09:53:41 -0000
@@ -1345,51 +1345,18 @@
  */
 #include <m68k/m68k/support.s>
 
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
  .data
 GLOBAL(curpcb)
  .long 0
 
 ASBSS(nullpcb,SIZEOF_PCB)
 
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and deallocate the process's resources.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- /* save state into garbage pcb */
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
-        /* Schedule the vmspace and stack to be freed. */
- movl    a0,sp@-                 | exit2(p)
- jbsr    _C_LABEL(exit2)
- lea     sp@(4),sp               | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
  stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
 
 /*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  *
  * NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
  * entire ATC.  The effort involved in selective flushing may not be
@@ -1399,55 +1366,15 @@
  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
  * bit).  For now, we just always flush the full ATC.
  */
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
 
  /*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
  * Save state of previous process in its pcb.
  */
  movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
  moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
  movl usp,a2 | grab USP (a2 has been saved)
  movl a2,a1@(PCB_USP) | and save it
@@ -1460,16 +1387,12 @@
  jeq Lswnofpsave | yes, all done
  fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
  fmovem fpcr/fpsr/fpi,a2@(FPF_FPCR) | save FP control registers
+
 Lswnofpsave:
+ movl sp@(8), a0 | newproc
 
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl a0, CURPROC
  movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
  movl a0@(P_ADDR),a1 | get p_addr
  movl a1,_C_LABEL(curpcb)
 
Index: arch/hp300/hp300/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/hp300/hp300/vm_machdep.c,v
retrieving revision 1.43
diff -u -r1.43 vm_machdep.c
--- arch/hp300/hp300/vm_machdep.c 27 May 2007 20:59:25 -0000 1.43
+++ arch/hp300/hp300/vm_machdep.c 25 Sep 2007 09:53:41 -0000
@@ -133,10 +133,10 @@
 cpu_exit(p)
  struct proc *p;
 {
+ (void)splhigh();
 
- (void) splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/hppa/hppa/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/genassym.cf,v
retrieving revision 1.30
diff -u -r1.30 genassym.cf
--- arch/hppa/hppa/genassym.cf 14 May 2007 19:54:21 -0000 1.30
+++ arch/hppa/hppa/genassym.cf 25 Sep 2007 09:53:41 -0000
@@ -130,8 +130,6 @@
 
 # proc fields and values
 struct proc
-member p_forw
-member p_back
 member p_addr
 member p_priority
 member p_stat
Index: arch/hppa/hppa/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/locore.S,v
retrieving revision 1.155
diff -u -r1.155 locore.S
--- arch/hppa/hppa/locore.S 20 Jul 2007 22:09:23 -0000 1.155
+++ arch/hppa/hppa/locore.S 25 Sep 2007 09:53:42 -0000
@@ -2771,171 +2771,23 @@
  copy r0, ret0
 EXIT(spstrcpy)
 
- .import whichqs, data
- .import qs, data
 /*
- * setrunqueue(struct proc *p);
- * Insert a process on the appropriate queue.  Should be called at splclock().
+ * int cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
  */
  .align 32
-ENTRY(setrunqueue,0)
-#ifdef DIAGNOSTIC
- ldw P_BACK(arg0), t1
- comb,<>,n r0, t1, Lsetrunqueue_panic
- ldw P_WCHAN(arg0), t1
- comb,<>,n r0, t1, Lsetrunqueue_panic
- ldb P_STAT(arg0), t1
- comib,=,n SRUN, t1, Lsetrunqueue_ok
-Lsetrunqueue_panic
- copy arg0, arg1
- ldil L%panic, r1
- ldil L%Lsrqpstr, arg0
- ldo R%panic(r1), r1
- ldo R%Lsrqpstr(arg0), arg0
- .call
- blr %r0, rp
- bv,n %r0(r1)
- nop
-Lsrqpstr
- .asciz "setrunqueue(%p)"
- .align 8
-Lsetrunqueue_ok
-#endif
-
- ldb P_PRIORITY(arg0), t2
- ldil L%qs, t4
- extru t2, 29, 5, t1
- ldo R%qs(t4), t4
- sh3add t1, t4, t4
- ldil L%whichqs, arg3
- ldw P_BACK(t4), t2
- stw t4, P_FORW(arg0)
- stw arg0, P_BACK(t4)
- ldw R%whichqs(arg3), t3
- stw arg0, P_FORW(t2)
- mtctl t1, sar
- stw t2, P_BACK(arg0)
- vdepi 1, 1, t3
- bv 0(rp)
- stw t3, R%whichqs(arg3)
-EXIT(setrunqueue)
-
-/*
- * remrunqueue(struct proc *p);
- * Remove a process from its queue.  Should be called at splclock().
- */
- .align 32
-ENTRY(remrunqueue,0)
- ldb P_PRIORITY(arg0), t2
- extru t2, 29, 5, arg2
- ldil L%whichqs, t2
- mtsar arg2
- ldw R%whichqs(t2), t3
-
-#ifdef DIAGNOSTIC
- bvb,<,n t3, remrunqueue_ok
-
-Lremrunqueue_panic
- copy arg0, arg1
- ldil L%panic, r1
- ldil L%Lrrqpstr, arg0
- ldo R%panic(r1), r1
- ldo R%Lrrqpstr(arg0), arg0
- .call
- blr %r0, rp
- bv,n %r0(r1)
- nop
-
-Lrrqpstr
- .asciz "remrunqueue(%p), bit=%x"
- .align 8
-remrunqueue_ok
-#endif
- ldw P_BACK(arg0), t4
- stw r0, P_BACK(arg0)
- ldw P_FORW(arg0), arg0
- stw arg0, P_FORW(t4)
- vdepi 0, 1, t3
- sub,<> t4, arg0, r0
- stw t3, R%whichqs(t2)
- bv 0(rp)
- stw t4, P_BACK(arg0)
-EXIT(remrunqueue)
-
-/*
- * cpu_switch()
- * Find the highest priority process and resume it.
- */
- .align 32
-ENTRY(cpu_switch,128)
- ldil L%cpl, t1
- ldw R%cpl(t1), ret0
+ENTRY(cpu_switchto,128)
  copy r3, r1
  stw rp, HPPA_FRAME_CRP(sp)
  copy sp, r3
- stw ret0, HPPA_FRAME_SL(sp)
  stwm r1, HPPA_FRAME_SIZE+20*4(sp)
 
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- */
- ldil L%curproc, t1
- ldw R%curproc(t1), arg2
- b switch_search
- stw r0, R%curproc(t1)
- /* remain on the old (curproc)'s stack until we have a better choice */
-
-cpu_idle
- copy r0, arg0
- break HPPA_BREAK_KERNEL, HPPA_BREAK_SPLLOWER
- .import uvm, data
- ldil L%(uvm + PAGE_IDLE_ZERO), t3
- ldw R%(uvm + PAGE_IDLE_ZERO)(t3), t4
- sub,<> r0, t4, r0
- b cpu_loop
-
- stw arg2, 4(r3)
- ldil L%uvm_pageidlezero, t1
- ldo R%uvm_pageidlezero(t1), t2
- .call
- ble 0(sr0, t2)
- copy r31, rp
-
- ldw HPPA_FRAME_SL(r3), ret0
- ldw 4(r3), arg2
-
-cpu_loop
- ldil L%cpl, arg0
- stw ret0, R%cpl(arg0)
-
-switch_search
- /*
- * t1:   &whichqs
- * arg2: old curproc
- *
- */
- ldil L%whichqs, t1
- ldw R%whichqs(t1), t3
- comb,=,n r0, t3, cpu_idle
- copy r0, arg0
-
- ldi 0, t4
-getbit
- mtsar t4
- bvb,>=,n t3, getbit
- ldo 1(t4), t4
-
- ldil L%qs, t2
- ldo R%qs(t2), t2
- sh3add t4, t2, t2
-
- ldw P_FORW(t2), arg1
 #ifdef DIAGNOSTIC
- comb,<> t2, arg1, link_ok
+ b kstack_check
  nop
 switch_error
- copy t4, arg1
- copy t2, arg2
+ copy arg1, arg2
+ copy arg0, arg1
  ldil L%panic, r1
  ldil L%Lcspstr, arg0
  ldo R%panic(r1), r1
@@ -2945,61 +2797,48 @@
  bv,n %r0(r1)
  nop
 Lcspstr
- .asciz "cpu_switch: bit=%x, q/p=%p"
+ .asciz "cpu_switch:old=%p, new=%p"
  .align 8
-link_ok
-#endif
- ldil L%want_resched, t4
- stw r0, R%want_resched(t4)
-
- ldw P_FORW(arg1), arg0
- stw arg0, P_FORW(t2)
- stw t2, P_BACK(arg0)
- stw r0, P_BACK(arg1)
-
- vdepi 0, 1, t3
- sub,<> t2, arg0, r0
- stw t3, R%whichqs(t1)
-
- /* don't need &whichqs (t1) starting here */
-#ifdef DIAGNOSTIC
+kstack_check
  ldw P_WCHAN(arg1), t1
  comb,<>,n r0, t1, switch_error
- copy arg1, t2
+ nop
  ldb P_STAT(arg1), t1
  comib,<>,n SRUN, t1, switch_error
- copy arg1, t2
+ nop
  /*
- * Either we must be switching to the same process, or
- * the new process' kernel stack must be reasonable.
+ * The new process' kernel stack must be reasonable.
  */
- comb,=,n arg1, arg2, kstack_ok
- ldw     P_ADDR(arg1), arg0
- ldw U_PCB+PCB_KSP(arg0), t1
- ldo     NBPG(arg0), arg0
- comb,>>,n arg0, t1, switch_error
- copy    arg1, t2
- sub     t1, arg0, t1
- ldil    L%USPACE, arg0
- ldo     R%USPACE(arg0), arg0
- comb,<<=,n arg0, t1, switch_error
- copy    arg1, t2
+ ldw     P_ADDR(arg1), arg2
+ ldw U_PCB+PCB_KSP(arg2), t1
+ ldo     NBPG(arg2), arg2
+ comb,>>,n arg2, t1, switch_error
+ nop
+ sub     t1, arg2, t1
+ ldil    L%USPACE, arg2
+ ldo     R%USPACE(arg2), arg2
+ comb,<<=,n arg2, t1, switch_error
+ nop
 kstack_ok
 #endif
+ ldil L%want_resched, t4
+ stw r0, R%want_resched(t4)
+
+ /* Record new proc. */
  ldi SONPROC, t1
  stb t1, P_STAT(arg1)
- /* Skip context switch if same process. */
- comb,=,n arg1, arg2, switch_return
+ ldil L%curproc, t1
+ stw arg1, R%curproc(t1)
 
  /* If old process exited, don't bother. */
- comb,=,n r0, arg2, switch_exited
+ comb,=,n r0, arg0, switch_exited
 
  /*
  * 2. save old proc context
  *
- * arg2: old proc
+ * arg0: old proc
  */
- ldw P_ADDR(arg2), t1
+ ldw P_ADDR(arg0), t1
  /* save callee-save registers */
  stw r4,   1*4(r3)
  stw sp, U_PCB+PCB_KSP(t1)
@@ -3021,13 +2860,14 @@
  stw r0, HPPA_FRAME_ARG(1)(sp) /* say no trampoline */
  sync
 
- /* don't need old curproc (arg2) starting from here */
+ /* don't need old curproc (arg0) starting from here */
 switch_exited
  /*
  * 3. restore new proc context
  *
  * arg1: new proc
  */
+ /* XXX disable interrupts? */
  ldw P_ADDR(arg1), t2
  ldw P_MD_REGS(arg1), t1
  ldw U_PCB+PCB_KSP(t2), sp
@@ -3036,11 +2876,12 @@
  ldw TF_CR9(t1), t3
  mtctl t2, cr30
  mtctl t3, pidr2
+ /* XXX enable interrupts? */
  ldo -(HPPA_FRAME_SIZE+20*4)(sp), r3
  ldw HPPA_FRAME_ARG(0)(sp), arg0
  ldw HPPA_FRAME_ARG(1)(sp), t4 /* in case we're on trampoline */
  sub,= r0, t4, r0
- b switch_gonnajump
+ b switch_return
  ldw 1*4(r3), r4
  ldw 2*4(r3), r5
  ldw 3*4(r3), r6
@@ -3056,21 +2897,31 @@
  ldw 13*4(r3), r16
  ldw 14*4(r3), r17
  ldw 15*4(r3), r18
-switch_gonnajump
- ldw HPPA_FRAME_SL(r3), ret0
- ldil L%cpl, t1
- stw ret0, R%cpl(t1)
- sync
 
 switch_return
- ldil L%curproc, t1
- stw arg1, R%curproc(t1)
  ldw HPPA_FRAME_CRP(r3), rp
  bv 0(rp)
  ldwm -(HPPA_FRAME_SIZE+20*4)(sp), r3
-EXIT(cpu_switch)
+EXIT(cpu_switchto)
+
+LEAF_ENTRY(cpu_idle_enter)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_enter)
+
+LEAF_ENTRY(cpu_idle_cycle)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_cycle)
+
+LEAF_ENTRY(cpu_idle_leave)
+ bv 0(rp)
+ nop
+EXIT(cpu_idle_leave)
 
 ENTRY(switch_trampoline,0)
+ ldil L%cpl, t1
+ stw r0, R%cpl(t1)
  .call
  blr r0, rp
  bv,n r0(t4)
Index: arch/hppa/hppa/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/vm_machdep.c,v
retrieving revision 1.61
diff -u -r1.61 vm_machdep.c
--- arch/hppa/hppa/vm_machdep.c 20 Jun 2007 17:29:34 -0000 1.61
+++ arch/hppa/hppa/vm_machdep.c 25 Sep 2007 09:53:43 -0000
@@ -160,12 +160,11 @@
  tf->tf_sp = (register_t)stack;
 
  /*
- * Build stack frames for the cpu_switch & co.
+ * Build stack frames for the cpu_switchto & co.
  */
  osp = sp + HPPA_FRAME_SIZE;
  *(register_t*)(osp - HPPA_FRAME_SIZE) = 0;
  *(register_t*)(osp + HPPA_FRAME_CRP) = (register_t)&switch_trampoline;
- *(register_t*)(osp + HPPA_FRAME_SL) = 0; /* cpl */
  *(register_t*)(osp) = (osp - HPPA_FRAME_SIZE);
 
  sp = osp + HPPA_FRAME_SIZE + 20*4; /* frame + calee-save registers */
@@ -187,8 +186,8 @@
  fpu_curpcb = 0;
  }
 
- exit2(p);
- cpu_switch(p);
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 void
Index: arch/hppa/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v
retrieving revision 1.51
diff -u -r1.51 cpu.h
--- arch/hppa/include/cpu.h 20 Jul 2007 22:12:39 -0000 1.51
+++ arch/hppa/include/cpu.h 25 Sep 2007 09:53:43 -0000
@@ -64,6 +64,7 @@
 
 #ifndef _LOCORE
 #ifdef _KERNEL
+#include <sys/queue.h>
 #include <sys/sched.h>
 
 struct cpu_info {
Index: arch/i386/i386/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/cpu.c,v
retrieving revision 1.25
diff -u -r1.25 cpu.c
--- arch/i386/i386/cpu.c 29 May 2007 18:18:20 -0000 1.25
+++ arch/i386/i386/cpu.c 25 Sep 2007 09:53:43 -0000
@@ -274,6 +274,7 @@
  identifycpu(ci);
  cpu_init(ci);
 
+ sched_init_cpu(ci);
 #if NLAPIC > 0
  /*
  * Enable local apic
@@ -295,6 +296,7 @@
  cpu_alloc_ldt(ci);
  ci->ci_flags |= CPUF_PRESENT | CPUF_AP;
  identifycpu(ci);
+ sched_init_cpu(ci);
  ci->ci_next = cpu_info_list->ci_next;
  cpu_info_list->ci_next = ci;
  ncpus++;
@@ -463,6 +465,9 @@
     ci->ci_dev.dv_xname, ci->ci_cpuid);
  microuptime(&ci->ci_schedstate.spc_runtime);
  splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 
 void
Index: arch/i386/i386/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/genassym.cf,v
retrieving revision 1.26
diff -u -r1.26 genassym.cf
--- arch/i386/i386/genassym.cf 3 Apr 2007 10:14:47 -0000 1.26
+++ arch/i386/i386/genassym.cf 25 Sep 2007 09:53:43 -0000
@@ -88,8 +88,6 @@
 # proc fields and values
 struct proc
 member p_addr
-member p_back
-member p_forw
 member p_priority
 member p_stat
 member p_wchan
Index: arch/i386/i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
retrieving revision 1.114
diff -u -r1.114 locore.s
--- arch/i386/i386/locore.s 29 May 2007 23:02:02 -0000 1.114
+++ arch/i386/i386/locore.s 25 Sep 2007 09:53:44 -0000
@@ -1295,279 +1295,52 @@
  ret
 
 /*****************************************************************************/
-
-/*
- * The following primitives manipulate the run queues.
- * whichqs tells which of the 32 queues qs have processes in them.
- * Setrq puts processes into queues, Remrq removes them from queues.
- * The running process is on no queue, other processes are on a queue
- * related to p->p_pri, divided by 4 actually to shrink the 0-127 range
- * of priorities into the 32 available queues.
- */
- .globl _C_LABEL(whichqs),_C_LABEL(qs),_C_LABEL(uvmexp),_C_LABEL(panic)
-/*
- * setrunqueue(struct proc *p);
- * Insert a process on the appropriate queue.  Should be called at splclock().
- */
-NENTRY(setrunqueue)
- movl 4(%esp),%eax
-#ifdef DIAGNOSTIC
- cmpl $0,P_BACK(%eax) # should not be on q already
- jne 1f
- cmpl $0,P_WCHAN(%eax)
- jne 1f
- cmpb $SRUN,P_STAT(%eax)
- jne 1f
-#endif /* DIAGNOSTIC */
- movzbl P_PRIORITY(%eax),%edx
- shrl $2,%edx
- btsl %edx,_C_LABEL(whichqs) # set q full bit
- leal _C_LABEL(qs)(,%edx,8),%edx # locate q hdr
- movl P_BACK(%edx),%ecx
- movl %edx,P_FORW(%eax) # link process on tail of q
- movl %eax,P_BACK(%edx)
- movl %eax,P_FORW(%ecx)
- movl %ecx,P_BACK(%eax)
- ret
-#ifdef DIAGNOSTIC
-1: pushl $2f
- call _C_LABEL(panic)
- /* NOTREACHED */
-2: .asciz "setrunqueue"
-#endif /* DIAGNOSTIC */
-
-/*
- * remrunqueue(struct proc *p);
- * Remove a process from its queue.  Should be called at splclock().
- */
-NENTRY(remrunqueue)
- movl 4(%esp),%ecx
- movzbl P_PRIORITY(%ecx),%eax
-#ifdef DIAGNOSTIC
- shrl $2,%eax
- btl %eax,_C_LABEL(whichqs)
- jnc 1f
-#endif /* DIAGNOSTIC */
- movl P_BACK(%ecx),%edx # unlink process
- movl $0,P_BACK(%ecx) # zap reverse link to indicate off list
- movl P_FORW(%ecx),%ecx
- movl %ecx,P_FORW(%edx)
- movl %edx,P_BACK(%ecx)
- cmpl %ecx,%edx # q still has something?
- jne 2f
-#ifndef DIAGNOSTIC
- shrl $2,%eax
-#endif
- btrl %eax,_C_LABEL(whichqs) # no; clear bit
-2: ret
+
 #ifdef DIAGNOSTIC
-1: pushl $3f
+NENTRY(switch_error1)
+ pushl %edi
+ pushl $1f
  call _C_LABEL(panic)
  /* NOTREACHED */
-3: .asciz "remrunqueue"
-#endif /* DIAGNOSTIC */
-
-#if NAPM > 0
- .globl _C_LABEL(apm_cpu_idle),_C_LABEL(apm_cpu_busy)
-#endif
-/*
- * When no processes are on the runq, cpu_switch() branches to here to wait for
- * something to come ready.
- */
-ENTRY(idle)
- /* Skip context saving if we have none. */
- testl %esi,%esi
- jz 1f
-
- /*
- * idling: save old context.
- *
- * Registers:
- *   %eax, %ebx, %ecx - scratch
- *   %esi - old proc, then old pcb
- *   %edi - idle pcb
- *   %edx - idle TSS selector
- */
-
- pushl %esi
- call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc)
- addl $4,%esp
-
- movl P_ADDR(%esi),%esi
-
- /* Save stack pointers. */
- movl %esp,PCB_ESP(%esi)
- movl %ebp,PCB_EBP(%esi)
-
- /* Find idle PCB for this CPU */
-#ifndef MULTIPROCESSOR
- movl $_C_LABEL(proc0),%ebx
- movl P_ADDR(%ebx),%edi
- movl P_MD_TSS_SEL(%ebx),%edx
-#else
- movl CPUVAR(IDLE_PCB), %edi
- movl CPUVAR(IDLE_TSS_SEL), %edx
-#endif
-
- /* Restore the idle context (avoid interrupts) */
- cli
-
- /* Restore stack pointers. */
- movl PCB_ESP(%edi),%esp
- movl PCB_EBP(%edi),%ebp
-
-
- /* Switch address space. */
- movl PCB_CR3(%edi),%ecx
- movl %ecx,%cr3
-
- /* Switch TSS. Reset "task busy" flag before loading. */
- movl CPUVAR(GDT), %eax
- andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
- ltr %dx
-
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%edi),%ecx
- movl %ecx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%edi)
-
- xorl %esi,%esi
- sti
-
-1:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle)
-#endif
-
- movl $IPL_NONE,CPL # spl0()
- call _C_LABEL(Xspllower) # process pending interrupts
- jmp _C_LABEL(idle_start)
-
-ENTRY(idle_loop)
-#if NAPM > 0
- call _C_LABEL(apm_cpu_idle)
-#else
-#if NPCTR > 0
- addl $1,_C_LABEL(pctr_idlcnt)
- adcl $0,_C_LABEL(pctr_idlcnt)+4
-#endif
- sti
- hlt
-#endif
-ENTRY(idle_start)
- cli
- cmpl $0,_C_LABEL(whichqs)
- jz _C_LABEL(idle_loop)
-
-ENTRY(idle_exit)
- movl $IPL_HIGH,CPL # splhigh
- sti
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle)
-#endif
-#if NAPM > 0
- call _C_LABEL(apm_cpu_busy)
-#endif
- jmp switch_search
-
-#ifdef DIAGNOSTIC
-NENTRY(switch_error)
+1: .asciz "cpu_switch1 %p"
+NENTRY(switch_error2)
+ pushl %edi
  pushl $1f
  call _C_LABEL(panic)
  /* NOTREACHED */
-1: .asciz "cpu_switch"
+1: .asciz "cpu_switch2 %p"
 #endif /* DIAGNOSTIC */
 
 /*
- * cpu_switch(void);
- * Find a runnable process and switch to it.  Wait if necessary.  If the new
- * process is the same as the old one, we short-circuit the context save and
- * restore.
+ * cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from the "old" proc to the "new" proc. If "old" is NULL, we
+ * don't need to bother saving old context.
  */
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
  pushl %ebx
  pushl %esi
  pushl %edi
- pushl CPL
 
- movl CPUVAR(CURPROC), %esi
+ movl 16(%esp), %esi
+ movl 20(%esp), %edi
 
- /*
- * Clear curproc so that we don't accumulate system time while idle.
- * This also insures that schedcpu() will move the old process to
- * the correct queue if it happens to get called from the spllower()
- * below and changes the priority.  (See corresponding comment in
- * userret()).
- */
- movl $0, CPUVAR(CURPROC)
-
-switch_search:
- /*
- * First phase: find new process.
- *
- * Registers:
- *   %eax - queue head, scratch, then zero
- *   %ebx - queue number
- *   %ecx - cached value of whichqs
- *   %edx - next process in queue
- *   %esi - old process
- *   %edi - new process
- */
+ xorl %eax, %eax
 
- /* Wait for new process. */
- movl _C_LABEL(whichqs),%ecx
- bsfl %ecx,%ebx # find a full q
- jz _C_LABEL(idle) # if none, idle
- leal _C_LABEL(qs)(,%ebx,8),%eax # select q
- movl P_FORW(%eax),%edi # unlink from front of process q
-#ifdef DIAGNOSTIC
- cmpl %edi,%eax # linked to self (i.e. nothing queued)?
- je _C_LABEL(switch_error) # not possible
-#endif /* DIAGNOSTIC */
- movl P_FORW(%edi),%edx
- movl %edx,P_FORW(%eax)
- movl %eax,P_BACK(%edx)
-
- cmpl %edx,%eax # q empty?
- jne 3f
-
- btrl %ebx,%ecx # yes, clear to indicate empty
- movl %ecx,_C_LABEL(whichqs) # update q status
-
-3: xorl %eax, %eax
- /* We just did it. */
- movl $0, CPUVAR(RESCHED)
+ movl %eax, CPUVAR(RESCHED)
 
 #ifdef DIAGNOSTIC
  cmpl %eax,P_WCHAN(%edi) # Waiting for something?
- jne _C_LABEL(switch_error) # Yes; shouldn't be queued.
+ jne _C_LABEL(switch_error1) # Yes; shouldn't be queued.
  cmpb $SRUN,P_STAT(%edi) # In run state?
- jne _C_LABEL(switch_error) # No; shouldn't be queued.
+ jne _C_LABEL(switch_error2) # No; shouldn't be queued.
 #endif /* DIAGNOSTIC */
 
- /* Isolate process.  XXX Is this necessary? */
- movl %eax,P_BACK(%edi)
-
- /* Record new process. */
- movb $SONPROC,P_STAT(%edi) # p->p_stat = SONPROC
- movl CPUVAR(SELF), %ecx
- movl %edi, CPUVAR(CURPROC)
- movl %ecx, P_CPU(%edi)
-
- /* Skip context switch if same process. */
- cmpl %edi,%esi
- je switch_return
-
  /* If old process exited, don't bother. */
  testl %esi,%esi
  jz switch_exited
 
  /*
- * Second phase: save old context.
+ * Save old context.
  *
  * Registers:
  *   %eax, %ecx - scratch
@@ -1597,18 +1370,19 @@
 
  /* No interrupts while loading new state. */
  cli
+
+ /* Record new process. */
+ movl CPUVAR(SELF), %ebx
+ movl %edi, CPUVAR(CURPROC)
+ movb $SONPROC, P_STAT(%edi)
+ movl %ebx, P_CPU(%edi)
+
  movl P_ADDR(%edi),%esi
 
  /* Restore stack pointers. */
  movl PCB_ESP(%esi),%esp
  movl PCB_EBP(%esi),%ebp
 
-#if 0
- /* Don't bother with the rest if switching to a system process. */
- testl $P_SYSTEM,P_FLAG(%edi)
- jnz switch_restored
-#endif
-
  /*
  * Activate the address space.  We're curproc, so %cr3 will
  * be reloaded, but we're not yet curpcb, so the LDT won't
@@ -1639,7 +1413,6 @@
  lldt %dx
 #endif /* USER_LDT */
 
-switch_restored:
  /* Restore cr0 (including FPU state). */
  movl PCB_CR0(%esi),%ecx
 #ifdef MULTIPROCESSOR
@@ -1661,103 +1434,29 @@
  /* Interrupts are okay again. */
  sti
 
-switch_return:
-#if 0
- pushl %edi
- movl CPUVAR(NAME), %ebx
- leal CPU_INFO_NAME(%ebx),%ebx
- pushl %ebx
- pushl $1f
- call _C_LABEL(printf)
- addl $0xc,%esp
-#endif
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call    _C_LABEL(sched_unlock_idle)
-#endif
- /*
- * Restore old cpl from stack.  Note that this is always an increase,
- * due to the spl0() on entry.
- */
- popl CPL
-
- movl %edi,%eax # return (p);
  popl %edi
  popl %esi
  popl %ebx
  ret
-1: .asciz "%s: scheduled %x\n"
-/*
- * switch_exit(struct proc *p);
- * Switch to the appropriate idle context (proc0's if uniprocessor; the cpu's if
- * multiprocessor) and deallocate the address space and kernel stack for p.
- * Then jump into cpu_switch(), as if we were in the idle proc all along.
- */
-#ifndef MULTIPROCESSOR
- .globl _C_LABEL(proc0)
-#endif
-ENTRY(switch_exit)
- movl 4(%esp),%edi # old process
-#ifndef MULTIPROCESSOR
- movl $_C_LABEL(proc0),%ebx
- movl P_ADDR(%ebx),%esi
- movl P_MD_TSS_SEL(%ebx),%edx
-#else
- movl CPUVAR(IDLE_PCB), %esi
- movl CPUVAR(IDLE_TSS_SEL), %edx
-#endif
 
- /* In case we fault... */
- movl $0, CPUVAR(CURPROC)
-
- /* Restore the idle context. */
- cli
-
- /* Restore stack pointers. */
- movl PCB_ESP(%esi),%esp
- movl PCB_EBP(%esi),%ebp
-
- /* Load TSS info. */
- movl CPUVAR(GDT), %eax
-
- /* Switch address space. */
- movl PCB_CR3(%esi),%ecx
- movl %ecx,%cr3
-
- /* Switch TSS. */
- andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
- ltr %dx
-
- /* We're always in the kernel, so we don't need the LDT. */
-
- /* Clear segment registers; always null in proc0. */
- xorl %ecx,%ecx
- movw %cx,%gs
-
- /* Point to cpu_info */
- movl $GSEL(GCPU_SEL, SEL_KPL),%ecx
- movw %cx,%fs
-
- /* Restore cr0 (including FPU state). */
- movl PCB_CR0(%esi),%ecx
- movl %ecx,%cr0
-
- /* Record new pcb. */
- SET_CURPCB(%esi)
+ENTRY(cpu_idle_enter)
+ ret
 
- /* Interrupts are okay again. */
+ENTRY(cpu_idle_cycle)
+#if NAPM > 0
+ call _C_LABEL(apm_cpu_idle)
+#else
+#if NPCTR > 0
+ addl $1,_C_LABEL(pctr_idlcnt)
+ adcl $0,_C_LABEL(pctr_idlcnt)+4
+#endif
  sti
+ hlt
+#endif
+ ret
 
- /*
- * Schedule the dead process's vmspace and stack to be freed.
- */
- pushl %edi /* exit2(p) */
- call _C_LABEL(exit2)
- addl $4,%esp
-
- /* Jump into cpu_switch() with the right state. */
- xorl %esi,%esi
- movl $0, CPUVAR(CURPROC)
- jmp switch_search
+ENTRY(cpu_idle_leave)
+ ret
 
 /*
  * savectx(struct pcb *pcb);
Index: arch/i386/i386/mptramp.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/mptramp.s,v
retrieving revision 1.8
diff -u -r1.8 mptramp.s
--- arch/i386/i386/mptramp.s 20 Feb 2007 21:15:01 -0000 1.8
+++ arch/i386/i386/mptramp.s 25 Sep 2007 09:53:44 -0000
@@ -249,9 +249,7 @@
  HALTT(0x30,%ecx)
  pushl %ecx
  call _C_LABEL(cpu_hatch)
- HALT(0x33)
- xorl %esi,%esi
- jmp _C_LABEL(idle_start)
+ /* NOTREACHED */
 
  .data
 _C_LABEL(mp_pdirpa):
Index: arch/i386/i386/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/vm_machdep.c,v
retrieving revision 1.52
diff -u -r1.52 vm_machdep.c
--- arch/i386/i386/vm_machdep.c 27 May 2007 20:59:25 -0000 1.52
+++ arch/i386/i386/vm_machdep.c 25 Sep 2007 09:53:44 -0000
@@ -126,7 +126,6 @@
  tf->tf_esp = (u_int)stack + stacksize;
 
  sf = (struct switchframe *)tf - 1;
- sf->sf_ppl = 0;
  sf->sf_esi = (int)func;
  sf->sf_ebx = (int)arg;
  sf->sf_eip = (int)proc_trampoline;
@@ -151,7 +150,7 @@
 #endif
 
  pmap_deactivate(p);
- switch_exit(p);
+ sched_exit(p);
 }
 
 void
Index: arch/i386/include/frame.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/frame.h,v
retrieving revision 1.8
diff -u -r1.8 frame.h
--- arch/i386/include/frame.h 27 Nov 2006 18:04:28 -0000 1.8
+++ arch/i386/include/frame.h 25 Sep 2007 09:53:44 -0000
@@ -106,7 +106,6 @@
  * Stack frame inside cpu_switch()
  */
 struct switchframe {
- int sf_ppl;
  int sf_edi;
  int sf_esi;
  int sf_ebx;
Index: arch/luna88k/luna88k/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/luna88k/luna88k/locore.S,v
retrieving revision 1.13
diff -u -r1.13 locore.S
--- arch/luna88k/luna88k/locore.S 12 Jan 2007 21:41:53 -0000 1.13
+++ arch/luna88k/luna88k/locore.S 25 Sep 2007 09:53:45 -0000
@@ -150,8 +150,8 @@
  * Now we will compete with the other processors to see which one
  * will be elected as the main one.
  */
- or.u r11, r0,  hi16(_ASM_LABEL(cpu_mutex))
- or r11, r11, lo16(_ASM_LABEL(cpu_mutex))
+ or.u r11, r0,  hi16(_C_LABEL(cpu_mutex))
+ or r11, r11, lo16(_C_LABEL(cpu_mutex))
 1:
  FLUSH_PIPELINE
  or r22, r0,  1
@@ -282,15 +282,6 @@
  bsr.n _C_LABEL(secondary_pre_main) /* set cpu number */
  or r31, r31, lo16(_ASM_LABEL(slavestack_end))
 
- /*
- * Release cpu_mutex; we have a race with other secondary CPUs here
- * because the stack has not been switched yet. However, since our
- * interrupts are disabled, the worst we can get is an NMI, and, oh
- * well, it means we're in deep trouble anyway.
- */
- or.u r10, r0, hi16(_ASM_LABEL(cpu_mutex))
- st r0, r10, lo16(_ASM_LABEL(cpu_mutex))
-
  ldcr r2, CPU
 1:
  ld r3, r2, CI_CURPCB
@@ -299,13 +290,6 @@
  br.n _C_LABEL(secondary_main)
  add r31, r3, USIZE /* switch to idle stack */
 
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_search)
 #else
 
  /*
@@ -315,15 +299,6 @@
 
 #endif /* MULTIPROCESSOR */
 
- /*
- * Release the cpu_mutex; secondary processors will now have their
- * chance to initialize.
- */
-GLOBAL(cpu_boot_secondary_processors)
- or.u r2,  r0,  hi16(_ASM_LABEL(cpu_mutex))
- jmp.n r1
- st r0,  r2,  lo16(_ASM_LABEL(cpu_mutex))
-
 /*
  * void delay(int count)
  *
@@ -382,10 +357,6 @@
 
 /* The first processor that XMEMs this becomes the master */
 ASLOCAL(master_mpu)
- word 0
-
-/* XMEM spin lock -- controls access to master_mpu */
-ASLOCAL(cpu_mutex)
  word 0
 
 #if defined(DDB) || NKSYMS > 0
Index: arch/luna88k/luna88k/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/luna88k/luna88k/machdep.c,v
retrieving revision 1.44
diff -u -r1.44 machdep.c
--- arch/luna88k/luna88k/machdep.c 6 Jun 2007 17:15:12 -0000 1.44
+++ arch/luna88k/luna88k/machdep.c 25 Sep 2007 09:53:46 -0000
@@ -85,6 +85,7 @@
 #include <machine/cmmu.h>
 #include <machine/cpu.h>
 #include <machine/kcore.h>
+#include <machine/lock.h>
 #include <machine/reg.h>
 #include <machine/trap.h>
 #include <machine/m88100.h>
@@ -105,6 +106,7 @@
 
 caddr_t allocsys(caddr_t);
 void consinit(void);
+void cpu_boot_secondary_processors(void);
 void dumpconf(void);
 void dumpsys(void);
 int getcpuspeed(void);
@@ -183,6 +185,8 @@
 struct vm_map *exec_map = NULL;
 struct vm_map *phys_map = NULL;
 
+__cpu_simple_lock_t cpu_mutex = __SIMPLELOCK_UNLOCKED;
+
 /*
  * Declare these as initialized data so we can patch them.
  */
@@ -756,6 +760,16 @@
 #ifdef MULTIPROCESSOR
 
 /*
+ * Release the cpu_mutex; secondary processors will now have their
+ * chance to initialize.
+ */
+void
+cpu_boot_secondary_processors()
+{
+ __cpu_simple_unlock(&cpu_mutex);
+}
+
+/*
  * Secondary CPU early initialization routine.
  * Determine CPU number and set it, then allocate the idle pcb (and stack).
  *
@@ -793,17 +807,18 @@
 secondary_main()
 {
  struct cpu_info *ci = curcpu();
+ int s;
 
  cpu_configuration_print(0);
+ sched_init_cpu(ci);
  ncpus++;
+ __cpu_simple_unlock(&cpu_mutex);
 
  microuptime(&ci->ci_schedstate.spc_runtime);
+ ci->ci_curproc = NULL;
 
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 
 #endif /* MULTIPROCESSOR */
@@ -966,7 +981,6 @@
  cpuid_t cpu;
  extern void m8820x_initialize_cpu(cpuid_t);
  extern void m8820x_set_sapr(cpuid_t, apr_t);
- extern void cpu_boot_secondary_processors(void);
 
  cmmu = &cmmu8820x;
 
Index: arch/m68k/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/m68k/include/cpu.h,v
retrieving revision 1.17
diff -u -r1.17 cpu.h
--- arch/m68k/include/cpu.h 22 May 2007 10:31:08 -0000 1.17
+++ arch/m68k/include/cpu.h 25 Sep 2007 09:53:46 -0000
@@ -66,6 +66,7 @@
 
 #ifdef _KERNEL
 #ifndef _LOCORE
+#include <sys/queue.h>
 #include <sys/sched.h>
 
 struct cpu_info {
@@ -268,6 +269,9 @@
  * This is used during profiling to integrate system time.
  */
 #define PROC_PC(p) (((struct trapframe *)((p)->p_md.md_regs))->tf_pc)
+
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_leave() do { /* nothing */ } while (0)
 
 #endif /* _KERNEL */
 
Index: arch/m68k/m68k/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/m68k/m68k/genassym.cf,v
retrieving revision 1.12
diff -u -r1.12 genassym.cf
--- arch/m68k/m68k/genassym.cf 15 May 2007 13:46:22 -0000 1.12
+++ arch/m68k/m68k/genassym.cf 25 Sep 2007 09:53:46 -0000
@@ -71,15 +71,10 @@
 
 # proc fields and values
 struct proc
-member p_forw
-member p_back
-member p_priority
 member p_stat
-member p_wchan
 member p_vmspace
 member p_addr
 
-export SRUN
 export SONPROC
 
 # contexts
Index: arch/m68k/m68k/proc_subr.s
===================================================================
RCS file: /cvs/src/sys/arch/m68k/m68k/proc_subr.s,v
retrieving revision 1.2
diff -u -r1.2 proc_subr.s
--- arch/m68k/m68k/proc_subr.s 2 Jun 2003 23:27:48 -0000 1.2
+++ arch/m68k/m68k/proc_subr.s 25 Sep 2007 09:53:46 -0000
@@ -1,129 +0,0 @@
-/* $OpenBSD: proc_subr.s,v 1.2 2003/06/02 23:27:48 millert Exp $ */
-/* $NetBSD: proc_subr.s,v 1.2 1997/04/25 02:22:01 thorpej Exp $ */
-
-/*
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1980, 1990, 1993
- * The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: Utah $Hdr: locore.s 1.66 92/12/22$
- *
- * @(#)locore.s 8.6 (Berkeley) 5/27/94
- */
-
-/*
- * Assembly routines related to process manipulation.
- */
-
-/*
- * NOTICE: This is not a standalone file.  To use it, #include it in
- * your port's locore.s, like so:
- *
- * #include <m68k/m68k/proc_subr.s>
- */
-
-/*
- * The following primitives manipulate the run queues.  _whichqs tells which
- * of the 32 queues _qs have processes in them.  Setrunqueue puts processes
- * into queues, remrunqueue removes them from queues.  The running process is
- * on no queue, other processes are on a queue related to p->p_priority,
- * divided by 4 actually to shrink the 0-127 range of priorities into the 32
- * available queues.
- */
-
-/*
- * Setrunqueue(p)
- *
- * Call should be made at spl6(), and p->p_stat should be SRUN
- */
-ENTRY(setrunqueue)
- movl sp@(4),a0
-#ifdef DIAGNOSTIC
- tstl a0@(P_BACK)
- jne Lset1
- tstl a0@(P_WCHAN)
- jne Lset1
- cmpb #SRUN,a0@(P_STAT)
- jne Lset1
-#endif
- clrl d0
- movb a0@(P_PRIORITY),d0
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
- bset d0,d1
- movl d1,_C_LABEL(whichqs)
- lslb #3,d0
- addl #_C_LABEL(qs),d0
- movl d0,a0@(P_FORW)
- movl d0,a1
- movl a1@(P_BACK),a0@(P_BACK)
- movl a0,a1@(P_BACK)
- movl a0@(P_BACK),a1
- movl a0,a1@(P_FORW)
- rts
-#ifdef DIAGNOSTIC
-Lset1:
- PANIC("setrunqueue")
-#endif
-
-/*
- * remrunqueue(p)
- *
- * Call should be made at spl6().
- */
-ENTRY(remrunqueue)
- movl sp@(4),a0
- movb a0@(P_PRIORITY),d0
-#ifdef DIAGNOSTIC
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
- btst d0,d1
- jeq Lrem2
-#endif
- movl a0@(P_BACK),a1
- clrl a0@(P_BACK)
- movl a0@(P_FORW),a0
- movl a0,a1@(P_FORW)
- movl a1,a0@(P_BACK)
- cmpal a0,a1
- jne Lrem1
-#ifndef DIAGNOSTIC
- lsrb #2,d0
- movl _C_LABEL(whichqs),d1
-#endif
- bclr d0,d1
- movl d1,_C_LABEL(whichqs)
-Lrem1:
- rts
-#ifdef DIAGNOSTIC
-Lrem2:
- PANIC("remrunqueue")
-#endif
Index: arch/m88k/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/m88k/include/cpu.h,v
retrieving revision 1.22
diff -u -r1.22 cpu.h
--- arch/m88k/include/cpu.h 19 May 2007 20:34:32 -0000 1.22
+++ arch/m88k/include/cpu.h 25 Sep 2007 09:53:46 -0000
@@ -58,6 +58,7 @@
 #include <machine/pcb.h>
 #include <machine/psl.h>
 #include <machine/intr.h>
+#include <sys/queue.h>
 #include <sys/sched.h>
 
 #if defined(MULTIPROCESSOR)
@@ -164,6 +165,8 @@
  */
 #define cpu_exec(p) do { /* nothing */ } while (0)
 #define cpu_wait(p) do { /* nothing */ } while (0)
+
+#define cpu_idle_cycle() do { /* nothing */ } while (0)
 
 #if defined(MULTIPROCESSOR)
 #include <sys/lock.h>
Index: arch/m88k/m88k/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/m88k/m88k/genassym.cf,v
retrieving revision 1.8
diff -u -r1.8 genassym.cf
--- arch/m88k/m88k/genassym.cf 12 May 2007 19:59:52 -0000 1.8
+++ arch/m88k/m88k/genassym.cf 25 Sep 2007 09:53:46 -0000
@@ -49,15 +49,11 @@
 
 # proc fields and values
 struct proc
-member p_forw
-member p_back
 member p_addr
 member p_stat
-member p_wchan
 member p_cpu
 member P_ASTPENDING p_md.md_astpending
 
-export SRUN
 export SONPROC
 
 # cpu fields
Index: arch/m88k/m88k/m88k_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/m88k/m88k/m88k_machdep.c,v
retrieving revision 1.21
diff -u -r1.21 m88k_machdep.c
--- arch/m88k/m88k/m88k_machdep.c 29 May 2007 18:10:42 -0000 1.21
+++ arch/m88k/m88k/m88k_machdep.c 25 Sep 2007 09:53:46 -0000
@@ -202,50 +202,6 @@
  return (ENAMETOOLONG);
 }
 
-void
-setrunqueue(p)
- struct proc *p;
-{
- struct prochd *q;
- struct proc *oldlast;
- int which = p->p_priority >> 2;
-
-#ifdef DIAGNOSTIC
- if (p->p_back != NULL)
- panic("setrunqueue %p", p);
-#endif
- q = &qs[which];
- whichqs |= 1 << which;
- p->p_forw = (struct proc *)q;
- p->p_back = oldlast = q->ph_rlink;
- q->ph_rlink = p;
- oldlast->p_forw = p;
-}
-
-/*
- * Remove process p from its run queue, which should be the one
- * indicated by its priority.  Calls should be made at splstatclock().
- */
-void
-remrunqueue(vp)
- struct proc *vp;
-{
- struct proc *p = vp;
- int which = p->p_priority >> 2;
- struct prochd *q;
-
-#ifdef DIAGNOSTIC
- if ((whichqs & (1 << which)) == 0)
- panic("remrq %p", p);
-#endif
- p->p_forw->p_back = p->p_back;
- p->p_back->p_forw = p->p_forw;
- p->p_back = NULL;
- q = &qs[which];
- if (q->ph_link == (struct proc *)q)
- whichqs &= ~(1 << which);
-}
-
 #ifdef DDB
 int longformat = 1;
 void
Index: arch/m88k/m88k/process.S
===================================================================
RCS file: /cvs/src/sys/arch/m88k/m88k/process.S,v
retrieving revision 1.16
diff -u -r1.16 process.S
--- arch/m88k/m88k/process.S 12 May 2007 19:59:52 -0000 1.16
+++ arch/m88k/m88k/process.S 25 Sep 2007 09:53:46 -0000
@@ -35,242 +35,63 @@
 #include <machine/psl.h>
 #include <machine/intr.h>
 
-#ifdef DIAGNOSTIC
- data
- align 4
-ASLOCAL(swchanpanic)
- string "switch wchan %x\0"
- align 4
-ASLOCAL(swsrunpanic)
- string "switch SRUN %x\0"
-
- text
- align 8
-ASLOCAL(Lswchanpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swchanpanic))
- or r2, r2, lo16(_ASM_LABEL(swchanpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-
-ASLOCAL(Lswsrunpanic)
- or.u r2, r0, hi16(_ASM_LABEL(swsrunpanic))
- or r2, r2, lo16(_ASM_LABEL(swsrunpanic))
- bsr.n _C_LABEL(panic)
- or r3, r0, r9
-#endif
-
 /*
- * void switch_exit(struct proc *p)
+ * void cpu_idle_enter()
  *
- * Do the final work to exit from a process. After switching to the
- * idle stack and pcb, invoke exit2() on behalf of the exiting process,
- * then continue into cpu_switch() to select another process to run.
+ * Enable all interrupts and lower spl. This actually enables interrupts
+ * in the psr; bootstrap of secondary processors depends on this.
  */
-
-ENTRY(switch_exit)
- /*
- * Disable interrupts since we are about to change the kernel
- * stack.
- */
- ldcr r3, PSR
- set r3, r3, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r3, PSR
+ENTRY(cpu_idle_enter)
+ ldcr r2, PSR
+ clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
+ stcr r2, PSR
  FLUSH_PIPELINE
 
- /*
- * Change pcb to idle u. area, i.e., set r31 to top of stack
- * and set curpcb to point to the cpu's idle stack.
- * r2 contains proc *p.
- */
- ldcr r10, CPU
- ld r30, r10, CI_IDLE_PCB
- addu r31, r30, USIZE /* now on idle stack */
- st r30, r10, CI_CURPCB /* curpcb = idle_pcb */
-
- /* Schedule the vmspace and stack to be freed. */
- bsr.n _C_LABEL(exit2)
- st r0, r10, CI_CURPROC /* curproc = NULL */
-
- /*
- * exit2() has acquired the scheduler lock for us. Jump into
- * cpu_switch(), after the context save since we do not need
- * to save anything.
- */
- br _ASM_LABEL(cpu_switch_search)
+ br.n _C_LABEL(setipl)
+ or r2, r0, IPL_NONE
 
 /*
- * void cpu_switch(struct proc *p)
+ * void cpu_idle_leave()
  *
- * Find a runnable process and switch to it. On entry, the scheduler lock is
- * held; it has to be released before returning to the process.
+ * Raise ipl to IPL_SCHED, but do not attempt to disable interrupts.
+ */
+ENTRY(cpu_idle_leave)
+ br.n _C_LABEL(setipl)
+ or r2, r0, IPL_SCHED
+
+/*
+ * void cpu_switchto(struct proc *oldproc, struct proc *newproc)
  *
- * Note that this code ignores its proc parameter and assumes it has the
- * same value as curproc. This may change in mi_switch() in the future,
- * be careful.
+ * Switch context from oldproc to newproc. oldproc may be NULL if there is
+ * no need to save the current context.
  */
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
  /*
- * Disable interrupts, we do not want to be disturbed while
- * saving context.
+ * Save state of previous process in its pcb if required.
  */
- ldcr r2, PSR
- set r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
+ bcnd eq0, r2, 1f
 
- /*
- * Save state of previous process in its pcb, and pmap_deactivate()
- * the process.
- */
  ldcr r2,  CPU
  ld r2,  r2,  CI_CURPCB
  st r1,  r2,  PCB_PC /* save return address */
  bsr _ASM_LABEL(__savectx)
  /* note that we don't need to recover r1 at this point */
 
+1:
  ldcr r11, CPU
- ld r2,  r11, CI_CURPROC
-
- /*
- * Note that we can still use curpcb as our stack after
- * pmap_deactivate() has been called, as it does not affect the u
- * area mappings.
- */
- bsr.n _C_LABEL(pmap_deactivate)
- st r0,  r11, CI_CURPROC /* curproc = NULL */
-
-#ifdef MULTIPROCESSOR
- /*
- * We need to switch to the processor's idle stack now (in case the
- * process we are using the stack of gets scheduled on another
- * processor).
- */
- ldcr r10, CPU
- ld r30, r10, CI_IDLE_PCB
- addu r31, r30, USIZE /* now on idle stack */
- st r30, r10, CI_CURPCB /* curpcb = idle_pcb */
-#endif
-
-ASLOCAL(cpu_switch_search)
- /*
- * This is the start of the idle loop. Find the highest-priority
- * queue that isn't empty, then take the first proc from that queue.
- */
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd ne0, r7, _ASM_LABEL(cpu_switch_found)
+ st r3,  r11, CI_CURPROC /* curproc = newproc */
 
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr _C_LABEL(sched_unlock_idle)
-#endif
-
-#ifdef MULTIPROCESSOR
-ASGLOBAL(cpu_switch_idle)
-#else
-ASLOCAL(cpu_switch_idle)
-#endif
- /*
- * There were no runnable processes. Enable all interrupts and
- * busy-wait for this to change.
- * Note that, besides doing setipl(IPL_NONE), this will actually enable
- * interrupts in the psr. Bootstrap of secondary processors
- * relies upon this.
- */
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- bsr.n _C_LABEL(setipl)
- or r2, r0, IPL_NONE
-
- or.u r7, r0, hi16(_C_LABEL(whichqs))
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd eq0, r7, _ASM_LABEL(cpu_switch_idle)
- /* XXX run fancy things here, such as page zeroing... */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr _C_LABEL(sched_lock_idle)
-#endif
-
-ASLOCAL(cpu_switch_found)
- /*
- * Disable interrupts.
- */
- ldcr r2, PSR
- set r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- /*
- * An interrupt could have occured between the last whichqs check
- * and the call to setipl(). Check again that whichqs is nonzero.
- */
- or.u r7, r0, hi16(_C_LABEL(whichqs)) /* reload whichqs */
- ld r7, r7, lo16(_C_LABEL(whichqs))
- bcnd eq0, r7, _ASM_LABEL(cpu_switch_search)
-
- /* XXX use ff1, like powerpc... needs *runqueue() adjustments */
- xor r6, r6, r6 /* set r6 to 0 */
-1: bb1 0,  r7, 2f /* if rightmost bit set, done */
- extu r7, r7, 0<1> /* else, right shift whichqs, */
- br.n 1b /* increment r6, and repeat */
- addu r6, r6, 1
-2:
- or.u r7, r0, hi16(_C_LABEL(qs))
- or r7, r7, lo16(_C_LABEL(qs))
-
- /*
- * Need to make
- * p->p_forw->p_back = p->p_back and
- * p->p_back->p_forw = p->p_forw where
- * p is q->p_forw.
- * Remember that q->p_forw == p and p->p_back == q.
- */
-
- lda.d r8,  r7[r6] /* r8 = &qs[ff1(whichqs)] */
- ld r9,  r8, P_FORW /* r8 is q, r9 is p */
-
- ld r12, r9, P_FORW /* r12 = p->p_forw */
- st r8, r12, P_BACK /* p->p_forw->p_back = q (p->p_back) */
- st r12, r8, P_FORW /* q->p_forw = p->p_forw */
- lda.d r8,  r7[r6] /* reload r8 with qs[ff1(whichqs)] */
- ld r12, r8, P_FORW /* q->p_forw */
- cmp r12, r12, r8 /* q == q->p_forw; anyone left on queue? */
- bb1 ne,  r12, 3f /* yes, skip clearing bit in whichqs  */
-
- or r12, r0, 1
- mak r12, r12, r6
- or.u r7,  r0, hi16(_C_LABEL(whichqs))
- ld r8,  r7, lo16(_C_LABEL(whichqs))
- and.c r8,  r8, r12 /* whichqs &= ~the bit */
- st r8,  r7, lo16(_C_LABEL(whichqs))
-3:
-#ifdef DIAGNOSTIC
- ld r2, r9, P_WCHAN
- bcnd ne0, r2, _ASM_LABEL(Lswchanpanic)
- ld.b r2, r9, P_STAT
- cmp r2, r2, SRUN
- bb1 ne, r2, _ASM_LABEL(Lswsrunpanic)
-#endif
-
- ldcr r11, CPU
- st r0,  r11, CI_WANT_RESCHED /* clear want_resched */
-
- st r9,  r11, CI_CURPROC /* curproc = p */
  or r2,  r0,  SONPROC
- st.b r2,  r9,  P_STAT
+ st.b r2,  r3,  P_STAT
 #ifdef MULTIPROCESSOR
- st r11, r9,  P_CPU /* p->p_cpu = curcpu */
+ st r11, r3,  P_CPU /* p->p_cpu = curcpu */
 #endif
-
- ld r3,  r9,  P_ADDR
- st r0,  r9,  P_BACK /* p->p_back = 0 */
- st r3,  r11, CI_CURPCB /* curpcb = p->p_addr */
+ ld r2,  r3,  P_ADDR
+ st r2,  r11, CI_CURPCB /* curpcb = p->p_addr */
 
  /* pmap_activate() the process' pmap */
  bsr.n _C_LABEL(pmap_activate)
- or r2, r0, r9
+ or r2, r0, r3
 
  ldcr r10,  CPU
  ld r10,  r10, CI_CURPCB
@@ -297,25 +118,9 @@
  ld r29, r10, PCB_R29
  ld r30, r10, PCB_R30 /* restore frame pointer & stack */
  ld r31, r10, PCB_SP
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bsr.n _C_LABEL(sched_unlock_idle)
- or r14, r10, r0
- ld r1,  r14, PCB_PC
- ld r14, r14, PCB_R14
-#else
  ld r1,  r10, PCB_PC
- ld r14, r10, PCB_R14
-#endif
-
- /*
- * Enable interrupts again.
- */
- ldcr r2, PSR
- clr r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
- stcr r2, PSR
- FLUSH_PIPELINE
-
- jmp r1
+ jmp.n r1
+ ld r14, r10, PCB_R14
 
 /*
  * savectx(pcb)
Index: arch/m88k/m88k/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/m88k/m88k/vm_machdep.c,v
retrieving revision 1.15
diff -u -r1.15 vm_machdep.c
--- arch/m88k/m88k/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.15
+++ arch/m88k/m88k/vm_machdep.c 25 Sep 2007 09:53:47 -0000
@@ -136,20 +136,17 @@
 
 /*
  * cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * including the memory for the user structure and kernel stack.
- * Once finished, we call switch_exit, which switches to a temporary
- * pcb and stack and never returns.  We block memory allocation
- * until switch_exit has made things safe again.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
  */
 void
 cpu_exit(struct proc *p)
 {
- splhigh();
+ (void)splhigh();
 
  pmap_deactivate(p);
- switch_exit(p);
- /* NOTREACHED */
+ sched_exit(p);
 }
 
 /*
Index: arch/mac68k/mac68k/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/mac68k/mac68k/locore.s,v
retrieving revision 1.58
diff -u -r1.58 locore.s
--- arch/mac68k/mac68k/locore.s 15 May 2007 13:46:22 -0000 1.58
+++ arch/mac68k/mac68k/locore.s 25 Sep 2007 09:53:47 -0000
@@ -954,52 +954,18 @@
  */
 #include <m68k/m68k/support.s>
 
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
  .data
 GLOBAL(curpcb)
  .long 0
 
 ASBSS(nullpcb,SIZEOF_PCB)
 
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and select a new process to run.  The
- * old stack and u-area will be freed by the reaper.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- /* save state into garbage pcb */
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
- /* Schedule the vmspace and stack to be freed. */
- movl a0,sp@- | exit2(p)
- jbsr _C_LABEL(exit2)
- lea sp@(4),sp | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
  stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
 
 /*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  *
  * NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
  * entire ATC.  The effort involved in selective flushing may not be
@@ -1009,55 +975,15 @@
  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
  * bit).  For now, we just always flush the full ATC.
  */
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
 
  /*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
  * Save state of previous process in its pcb.
  */
  movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
  moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
  movl usp,a2 | grab USP (a2 has been saved)
  movl a2,a1@(PCB_USP) | and save it
@@ -1070,16 +996,12 @@
  jeq Lswnofpsave | yes, all done
  fmovem fp0-fp7,a2@(FPF_REGS) | save FP general registers
  fmovem fpcr/fpsr/fpi,a2@(FPF_FPCR) | save FP control registers
+
 Lswnofpsave:
+ movl sp@(8), a0 | newproc
 
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl a0, CURPROC
  movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
  movl a0@(P_ADDR),a1 | get p_addr
  movl a1,_C_LABEL(curpcb)
 
Index: arch/mac68k/mac68k/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/mac68k/mac68k/vm_machdep.c,v
retrieving revision 1.39
diff -u -r1.39 vm_machdep.c
--- arch/mac68k/mac68k/vm_machdep.c 27 May 2007 20:59:25 -0000 1.39
+++ arch/mac68k/mac68k/vm_machdep.c 25 Sep 2007 09:53:47 -0000
@@ -119,19 +119,18 @@
 
 /*
  * cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * block context switches and then call switch_exit() which will
- * free our stack and user area and switch to another process.
- * Thus, we never return.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
  */
 void
 cpu_exit(p)
  struct proc *p;
 {
-
  (void)splhigh();
- switch_exit(p);
- /* NOTREACHED */
+
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/macppc/macppc/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/cpu.c,v
retrieving revision 1.43
diff -u -r1.43 cpu.c
--- arch/macppc/macppc/cpu.c 23 May 2007 23:40:21 -0000 1.43
+++ arch/macppc/macppc/cpu.c 25 Sep 2007 09:53:48 -0000
@@ -676,7 +676,7 @@
 cpu_hatch(void)
 {
  volatile struct cpu_hatch_data *h = cpu_hatch_data;
- int scratch, i;
+ int scratch, i, s;
 
         /* Initialize timebase. */
         __asm ("mttbl %0; mttbu %0; mttbl %0" :: "r"(0));
@@ -759,5 +759,12 @@
 
  curcpu()->ci_ipending = 0;
  curcpu()->ci_cpl = 0;
+
+ s = splhigh();
+ microuptime(&curcpu()->ci_schedstate.spc_runtime);
+ splx(s);
+
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 #endif
Index: arch/macppc/macppc/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/genassym.cf,v
retrieving revision 1.14
diff -u -r1.14 genassym.cf
--- arch/macppc/macppc/genassym.cf 22 Mar 2007 19:26:28 -0000 1.14
+++ arch/macppc/macppc/genassym.cf 25 Sep 2007 09:53:48 -0000
@@ -61,7 +61,6 @@
 struct pcb
 member PCB_PMR pcb_pmreal
 member pcb_sp
-member pcb_spl
 member PCB_FAULT pcb_onfault
 
 struct pmap
@@ -70,8 +69,6 @@
 member PM_KERNELSR pm_sr[PPC_KERNEL_SR]
 
 struct proc
-member p_forw
-member p_back
 member p_addr
 member p_stat
 member p_cpu
Index: arch/macppc/macppc/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/locore.S,v
retrieving revision 1.32
diff -u -r1.32 locore.S
--- arch/macppc/macppc/locore.S 20 Mar 2007 20:59:54 -0000 1.32
+++ arch/macppc/macppc/locore.S 25 Sep 2007 09:53:48 -0000
@@ -133,150 +133,41 @@
  lis %r3,_C_LABEL(cpu_hatch_stack)@ha
  lwz %r1,_C_LABEL(cpu_hatch_stack)@l(%r3)
 
- bl _C_LABEL(cpu_hatch)
- bl _C_LABEL(sched_lock_idle)
- li %r30,0
- b _C_LABEL(idle)
-#endif
-/*
- * No processes are runnable, so loop waiting for one.
- * Separate label here for accounting purposes.
- */
- .globl _C_LABEL(idle)
- .type _C_LABEL(idle),@function
-_C_LABEL(idle):
- mfmsr %r3
- /* disable interrupts while manipulating runque */
- andi. %r3,%r3,~PSL_EE@l
- mtmsr %r3
-
- lis %r8,_C_LABEL(whichqs)@ha
- lwz %r9,_C_LABEL(whichqs)@l(%r8)
-
- or. %r9,%r9,%r9
- bne- _C_LABEL(sw1) /* at least one queue non-empty */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_unlock_idle)
+ b _C_LABEL(cpu_hatch)
+ /* NOTREACHED */
 #endif
 
- ori %r3,%r3,PSL_EE /* reenable ints again */
- mtmsr %r3
- isync
- sync
- /* low power mode */
- mfmsr %r3
- oris %r3, %r3, PSL_POW@h
- mtmsr %r3
- isync
-
-/* May do some power saving here? */
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- bl _C_LABEL(sched_lock_idle)
-#endif
- b _C_LABEL(idle)
-
-/*
- * switchexit gets called from cpu_exit to free the user structure
- * and kernel stack of the current process.
- */
-_ENTRY(_C_LABEL(switchexit))
-/* First switch to the idle pcb/kernel stack */
- GET_CPUINFO(%r7)
- lwz %r6,CI_IDLE_PCB(%r7)
- stw %r6,CI_CURPCB(%r7)
- addi %r1,%r6,USPACE-16 /* 16 bytes are reserved at stack top */
- /*
- * Schedule the vmspace and stack to be freed (the proc arg is
- * already in r3).
- */
- bl _C_LABEL(exit2)
-
- /* Fall through to cpu_switch to actually select another proc */
- li %r3,0 /* indicate exited process */
-
-/* Fall through to cpu_switch to actually select another proc */
-
 /*
- * void cpu_switch(struct proc *p)
- * Find a runnable process and switch to it.
+ * void cpu_switchto(struct proc *old, struct proc *new)
+ * Switch from "old" proc to "new".
  */
-_ENTRY(_C_LABEL(cpu_switch))
+_ENTRY(_C_LABEL(cpu_switchto))
  mflr %r0 /* save lr */
  stw %r0,4(%r1)
  stwu %r1,-16(%r1)
  stw %r31,12(%r1)
  stw %r30,8(%r1)
 
- mr %r30,%r3
- GET_CPUINFO(%r3)
+/*
+ * r3 - old proc
+ * r4 - new proc
+ * r5 - cpuinfo
+ */
+ GET_CPUINFO(%r5)
  li %r31,0
- /* Zero to not accumulate cpu time */
- stw %r31,CI_CURPROC(%r3)
- lwz %r31,CI_CURPCB(%r3)
-
- li %r3,0
- bl _C_LABEL(lcsplx)
- stw %r3,PCB_SPL(%r31) /* save spl */
-
-/* Find a new process */
- mfmsr %r3
- andi. %r3,%r3,~PSL_EE@l /* disable interrupts while
-   manipulating runque */
- mtmsr %r3
- isync
-
- lis %r8,_C_LABEL(whichqs)@ha
- lwz %r9,_C_LABEL(whichqs)@l(%r8)
-
- or. %r9,%r9,%r9
- beq- _C_LABEL(idle) /* all queues empty */
-_C_LABEL(sw1):
- cntlzw %r10,%r9
- lis %r4,_C_LABEL(qs)@ha
- addi %r4,%r4,_C_LABEL(qs)@l
- slwi %r3,%r10,3
- add %r3,%r3,%r4 /* select queue */
-
- lwz %r31,P_FORW(%r3) /* unlink first proc from queue */
- lwz %r4,P_FORW(%r31)
- stw %r4,P_FORW(%r3)
- stw %r3,P_BACK(%r4)
-
- cmpl 0,%r3,%r4 /* queue empty? */
- bne 1f
-
- lis %r3,0x80000000@ha
- srw %r3,%r3,%r10
- andc %r9,%r9,%r3
- stw %r9,_C_LABEL(whichqs)@l(%r8) /* mark it empty */
-
-1:
  /* just did this resched thing, clear resched */
- li %r3,0
- GET_CPUINFO(%r4)
- stw %r3,CI_WANT_RESCHED(%r4)
-
- stw %r3,P_BACK(%r31) /* probably superfluous */
+ stw %r31,CI_WANT_RESCHED(%r5)
 
 #ifdef MULTIPROCESSOR
- stw %r4,P_CPU(%r31)
+ stw %r5,P_CPU(%r4)
 #endif
 
- stw %r31,CI_CURPROC(%r4) /* record new process */
-
- li %r3,SONPROC
- stb %r3,P_STAT(%r31)
+ stw %r4,CI_CURPROC(%r5) /* record new process */
 
- mfmsr %r3
- ori %r3,%r3,PSL_EE /* Now we can interrupt again */
- mtmsr %r3
+ li %r31,SONPROC
+ stb %r31,P_STAT(%r4)
 
- cmpl 0,%r31,%r30 /* is it the same process? */
- beq switch_return
-
- or. %r30,%r30,%r30 /* old process was exiting? */
+ or. %r3,%r3,%r3 /* old process was exiting? */
  beq switch_exited
 
  mfsr %r10,PPC_USER_SR /* save PPC_USER_SR for copyin/copyout*/
@@ -284,33 +175,31 @@
  mr %r12,%r2 /* save r2 */
  stwu %r1,-SFRAMELEN(%r1) /* still running on old stack */
  stmw %r10,8(%r1)
- lwz %r3,P_ADDR(%r30)
- stw %r1,PCB_SP(%r3) /* save SP */
+ lwz %r31,P_ADDR(%r3)
+ stw %r1,PCB_SP(%r31) /* save SP */
 
 switch_exited:
  /* disable interrupts while actually switching */
- mfmsr %r3
- andi. %r3,%r3,~PSL_EE@l
- mtmsr %r3
+ mfmsr %r30
+ andi. %r30,%r30,~PSL_EE@l
+ mtmsr %r30
 
- lwz %r4,P_ADDR(%r31)
- GET_CPUINFO(%r5)
- stw %r4,CI_CURPCB(%r5) /* indicate new pcb */
+ lwz %r31,P_ADDR(%r4)
+ stw %r31,CI_CURPCB(%r5) /* indicate new pcb */
 
- lwz %r5,PCB_PMR(%r4)
+ lwz %r6,PCB_PMR(%r31)
 
  /* save real pmap pointer for spill fill */
- GET_CPUINFO(%r6)
- stwu %r5,CI_CURPM(%r6)
- stwcx. %r5,%r0,%r6 /* clear possible reservation */
+ stwu %r6,CI_CURPM(%r5)
+ stwcx. %r6,%r0,%r5 /* clear possible reservation */
 
- addic. %r5,%r5,64
- li %r6,0
+ addic. %r6,%r6,64
+ li %r5,0
 
- lwz %r1,PCB_SP(%r4) /* get new procs SP */
+ lwz %r1,PCB_SP(%r31) /* get new procs SP */
 
- ori %r3,%r3,PSL_EE /* interrupts are okay again */
- mtmsr %r3
+ ori %r30,%r30,PSL_EE /* interrupts are okay again */
+ mtmsr %r30
 
  lmw %r10,8(%r1) /* get other regs */
  lwz %r1,0(%r1) /* get saved SP */
@@ -320,17 +209,6 @@
  mtsr PPC_USER_SR,%r10 /* get saved PPC_USER_SR */
  isync
 
-switch_return:
- mr %r30,%r7 /* save proc pointer */
- lwz %r3,PCB_SPL(%r4)
- bl _C_LABEL(lcsplx)
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
-        bl      _C_LABEL(sched_unlock_idle)
-#endif
-
- mr %r3,%r30 /* curproc for special fork returns */
-
  lwz %r31,12(%r1)
  lwz %r30,8(%r1)
  addi %r1,%r1,16
@@ -338,6 +216,19 @@
  mtlr %r0
  blr
 
+_ENTRY(_C_LABEL(cpu_idle_enter))
+ blr
+
+_ENTRY(_C_LABEL(cpu_idle_cycle))
+ /* low power mode */
+ mfmsr %r3
+ oris %r3, %r3, PSL_POW@h
+ mtmsr %r3
+ isync
+ blr
+
+_ENTRY(_C_LABEL(cpu_idle_leave))
+ blr
 
 /*
  * Data used during primary/secondary traps/interrupts
Index: arch/mips64/mips64/context.S
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/context.S,v
retrieving revision 1.13
diff -u -r1.13 context.S
--- arch/mips64/mips64/context.S 16 Jul 2007 20:22:18 -0000 1.13
+++ arch/mips64/mips64/context.S 25 Sep 2007 09:53:49 -0000
@@ -69,92 +69,11 @@
  move v0, zero
 END(savectx)
 
-/*
- * The following primitives manipulate the run queues.  _whichqs tells which
- * of the 32 queues _qs have processes in them.  Setrunqueue puts processes
- * into queues, Remrq removes them from queues.  The running process is on
- * no queue, other processes are on a queue related to p->p_priority, divided
- * by 4 actually to shrink the 0-127 range of priorities into the 32 available
- * queues.
- */
-/*
- * setrunqueue(p)
- * proc *p;
- *
- * Call should be made at splclock(), and p->p_stat should be SRUN.
- */
-NON_LEAF(setrunqueue, FRAMESZ(CF_SZ), ra)
- .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
- PTR_L t0, P_BACK(a0) ## firewall: p->p_back must be 0
- bne t0, zero, 1f ##
- lbu t0, P_PRIORITY(a0) # put on p->p_priority / 4 queue
- li t1, 1 # compute corresponding bit
- srl t0, t0, 2 # compute index into 'whichqs'
- sll t1, t1, t0
- lw t2, whichqs # set corresponding bit
- sll t0, t0, LOGREGSZ+1 # compute index into 'qs'
- or t2, t2, t1
- sw t2, whichqs
- LA t1, qs
- PTR_ADDU t0, t0, t1 # t0 = qp = &qs[pri >> 2]
- PTR_L t1, P_BACK(t0) # t1 = qp->ph_rlink
- PTR_S t0, P_FORW(a0) # p->p_forw = qp
- PTR_S t1, P_BACK(a0) # p->p_back = qp->ph_rlink
- PTR_S a0, P_FORW(t1) # p->p_back->p_forw = p;
- j ra
- PTR_S a0, P_BACK(t0) # qp->ph_rlink = p
-
-1:
+NON_LEAF(cpu_idle_enter, FRAMESZ(CF_SZ), ra)
  PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
  PTR_S ra, CF_RA_OFFS(sp)
- PANIC("setrunqueue")
- jr ra
- nop
-END(setrunqueue)
-
-/*
- * Remrq(p)
- *
- * Call should be made at splclock().
- */
-NON_LEAF(remrunqueue, FRAMESZ(CF_SZ), ra)
  .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
- lbu t0, P_PRIORITY(a0) # get from p->p_priority / 4 queue
- li t1, 1 # compute corresponding bit
- srl t0, t0, 2 # compute index into 'whichqs'
- lw t2, whichqs # check corresponding bit
- sll t1, t1, t0
- and v0, t2, t1
- beqz v0, 2f # oops! queue is empty!
- PTR_L v0, P_BACK(a0) # v0 = p->p_back
-
- PTR_L v1, P_FORW(a0) # v1 = p->p_forw
- PTR_SLL t0, t0, LOGREGSZ+1 # compute index into 'qs'
- PTR_S v1, P_FORW(v0) # p->p_back->p_forw = p->p_forw;
- PTR_S v0, P_BACK(v1) # p->p_forw->p_back = p->r_rlink
- LA v0, qs
- PTR_ADDU t0, t0, v0 # t0 = qp = &qs[pri >> 2]
- PTR_L v0, P_FORW(t0) # check if queue empty
- bne v0, t0, 1f # No. qp->ph_link != qp
- xor t2, t2, t1 # clear corresponding bit in 'whichqs'
- sw t2, whichqs
-1:
- j ra
- PTR_S zero, P_BACK(a0) # for firewall checking
-
-2:
- PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
- PTR_S ra, CF_RA_OFFS(sp)
- PANIC("remrunqueue empty")
- jr ra
- nop
-END(remrunqueue)
 
-/*
- *   Idle, this is where we spend time when nothing to do.
- */
-LEAF(idle, 0)
-_idle:
  sw zero, cpl # lower to spl0
  lw t0, ipending
  beqz t0, 1f
@@ -175,63 +94,57 @@
  jal updateimask # Make sure SR imask is updated
  xor a0, a0
 
- li t1,1
 #if defined(TGT_CP7000) || defined(TGT_CP7000G)
  PTR_L t2, misc_h # if non zero, do Ocelot LEDs.
  beqz t2, 1f
  li t0, 0x40
  sb t0, 0x0d(t2)
-#endif
 1:
- lw t0, whichqs # look for non-empty queue
- beq t0, zero, 1b
- nop
+#endif
+
+ PTR_L ra, CF_RA_OFFS(sp)
+ j ra
+ PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
+END(cpu_idle_enter)
+
+LEAF(cpu_idle_leave, 0)
 #if defined(TGT_CP7000) || defined(TGT_CP7000G)
- beqz t2, sw1
+ PTR_L t2, misc_h # if non zero, do Ocelot LEDs.
+ beqz t2, 1f
  li t0, 0x40
  sb t0, 0x0c(t2)
+1:
 #endif
- b sw1 # Hey, time to do some work!
- nop
- jr ra # DDB trace
- nop
- .globl e_idle
-e_idle:
-END(idle)
 
-/*
- * switch_exit(p)
- *
- * At exit of a process, do a cpu_switch for the last time.
- * All interrupts should be blocked at this point.
- */
-LEAF(switch_exit, 0)
- mfc0 v0, COP_0_STATUS_REG
- li v1, ~SR_INT_ENAB
- and v0, v0, v1
- mtc0 v0, COP_0_STATUS_REG
+ mfc0 a0, COP_0_STATUS_REG # disable interrupts
+ li a1, ~SR_INT_ENAB
+ and a0, a0, a1
+ mtc0 a0, COP_0_STATUS_REG
  ITLBNOPFIX
- LA sp, idle_stack - FRAMESZ(CF_SZ)
- jal exit2
- nop
 
- PTR_S zero, curproc
- b sw0
+ j ra
  nop
- jr ra # DDB trace
+END(cpu_idle_leave)
+
+LEAF(cpu_idle_cycle, 0)
+ j ra
  nop
-END(switch_exit)
+END(cpu_idle_cycle)
 
 /*
- * cpu_switch()
- * Find the highest priority process and resume it.
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  */
-NON_LEAF(cpu_switch, FRAMESZ(CF_SZ), ra)
+NON_LEAF(cpu_switchto, FRAMESZ(CF_SZ), ra)
  PTR_L t3, curprocpaddr
  REG_S sp, PCB_CONTEXT+8*REGSZ(t3) # save old sp
+
  PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
  REG_S ra, CF_RA_OFFS(sp)
  .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
+
+ beqz a0, 1f
+ nop
+
  lw t0, cpl
  REG_S t0, PCB_CONTEXT+13*REGSZ(t3)
  REG_S s0, PCB_CONTEXT+0*REGSZ(t3) # do a 'savectx()'
@@ -249,59 +162,23 @@
  REG_S t0, PCB_CONTEXT+11*REGSZ(t3)
  REG_S t1, PCB_CONTEXT+12*REGSZ(t3)
 
-sw0:
-# lw t2, cnt+V_SWTCH # for statistics
- lw t1, whichqs # look for non-empty queue
-# addu t2, t2, 1
-# sw t2, cnt+V_SWTCH
- beq t1, zero, _idle # if none, idle
- nop
-sw1:
- mfc0 v0, COP_0_STATUS_REG
+1:
+ /*
+ * Disable interrupts
+ */
+ mfc0 v0, COP_0_STATUS_REG # disable interrupts
  li v1, ~SR_INT_ENAB
  and v0, v0, v1
  mtc0 v0, COP_0_STATUS_REG
  ITLBNOPFIX
- lw t0, whichqs # look for non-empty queue
- li t2, -1 # t2 = lowest bit set
- beq t0, zero, _idle # if none, idle
- move t3, t0 # t3 = saved whichqs
-1:
- addu t2, t2, 1
- and t1, t0, 1 # bit set?
- beq t1, zero, 1b
- srl t0, t0, 1 # try next bit
-/*
- * Remove process from queue.
- */
- PTR_SLL t0, t2, LOGREGSZ+1
- LA t1, qs
- PTR_ADDU t0, t0, t1 # t0 = qp = &qs[highbit]
- PTR_L a0, P_FORW(t0) # a0 = p = highest pri process
- PTR_L v0, P_FORW(a0) # v0 = p->p_forw
- beq t0, a0, 4f # make sure something in queue
- PTR_S v0, P_FORW(t0) # qp->ph_link = p->p_forw;
- PTR_S t0, P_BACK(v0) # p->p_forw->p_back = qp
- bne v0, t0, 2f # queue still not empty
- PTR_S zero, P_BACK(a0) ## for firewall checking
- li v1, 1 # compute bit in 'whichqs'
- sll v1, v1, t2
- xor t3, t3, v1 # clear bit in 'whichqs'
- sw t3, whichqs
-2:
-/*
- * Switch to new context.
- */
- sw zero, want_resched
- jal pmap_activate # v0 = TLB PID
- move s0, a0 # BDSLOT: save p
 
-/*
- * We need to wire the process kernel stack mapping so there
- * will be no tlb misses in exception handlers. This is done
- * by invalidating any tlb entries mapping the U-area and
- * put valid mappings in tlb entries 0 and 1.
- */
+ /*
+ * Switch to new context
+ */
+ move s0, a1 # save p
+ sw zero, want_resched
+ jal pmap_activate
+ move a0, s0
 
  PTR_L t3, P_ADDR(s0) # get uarea pointer.
  PTR_S s0, curproc # set curproc
@@ -310,6 +187,13 @@
  li t1, SONPROC
  sb t1, P_STAT(s0) # set to onproc.
 
+ /*
+ * We need to wire the process kernel stack mapping so there
+ * will be no tlb misses in exception handlers. This is done
+ * by invalidating any tlb entries mapping the U-area and
+ * put valid mappings in tlb entries 0 and 1.
+ */
+
  or v0, t3
  dmtc0 v0, COP_0_TLB_HI # init high entry (tlbid)
  LA t1, (VM_MIN_KERNEL_ADDRESS)
@@ -399,9 +283,10 @@
 
 ctx3:
 
-/*
- * Restore registers and return.
- */
+ /*
+ * Restore registers and return.
+ */
+
  REG_L a0, PCB_CONTEXT+13*REGSZ(t3)
  REG_L s0, PCB_CONTEXT+0*REGSZ(t3)
  REG_L s1, PCB_CONTEXT+1*REGSZ(t3)
@@ -428,6 +313,4 @@
  ITLBNOPFIX
  j ra
  nop
-4:
- PANIC("cpu_switch") # nothing in queue
-END(cpu_switch)
+END(cpu_switchto)
Index: arch/mips64/mips64/db_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/db_machdep.c,v
retrieving revision 1.12
diff -u -r1.12 db_machdep.c
--- arch/mips64/mips64/db_machdep.c 3 Sep 2007 01:15:50 -0000 1.12
+++ arch/mips64/mips64/db_machdep.c 25 Sep 2007 09:53:49 -0000
@@ -221,7 +221,6 @@
  extern char edata[];
  extern char k_intr[];
  extern char k_general[];
- extern char idle[];
  struct trap_frame *regs = &ddb_regs;
 
  /* get initial values from the exception frame */
@@ -396,14 +395,10 @@
  }
 
 done:
- if (symname == NULL) {
- if (subr == (long)idle)
- (*pr)("idle ");
- else
- (*pr)("%p ", subr);
- } else {
+ if (symname == NULL)
+ (*pr)("%p ", subr);
+ else
  (*pr)("%s+%p ", symname, diff);
- }
  (*pr)("(%llx,%llx,%llx,%llx) sp %llx ra %llx, sz %d\n", a0, a1, a2, a3, sp, ra, stksize);
 
  if (subr == (long)k_intr || subr == (long)k_general) {
Index: arch/mips64/mips64/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/vm_machdep.c,v
retrieving revision 1.15
diff -u -r1.15 vm_machdep.c
--- arch/mips64/mips64/vm_machdep.c 3 Sep 2007 17:35:51 -0000 1.15
+++ arch/mips64/mips64/vm_machdep.c 25 Sep 2007 09:53:49 -0000
@@ -134,9 +134,9 @@
  if (machFPCurProcPtr == p)
  machFPCurProcPtr = (struct proc *)0;
 
- (void) splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ (void)splhigh();
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/mvme68k/mvme68k/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/mvme68k/mvme68k/locore.s,v
retrieving revision 1.54
diff -u -r1.54 locore.s
--- arch/mvme68k/mvme68k/locore.s 15 May 2007 13:46:22 -0000 1.54
+++ arch/mvme68k/mvme68k/locore.s 25 Sep 2007 09:53:50 -0000
@@ -1165,51 +1165,18 @@
  */
 #include <m68k/m68k/support.s>
 
-/*
- * Use common m68k process manipulation routines.
- */
-#include <m68k/m68k/proc_subr.s>
-
  .data
 GLOBAL(curpcb)
  .long 0
 
 ASBSS(nullpcb,SIZEOF_PCB)
 
-/*
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and deallocate the process's resources.
- */
-ENTRY(switch_exit)
- movl sp@(4),a0
- | save state into garbage pcb
- movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
- lea _ASM_LABEL(tmpstk),sp | goto a tmp stack
-
-        /* Schedule the vmspace and stack to be freed. */
- movl    a0,sp@-                 | exit2(p)
- jbsr    _C_LABEL(exit2)
- lea     sp@(4),sp               | pop args
-
- jra _C_LABEL(cpu_switch)
-
-/*
- * When no processes are on the runq, Swtch branches to Idle
- * to wait for something to come ready.
- */
-ASENTRY_NOPROFILE(Idle)
+ENTRY_NOPROFILE(cpu_idle_cycle)
  stop #PSL_LOWIPL
- movw #PSL_HIGHIPL,sr
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
- jra Lsw1
-
-Lbadsw:
- PANIC("switch")
- /*NOTREACHED*/
+ rts
 
 /*
- * cpu_switch()
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  *
  * NOTE: On the mc68851 we attempt to avoid flushing the
  * entire ATC.  The effort involved in selective flushing may not be
@@ -1219,55 +1186,15 @@
  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
  * bit).  For now, we just always flush the full ATC.
  */
-ENTRY(cpu_switch)
- movl _C_LABEL(curpcb),a0 | current pcb
- movw sr,a0@(PCB_PS) | save sr before changing ipl
-#ifdef notyet
- movl CURPROC,sp@- | remember last proc running
-#endif
- clrl CURPROC
+ENTRY(cpu_switchto)
+ movl sp@(4), d0 | oldproc
+ beq Lswnofpsave | is NULL, don't save anything
 
  /*
- * Find the highest-priority queue that isn't empty,
- * then take the first proc from that queue.
- */
- movw #PSL_HIGHIPL,sr | lock out interrupts
- movl _C_LABEL(whichqs),d0
- jeq _ASM_LABEL(Idle)
-Lsw1:
- movl d0,d1
- negl d0
- andl d1,d0
- bfffo d0{#0:#32},d1
- eorib #31,d1
-
- movl d1,d0
- lslb #3,d1 | convert queue number to index
- addl #_C_LABEL(qs),d1 | locate queue (q)
- movl d1,a1
- movl a1@(P_FORW),a0 | p = q->p_forw
- cmpal d1,a0 | anyone on queue?
- jeq Lbadsw | no, panic
- movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
- movl a0@(P_FORW),a1 | n = p->p_forw
- movl d1,a1@(P_BACK) | n->p_back = q
- cmpal d1,a1 | anyone left on queue?
- jne Lsw2 | yes, skip
- movl _C_LABEL(whichqs),d1
- bclr d0,d1 | no, clear bit
- movl d1,_C_LABEL(whichqs)
-Lsw2:
- movl a0,CURPROC
- clrl _C_LABEL(want_resched)
-#ifdef notyet
- movl sp@+,a1
- cmpl a0,a1 | switching to same proc?
- jeq Lswdone | yes, skip save and restore
-#endif
- /*
  * Save state of previous process in its pcb.
  */
         movl _C_LABEL(curpcb),a1
+ movw sr, a1@(PCB_PS) | save sr before switching context
  moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
  movl usp,a2 | grab USP (a2 has been saved)
  movl a2,a1@(PCB_USP) | and save it
@@ -1295,15 +1222,12 @@
  fmovem fpsr,a2@(FPF_FPSR)
  fmovem fpi,a2@(FPF_FPI)
 #endif /* M68060 */
+
 Lswnofpsave:
-#ifdef DIAGNOSTIC
- tstl a0@(P_WCHAN)
- jne Lbadsw
- cmpb #SRUN,a0@(P_STAT)
- jne Lbadsw
-#endif
+ movl sp@(8), a0 | newproc
+
+ movl a0, CURPROC
  movb #SONPROC,a0@(P_STAT)
- clrl a0@(P_BACK) | clear back link
  movl a0@(P_ADDR),a1 | get p_addr
  movl a1,_C_LABEL(curpcb)
 
Index: arch/mvme68k/mvme68k/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/mvme68k/mvme68k/vm_machdep.c,v
retrieving revision 1.45
diff -u -r1.45 vm_machdep.c
--- arch/mvme68k/mvme68k/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.45
+++ arch/mvme68k/mvme68k/vm_machdep.c 25 Sep 2007 09:53:50 -0000
@@ -117,20 +117,18 @@
 
 /*
  * cpu_exit is called as the last action during exit.
- * We release the address space and machine-dependent resources,
- * including the memory for the user structure and kernel stack.
- * Once finished, we call switch_exit, which switches to a temporary
- * pcb and stack and never returns.  We block memory allocation
- * until switch_exit has made things safe again.
+ *
+ * Block context switches and then call switch_exit() which will
+ * switch to another process thus we never return.
  */
 void
 cpu_exit(p)
  struct proc *p;
 {
+ (void)splhigh();
 
- splhigh();
- switch_exit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/mvme88k/mvme88k/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/mvme88k/mvme88k/locore.S,v
retrieving revision 1.49
diff -u -r1.49 locore.S
--- arch/mvme88k/mvme88k/locore.S 8 May 2006 14:03:35 -0000 1.49
+++ arch/mvme88k/mvme88k/locore.S 25 Sep 2007 09:53:50 -0000
@@ -346,14 +346,6 @@
  bsr.n _C_LABEL(secondary_main)
  addu r31, r3, USIZE /* switch to idle stack */
 
- /*
- * At this point, the CPU has been correctly initialized and has
- * identified itself on the console.
- * All it needs now is to jump to the idle loop and wait for work to
- * be offered.
- */
- br _ASM_LABEL(cpu_switch_idle)
-
 #endif /* MULTIPROCESSOR */
 
 /*
Index: arch/mvme88k/mvme88k/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/mvme88k/mvme88k/machdep.c,v
retrieving revision 1.192
diff -u -r1.192 machdep.c
--- arch/mvme88k/mvme88k/machdep.c 6 Jun 2007 17:15:12 -0000 1.192
+++ arch/mvme88k/mvme88k/machdep.c 25 Sep 2007 09:53:51 -0000
@@ -719,19 +719,18 @@
 secondary_main()
 {
  struct cpu_info *ci = curcpu();
+ int s;
 
  cpu_configuration_print(0);
+ sched_init_cpu(ci);
  ncpus++;
  __cpu_simple_unlock(&cpu_mutex);
 
  microuptime(&ci->ci_schedstate.spc_runtime);
  ci->ci_curproc = NULL;
 
- /*
- * Upon return, the secondary cpu bootstrap code in locore will
- * enter the idle loop, waiting for some food to process on this
- * processor.
- */
+ SCHED_LOCK(s);
+ cpu_switchto(NULL, sched_chooseproc());
 }
 
 #endif /* MULTIPROCESSOR */
Index: arch/powerpc/conf/files.powerpc
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/conf/files.powerpc,v
retrieving revision 1.42
diff -u -r1.42 files.powerpc
--- arch/powerpc/conf/files.powerpc 22 Mar 2007 19:26:27 -0000 1.42
+++ arch/powerpc/conf/files.powerpc 25 Sep 2007 09:53:51 -0000
@@ -2,7 +2,6 @@
 #
 
 file arch/powerpc/powerpc/setjmp.S ddb
-file arch/powerpc/powerpc/Locore.c
 file arch/powerpc/powerpc/bcopy.c
 file arch/powerpc/powerpc/copystr.c
 file arch/powerpc/powerpc/cpu_subr.c
Index: arch/powerpc/include/pcb.h
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/include/pcb.h,v
retrieving revision 1.10
diff -u -r1.10 pcb.h
--- arch/powerpc/include/pcb.h 20 Mar 2007 20:59:53 -0000 1.10
+++ arch/powerpc/include/pcb.h 25 Sep 2007 09:53:51 -0000
@@ -49,7 +49,6 @@
  struct pmap *pcb_pm; /* pmap of our vmspace */
  struct pmap *pcb_pmreal; /* real address of above */
  register_t pcb_sp; /* saved SP */
- int pcb_spl; /* saved SPL */
  faultbuf *pcb_onfault; /* For use during copyin/copyout */
  int pcb_flags;
 #define PCB_FPU 1 /* Process had FPU initialized */
Index: arch/powerpc/powerpc/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/powerpc/vm_machdep.c,v
retrieving revision 1.44
diff -u -r1.44 vm_machdep.c
--- arch/powerpc/powerpc/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.44
+++ arch/powerpc/powerpc/vm_machdep.c 25 Sep 2007 09:53:51 -0000
@@ -123,7 +123,6 @@
  sf->sp = (int)cf;
  sf->user_sr = pmap_kernel()->pm_sr[PPC_USER_SR]; /* just in case */
  pcb->pcb_sp = (int)stktop2;
- pcb->pcb_spl = 0;
 }
 
 /*
@@ -155,8 +154,8 @@
  pool_put(&ppc_vecpl, pcb->pcb_vr);
 #endif /* ALTIVEC */
 
- (void)splsched();
- switchexit(p);
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/sgi/localbus/macebus.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/localbus/macebus.c,v
retrieving revision 1.26
diff -u -r1.26 macebus.c
--- arch/sgi/localbus/macebus.c 9 Jul 2007 21:40:24 -0000 1.26
+++ arch/sgi/localbus/macebus.c 25 Sep 2007 09:53:52 -0000
@@ -780,7 +780,6 @@
 intrmask_t
 macebus_aux(intrmask_t hwpend, struct trap_frame *cf)
 {
- extern char idle[], e_idle[];
  u_int64_t mask;
 
  mask = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG);
@@ -791,7 +790,8 @@
  /* RED   - User Mode */
  if (cf->sr & SR_KSU_USER) {
  mask &= ~MACE_ISA_MISC_RLED_OFF;
- } else if (cf->pc >= (long)idle && cf->pc < (long)e_idle) {
+ } else if (curproc == NULL ||
+    curproc == curcpu()->ci_schedstate.spc_idleproc) {
  mask &= ~MACE_ISA_MISC_GLED_OFF;
  } else {
  mask &= ~(MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF);
Index: arch/sgi/sgi/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/genassym.cf,v
retrieving revision 1.9
diff -u -r1.9 genassym.cf
--- arch/sgi/sgi/genassym.cf 18 Jun 2007 20:25:55 -0000 1.9
+++ arch/sgi/sgi/genassym.cf 25 Sep 2007 09:53:52 -0000
@@ -38,9 +38,7 @@
 export SONPROC
 
 struct proc
-member p_forw
-member p_back
-member p_priority
+#member p_priority
 member p_stat
 member p_addr
 #member P_UPTE p_md.md_upte
Index: arch/sh/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sh/include/cpu.h,v
retrieving revision 1.10
diff -u -r1.10 cpu.h
--- arch/sh/include/cpu.h 6 Jun 2007 17:15:12 -0000 1.10
+++ arch/sh/include/cpu.h 25 Sep 2007 09:53:52 -0000
@@ -125,6 +125,11 @@
  * We need a machine-independent name for this.
  */
 #define DELAY(x) delay(x)
+
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_cycle() __asm volatile("sleep")
+#define cpu_idle_leave() do { /* nothing */ } while (0)
+
 #endif /* _KERNEL */
 
 /*
Index: arch/sh/sh/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/genassym.cf,v
retrieving revision 1.3
diff -u -r1.3 genassym.cf
--- arch/sh/sh/genassym.cf 14 May 2007 07:05:49 -0000 1.3
+++ arch/sh/sh/genassym.cf 25 Sep 2007 09:53:52 -0000
@@ -54,8 +54,6 @@
 
 struct proc
 member p_addr
-member p_back
-member p_forw
 member p_stat
 member p_wchan
 member P_MD_UPTE p_md.md_upte
Index: arch/sh/sh/locore_c.c
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/locore_c.c,v
retrieving revision 1.5
diff -u -r1.5 locore_c.c
--- arch/sh/sh/locore_c.c 9 Sep 2007 11:57:55 -0000 1.5
+++ arch/sh/sh/locore_c.c 25 Sep 2007 09:53:52 -0000
@@ -127,26 +127,14 @@
 #include <sh/ubcreg.h>
 
 void (*__sh_switch_resume)(struct proc *);
-struct proc *cpu_switch_search(struct proc *);
-struct proc *cpu_switch_prepare(struct proc *, struct proc *);
-void switch_exit(struct proc *, void (*)(struct proc *));
-void idle(void);
+void cpu_switch_prepare(struct proc *, struct proc *);
 int want_resched;
 
-#ifdef LOCKDEBUG
-#define SCHED_LOCK_IDLE() sched_lock_idle()
-#define SCHED_UNLOCK_IDLE() sched_unlock_idle()
-#else
-#define SCHED_LOCK_IDLE() do {} while (/* CONSTCOND */ 0)
-#define SCHED_UNLOCK_IDLE() do {} while (/* CONSTCOND */ 0)
-#endif
-
-
 /*
  * Prepare context switch from oproc to nproc.
- * This code is shared by cpu_switch and cpu_switchto.
+ * This code is used by cpu_switchto.
  */
-struct proc *
+void
 cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
 {
  nproc->p_stat = SONPROC;
@@ -154,10 +142,8 @@
  if (oproc && (oproc->p_md.md_flags & MDP_STEP))
  _reg_write_2(SH_(BBRB), 0);
 
- if (nproc != oproc) {
- curpcb = nproc->p_md.md_pcb;
- pmap_activate(nproc);
- }
+ curpcb = nproc->p_md.md_pcb;
+ pmap_activate(nproc);
 
  if (nproc->p_md.md_flags & MDP_STEP) {
  int pm_asid = nproc->p_vmspace->vm_map.pmap->pm_asid;
@@ -171,34 +157,6 @@
  }
 
  curproc = nproc;
- return (nproc);
-}
-
-/*
- * Find the highest priority proc and prepare to switching to it.
- */
-struct proc *
-cpu_switch_search(struct proc *oproc)
-{
- struct prochd *q;
- struct proc *p;
-
- curproc = NULL;
-
- SCHED_LOCK_IDLE();
- while (sched_is_idle()) {
- SCHED_UNLOCK_IDLE();
- idle();
- SCHED_LOCK_IDLE();
- }
-
- q = &qs[ffs(whichqs) - 1];
- p = q->ph_link;
- remrunqueue(p);
- want_resched = 0;
- SCHED_UNLOCK_IDLE();
-
- return (cpu_switch_prepare(oproc, p));
 }
 
 void
@@ -207,24 +165,8 @@
  if (p->p_md.md_flags & MDP_STEP)
  _reg_write_2(SH_(BBRB), 0);
 
- switch_exit(p, exit2);
-}
-
-/*
- * void idle(void):
- * When no processes are on the run queue, wait for something to come
- * ready. Separated function for profiling.
- */
-void
-idle()
-{
- spl0();
-#if 0
- if (uvm.page_idle_zero)
- uvm_pageidlezero();
-#endif
- __asm volatile("sleep");
- splsched();
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 #ifndef P1_STACK
Index: arch/sh/sh/locore_subr.S
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/locore_subr.S,v
retrieving revision 1.6
diff -u -r1.6 locore_subr.S
--- arch/sh/sh/locore_subr.S 2 Mar 2007 06:11:54 -0000 1.6
+++ arch/sh/sh/locore_subr.S 25 Sep 2007 09:53:53 -0000
@@ -180,27 +180,26 @@
  .text
  .align 5 /* align cache line size (32B) */
 /*
- * LINTSTUB: Func: void cpu_switch(struct proc *p, struct proc *XXX_IGNORED)
- * Find a runnable proc and switch to it.  Wait if necessary.
+ * LINTSTUB: Func: void cpu_switchto(struct proc *old, struct proc *new)
+ * Switch proc contexts.
  */
-ENTRY(cpu_switch)
- /* Save current proc's context to switchframe */
+ENTRY(cpu_switchto)
+ mov r4, r0
+ cmp/eq #0, r0
+ bt 1f
+
+ /* Save old proc's context to switchframe */
  mov.l .L_SF, r0
  mov.l @(r0, r4), r1
  SAVEPCB(r1)
  add #PCB_FP, r1
  SAVEFP(r1, r8, r9)
 
-.L_find_and_switch:
- /* Search next proc. cpu_switch_search may or may not sleep. */
- mov.l .L_cpu_switch_search, r0
+1:
+ mov.l .L_cpu_switch_prepare, r0
  jsr @r0
- mov r4, r8 /* save old proc */
-
- /* Skip context switch if same proc. */
- cmp/eq r8, r0
- bt/s 1f
- mov r0, r4 /* new proc */
+ mov r5, r8 /* save new proc */
+ mov r8, r4
 
  /* Setup kernel stack */
  mov.l .L_SF, r0
@@ -224,7 +223,7 @@
  /* Now OK to use kernel stack. */
 
  /* Restore new proc's context from switchframe */
-1: mov.l .L_SF, r0
+ mov.l .L_SF, r0
  mov.l @(r0, r4), r1
  add #4, r1 /* r15 already restored */
  mov.l @r1+, r14
@@ -248,48 +247,8 @@
  nop
  .align 2
 .L_SF: .long (P_MD_PCB)
-.L_cpu_switch_search: .long _C_LABEL(cpu_switch_search)
+.L_cpu_switch_prepare: .long _C_LABEL(cpu_switch_prepare)
 FUNC_SYMBOL(switch_resume)
-
-
-/*
- * LINTSTUB: Func: void switch_exit(struct proc *p, void (*exit_func)(struct proc *))
- * Called only from cpu_exit(p).  Before we call exit_func to
- * free proc's resources (including kernel stack) we need to
- * switch to the proc0's kernel stack.  Then we jump into the
- * middle of cpu_switch to find and switch to a new proc.
- */
-ALTENTRY(switch_exit)
- mov.l .L_switch_exit_proc0_pcb, r1
- mov.l .L_switch_exit_curpcb, r0
- mov.l @r1, r1
- mov.l r1, @r0 /* curpcb = proc0.p_md.md_pcb */
-
- mov.l @(SF_R7_BANK, r1), r0 /* stack top */
- mov.l @(SF_R6_BANK, r1), r2 /* current frame */
- mov.l @(SF_R15, r1), r3 /* current stack */
-
- /* switch to proc0's kernel stack */
- __EXCEPTION_BLOCK(r1, r6)
- ldc r0, r7_bank
- ldc r2, r6_bank
- mov r3, r15
- __EXCEPTION_UNBLOCK(r0, r1)
-
- /* safe to call (*exit_func)(p); now */
- jsr @r5
- nop /* proc is already in r4 */
-
- /* proceed to cpu_switch */
- bra .L_find_and_switch
- mov #0, r4 /* no "previous" proc */
-
- .align 2
-.L_switch_exit_proc0_pcb:
- .long _C_LABEL(proc0) + P_MD_PCB
-.L_switch_exit_curpcb:
- .long _C_LABEL(curpcb)
-
 
 #ifdef SH3
 /*
Index: arch/sh/sh/sh_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/sh_machdep.c,v
retrieving revision 1.16
diff -u -r1.16 sh_machdep.c
--- arch/sh/sh/sh_machdep.c 6 Jun 2007 17:15:12 -0000 1.16
+++ arch/sh/sh/sh_machdep.c 25 Sep 2007 09:53:53 -0000
@@ -716,45 +716,6 @@
  rval[1] = 0;
 }
 
-void
-setrunqueue(struct proc *p)
-{
- int whichq = p->p_priority / PPQ;
- struct prochd *q;
- struct proc *prev;
-
-#ifdef DIAGNOSTIC
- if (p->p_back != NULL || p->p_wchan != NULL || p->p_stat != SRUN)
- panic("setrunqueue");
-#endif
- q = &qs[whichq];
- prev = q->ph_rlink;
- p->p_forw = (struct proc *)q;
- q->ph_rlink = p;
- prev->p_forw = p;
- p->p_back = prev;
- whichqs |= 1 << whichq;
-}
-
-void
-remrunqueue(struct proc *p)
-{
- struct proc *prev, *next;
- int whichq = p->p_priority / PPQ;
-
-#ifdef DIAGNOSTIC
-       if (((whichqs & (1 << whichq)) == 0))
- panic("remrunqueue: bit %d not set", whichq);
-#endif
- prev = p->p_back;
- p->p_back = NULL;
- next = p->p_forw;
- prev->p_forw = next;
- next->p_back = prev;
- if (prev == next)
- whichqs &= ~(1 << whichq);
-}
-
 /*
  * Jump to reset vector.
  */
Index: arch/solbourne/solbourne/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/solbourne/solbourne/locore.s,v
retrieving revision 1.8
diff -u -r1.8 locore.s
--- arch/solbourne/solbourne/locore.s 15 Apr 2006 17:36:47 -0000 1.8
+++ arch/solbourne/solbourne/locore.s 25 Sep 2007 09:53:55 -0000
@@ -3233,291 +3233,52 @@
  .comm _C_LABEL(masterpaddr), 4
 
 /*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  */
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
-
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs)); newpsr
- * %g3 = p
- * %g4 = lastproc
- * %g5 = <free>; newpcb
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its kernel stack; we must free it.  (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- mov %o0, %g2 ! save proc for exit2() call
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it.  Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %g5
- sethi %hi(_C_LABEL(cpcb)), %g6
- mov 1, %g7
- wr %g0, PSR_S, %psr ! change to window 0, traps off
- nop; nop; nop
- wr %g0, 2, %wim ! and make window 1 the trap window
- st %g5, [%g6 + %lo(_C_LABEL(cpcb))] ! cpcb = &idle_u
- st %g7, [%g5 + PCB_WIM] ! idle_u.pcb_wim = log2(2) = 1
- set _C_LABEL(idle_u) + USPACE-CCFSZ, %sp ! set new %sp
-#ifdef DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE(%l6, %l5)
-#endif
- wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps
- call    _C_LABEL(exit2) ! exit2(p)
- mov    %g2, %o0
-
- /*
- * Now fall through to `the last switch'.  %g6 was set to
- * %hi(_C_LABEL(cpcb)), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g4 = lastproc
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR(_C_LABEL(nswitchexit)) ! nswitchexit++;
- INCR(_C_LABEL(uvmexp)+V_SWTCH) ! cnt.v_switch++;
-
- mov PSR_S|PSR_ET, %g1 ! oldpsr = PSR_S | PSR_ET;
- sethi %hi(_C_LABEL(whichqs)), %g2
- clr %g4 ! lastproc = NULL;
+ENTRY(cpu_switchto)
  sethi %hi(_C_LABEL(cpcb)), %g6
  sethi %hi(_C_LABEL(curproc)), %g7
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
-1: ! spin reading _whichqs until nonzero
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
- tst %o3
- bnz,a Lsw_scan
- wr %g1, IPL_CLOCK << 8, %psr ! (void) splclock();
- b,a 1b
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
-Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
-Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
- _ALIGN
-
-/*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away.  On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load.  If that someone
- * is the current process we avoid both store and load.
- *
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
- */
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
- /*
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g3 = p
- * %g4 = lastproc
- * %g5 = tmp 0
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
- sethi %hi(_C_LABEL(whichqs)), %g2 ! set up addr regs
- sethi %hi(_C_LABEL(cpcb)), %g6
- ld [%g6 + %lo(_C_LABEL(cpcb))], %o0
- std %o6, [%o0 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
+ ld [%g6 + %lo(_C_LABEL(cpcb))], %o2
+ std %o6, [%o2 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
  rd %psr, %g1 ! oldpsr = %psr;
- sethi %hi(_C_LABEL(curproc)), %g7
- ld [%g7 + %lo(_C_LABEL(curproc))], %g4 ! lastproc = curproc;
- st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
+ st %g1, [%o2 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
  andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
 
  /*
- * In all the fiddling we did to get this far, the thing we are
- * waiting for might have come ready, so let interrupts in briefly
- * before checking for other processes.  Note that we still have
- * curproc set---we have to fix this or we can get in trouble with
- * the run queues below.
- */
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
- nop; nop; nop ! paranoia
- wr %g1, IPL_CLOCK << 8 , %psr ! (void) splclock();
-
-Lsw_scan:
- nop; nop; nop ! paranoia
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
-
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set ffstab, %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a 1f ! yes, try byte 1
- srl %o3, 8, %o0
- b 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- b 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- b 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz idle ! if answer was 0, go idle
- EMPTY
-2: sub %o0, 1, %o4 ! which = ffs(whichqs) - 1
-3: /* end optimized inline expansion */
-
- /*
- * We found a nonempty run queue.  Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3, %o0
- add %o0, %o5, %o5
- ld [%o5], %g3 ! p = q->ph_link;
- cmp %g3, %o5 ! if (p == q)
- be Lsw_panic_rq ! panic("switch rq");
- EMPTY
- ld [%g3], %o0 ! tmp0 = p->p_forw;
- st %o0, [%o5] ! q->ph_link = tmp0;
- st %o5, [%o0 + 4] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
- EMPTY
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%g2 + %lo(_C_LABEL(whichqs))]
-1:
- /*
- * PHASE TWO: NEW REGISTER USAGE:
+ * REGISTER USAGE:
  * %g1 = oldpsr (excluding ipl bits)
  * %g2 = newpsr
- * %g3 = p
- * %g4 = lastproc
  * %g5 = newpcb
  * %g6 = %hi(_C_LABEL(cpcb))
  * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
+ * %o0 = oldproc
+ * %o1 = newproc
  * %o2 = tmp 3
  * %o3 = vm
  * %o4 = sswap
  * %o5 = <free>
  */
 
- /* firewalls */
- ld [%g3 + P_WCHAN], %o0 ! if (p->p_wchan)
- tst %o0
- bne Lsw_panic_wchan ! panic("switch wchan");
- EMPTY
- ldsb [%g3 + P_STAT], %o0 ! if (p->p_stat != SRUN)
- cmp %o0, SRUN
- bne Lsw_panic_srun ! panic("switch SRUN");
- EMPTY
-
  /*
- * Committed to running process p.
- * It may be the same as the one we were running before.
+ * Committed to running process p (in o1).
  */
+ mov %o1, %g3
+
  mov SONPROC, %o0 ! p->p_stat = SONPROC
  stb %o0, [%g3 + P_STAT]
  sethi %hi(_C_LABEL(want_resched)), %o0
  st %g0, [%o0 + %lo(_C_LABEL(want_resched))] ! want_resched = 0;
  ld [%g3 + P_ADDR], %g5 ! newpcb = p->p_addr;
- st %g0, [%g3 + 4] ! p->p_back = NULL;
  ld [%g5 + PCB_PSR], %g2 ! newpsr = newpcb->pcb_psr;
  st %g3, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = p;
 
- cmp %g3, %g4 ! p == lastproc?
- be,a Lsw_sameproc ! yes, go return 0
- wr %g2, 0, %psr ! (after restoring ipl)
-
  /*
- * Not the old process.  Save the old process, if any;
- * then load p.
+ * Save the old process, if any; then load p.
  */
- tst %g4
+ tst %o0
  be,a Lsw_load ! if no old process, go load
  wr %g1, (IPL_CLOCK << 8) | PSR_ET, %psr
 
- INCR(_C_LABEL(nswitchdiff)) ! clobbers %o0,%o1
  /*
  * save: write back all windows (including the current one).
  * XXX crude; knows nwindows <= 8
@@ -3659,16 +3420,17 @@
  */
 
  retl
- EMPTY
-1:
+ nop
 
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch().  Just set psr ipl and return.
- */
-! wr %g2, 0 %psr ! %psr = newpsr; (done earlier)
- nop
+ENTRY(cpu_idle_enter)
+ retl
+ nop
+
+ENTRY(cpu_idle_cycle)
+ retl
+ nop
+
+ENTRY(cpu_idle_leave)
  retl
  nop
 
Index: arch/sparc/conf/files.sparc
===================================================================
RCS file: /cvs/src/sys/arch/sparc/conf/files.sparc,v
retrieving revision 1.78
diff -u -r1.78 files.sparc
--- arch/sparc/conf/files.sparc 29 May 2007 09:54:03 -0000 1.78
+++ arch/sparc/conf/files.sparc 25 Sep 2007 09:53:55 -0000
@@ -291,7 +291,6 @@
 file arch/sparc/sparc/in_cksum.c inet
 file arch/sparc/sparc/intr.c
 file arch/sparc/sparc/kgdb_machdep.c kgdb
-file arch/sparc/sparc/locore2.c
 file arch/sparc/sparc/machdep.c !solbourne
 file arch/sparc/sparc/mem.c !solbourne
 file arch/sparc/sparc/mutex.c
Index: arch/sparc/sparc/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/sparc/sparc/locore.s,v
retrieving revision 1.72
diff -u -r1.72 locore.s
--- arch/sparc/sparc/locore.s 29 May 2007 09:54:01 -0000 1.72
+++ arch/sparc/sparc/locore.s 25 Sep 2007 09:53:58 -0000
@@ -4383,290 +4383,52 @@
  .comm _C_LABEL(masterpaddr), 4
 
 /*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
+ * cpu_switchto(struct proc *oldproc, struct proc *newproc)
  */
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
-
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs)); newpsr
- * %g3 = p
- * %g4 = lastproc
- * %g5 = <free>; newpcb
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its kernel stack; we must free it.  (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- mov %o0, %g2 ! save proc for exit2() call
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it.  Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %g5
- sethi %hi(_C_LABEL(cpcb)), %g6
- mov 1, %g7
- wr %g0, PSR_S, %psr ! change to window 0, traps off
- wr %g0, 2, %wim ! and make window 1 the trap window
- st %g5, [%g6 + %lo(_C_LABEL(cpcb))] ! cpcb = &idle_u
- st %g7, [%g5 + PCB_WIM] ! idle_u.pcb_wim = log2(2) = 1
- set _C_LABEL(idle_u) + USPACE-CCFSZ, %sp ! set new %sp
-#ifdef DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE(%l6, %l5)
-#endif
- wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps
- call    _C_LABEL(exit2) ! exit2(p)
- mov    %g2, %o0
-
- /*
- * Now fall through to `the last switch'.  %g6 was set to
- * %hi(_C_LABEL(cpcb)), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g4 = lastproc
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR(_C_LABEL(nswitchexit)) ! nswitchexit++;
- INCR(_C_LABEL(uvmexp)+V_SWTCH) ! cnt.v_switch++;
-
- mov PSR_S|PSR_ET, %g1 ! oldpsr = PSR_S | PSR_ET;
- sethi %hi(_C_LABEL(whichqs)), %g2
- clr %g4 ! lastproc = NULL;
+ENTRY(cpu_switchto)
  sethi %hi(_C_LABEL(cpcb)), %g6
  sethi %hi(_C_LABEL(curproc)), %g7
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
-1: ! spin reading _whichqs until nonzero
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
- tst %o3
- bnz,a Lsw_scan
- wr %g1, IPL_CLOCK << 8, %psr ! (void) splclock();
- b,a 1b
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
-Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
-Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
- _ALIGN
-
-/*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away.  On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load.  If that someone
- * is the current process we avoid both store and load.
- *
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
- */
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
- /*
- * REGISTER USAGE AT THIS POINT:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = %hi(_C_LABEL(whichqs))
- * %g3 = p
- * %g4 = lastproc
- * %g5 = tmp 0
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
- sethi %hi(_C_LABEL(whichqs)), %g2 ! set up addr regs
- sethi %hi(_C_LABEL(cpcb)), %g6
- ld [%g6 + %lo(_C_LABEL(cpcb))], %o0
- std %o6, [%o0 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
+ ld [%g6 + %lo(_C_LABEL(cpcb))], %o2
+ std %o6, [%o2 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
  rd %psr, %g1 ! oldpsr = %psr;
- sethi %hi(_C_LABEL(curproc)), %g7
- ld [%g7 + %lo(_C_LABEL(curproc))], %g4 ! lastproc = curproc;
- st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
+ st %g1, [%o2 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
  andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
 
  /*
- * In all the fiddling we did to get this far, the thing we are
- * waiting for might have come ready, so let interrupts in briefly
- * before checking for other processes.  Note that we still have
- * curproc set---we have to fix this or we can get in trouble with
- * the run queues below.
- */
- st %g0, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = NULL;
- wr %g1, 0, %psr ! (void) spl0();
- nop; nop; nop ! paranoia
- wr %g1, IPL_CLOCK << 8 , %psr ! (void) splclock();
-
-Lsw_scan:
- nop; nop; nop ! paranoia
- ld [%g2 + %lo(_C_LABEL(whichqs))], %o3
-
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set ffstab, %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a 1f ! yes, try byte 1
- srl %o3, 8, %o0
- b 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- b 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- b 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz idle ! if answer was 0, go idle
- EMPTY
-2: sub %o0, 1, %o4 ! which = ffs(whichqs) - 1
-3: /* end optimized inline expansion */
-
- /*
- * We found a nonempty run queue.  Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3, %o0
- add %o0, %o5, %o5
- ld [%o5], %g3 ! p = q->ph_link;
- cmp %g3, %o5 ! if (p == q)
- be Lsw_panic_rq ! panic("switch rq");
- EMPTY
- ld [%g3], %o0 ! tmp0 = p->p_forw;
- st %o0, [%o5] ! q->ph_link = tmp0;
- st %o5, [%o0 + 4] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
- EMPTY
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%g2 + %lo(_C_LABEL(whichqs))]
-1:
- /*
- * PHASE TWO: NEW REGISTER USAGE:
+ * REGISTER USAGE:
  * %g1 = oldpsr (excluding ipl bits)
  * %g2 = newpsr
- * %g3 = p
- * %g4 = lastproc
  * %g5 = newpcb
  * %g6 = %hi(_C_LABEL(cpcb))
  * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = tmp 1
- * %o1 = tmp 2
+ * %o0 = oldproc
+ * %o1 = newproc
  * %o2 = tmp 3
  * %o3 = vm
  * %o4 = sswap
  * %o5 = <free>
  */
 
- /* firewalls */
- ld [%g3 + P_WCHAN], %o0 ! if (p->p_wchan)
- tst %o0
- bne Lsw_panic_wchan ! panic("switch wchan");
- EMPTY
- ldsb [%g3 + P_STAT], %o0 ! if (p->p_stat != SRUN)
- cmp %o0, SRUN
- bne Lsw_panic_srun ! panic("switch SRUN");
- EMPTY
-
  /*
- * Committed to running process p.
- * It may be the same as the one we were running before.
+ * Committed to running process p (in o1).
  */
+ mov %o1, %g3
+
  mov SONPROC, %o0 ! p->p_stat = SONPROC
  stb %o0, [%g3 + P_STAT]
  sethi %hi(_C_LABEL(want_resched)), %o0
  st %g0, [%o0 + %lo(_C_LABEL(want_resched))] ! want_resched = 0;
  ld [%g3 + P_ADDR], %g5 ! newpcb = p->p_addr;
- st %g0, [%g3 + 4] ! p->p_back = NULL;
  ld [%g5 + PCB_PSR], %g2 ! newpsr = newpcb->pcb_psr;
  st %g3, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = p;
 
- cmp %g3, %g4 ! p == lastproc?
- be,a Lsw_sameproc ! yes, go return 0
- wr %g2, 0, %psr ! (after restoring ipl)
-
  /*
- * Not the old process.  Save the old process, if any;
- * then load p.
+ * Save the old process, if any; then load p.
  */
- tst %g4
+ tst %o0
  be,a Lsw_load ! if no old process, go load
  wr %g1, (IPL_CLOCK << 8) | PSR_ET, %psr
 
- INCR(_C_LABEL(nswitchdiff)) ! clobbers %o0,%o1
  /*
  * save: write back all windows (including the current one).
  * XXX crude; knows nwindows <= 8
@@ -4773,16 +4535,17 @@
  sta %o0, [%o1] ASI_SRMMU ! setcontext(vm->vm_map.pmap->pm_ctxnum);
 #endif
 
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch().  Just set psr ipl and return.
- */
-! wr %g2, 0 %psr ! %psr = newpsr; (done earlier)
- nop
+ENTRY(cpu_idle_enter)
+ retl
+ nop
+
+ENTRY(cpu_idle_cycle)
  retl
  nop
 
+ENTRY(cpu_idle_leave)
+ retl
+ nop
 
 /*
  * Snapshot the current process so that stack frames are up to date.
Index: arch/sparc/sparc/locore2.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc/sparc/locore2.c,v
retrieving revision 1.5
diff -u -r1.5 locore2.c
--- arch/sparc/sparc/locore2.c 2 Jun 2003 23:27:55 -0000 1.5
+++ arch/sparc/sparc/locore2.c 25 Sep 2007 09:53:58 -0000
@@ -1,99 +0,0 @@
-/* $OpenBSD: locore2.c,v 1.5 2003/06/02 23:27:55 millert Exp $ */
-/* $NetBSD: locore2.c,v 1.7 1996/11/06 20:19:53 cgd Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California.  All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)locore2.c 8.4 (Berkeley) 12/10/93
- */
-
-/*
- * Primitives which are in locore.s on other machines,
- * but which have no reason to be assembly-coded on SPARC.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/resourcevar.h>
-
-#include <machine/cpu.h>
-
-int whichqs;
-
-/*
- * Put process p on the run queue indicated by its priority.
- * Calls should be made at splstatclock(), and p->p_stat should be SRUN.
- */
-void
-setrunqueue(p)
- register struct proc *p;
-{
- register struct prochd *q;
- register struct proc *oldlast;
- register int which = p->p_priority >> 2;
-
- if (p->p_back != NULL)
- panic("setrunqueue");
- q = &qs[which];
- whichqs |= 1 << which;
- p->p_forw = (struct proc *)q;
- p->p_back = oldlast = q->ph_rlink;
- q->ph_rlink = p;
- oldlast->p_forw = p;
-}
-
-/*
- * Remove process p from its run queue, which should be the one
- * indicated by its priority.  Calls should be made at splstatclock().
- */
-void
-remrunqueue(p)
- register struct proc *p;
-{
- register int which = p->p_priority >> 2;
- register struct prochd *q;
-
- if ((whichqs & (1 << which)) == 0)
- panic("remrunqueue");
- p->p_forw->p_back = p->p_back;
- p->p_back->p_forw = p->p_forw;
- p->p_back = NULL;
- q = &qs[which];
- if (q->ph_link == (struct proc *)q)
- whichqs &= ~(1 << which);
-}
Index: arch/sparc/sparc/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc/sparc/vm_machdep.c,v
retrieving revision 1.49
diff -u -r1.49 vm_machdep.c
--- arch/sparc/sparc/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.49
+++ arch/sparc/sparc/vm_machdep.c 25 Sep 2007 09:53:58 -0000
@@ -449,10 +449,9 @@
 /*
  * cpu_exit is called as the last action during exit.
  *
- * We clean up a little and then call switchexit() with the old proc
- * as an argument.  switchexit() switches to the idle context, schedules
- * the old vmspace and stack to be freed, then selects a new process to
- * run.
+ * We clean up a little and then call sched_exit() with the old proc
+ * as an argument.  sched_exit() schedules the old vmspace and stack
+ * to be freed, then selects a new process to run.
  */
 void
 cpu_exit(p)
@@ -468,8 +467,8 @@
  free((void *)fs, M_SUBPROC);
  }
 
- switchexit(p);
- /* NOTREACHED */
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/sparc64/conf/files.sparc64
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/conf/files.sparc64,v
retrieving revision 1.89
diff -u -r1.89 files.sparc64
--- arch/sparc64/conf/files.sparc64 10 Sep 2007 21:33:16 -0000 1.89
+++ arch/sparc64/conf/files.sparc64 25 Sep 2007 09:53:59 -0000
@@ -243,7 +243,6 @@
 file arch/sparc64/sparc64/kgdb_machdep.c kgdb
 # sparc64/sparc64/locore.s is handled specially in the makefile,
 # because it must come first in the "ld" command line.
-file arch/sparc64/sparc64/locore2.c
 file arch/sparc64/sparc64/machdep.c
 file arch/sparc64/sparc64/mem.c
 file arch/sparc64/sparc64/mutex.S
Index: arch/sparc64/sparc64/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/locore.s,v
retrieving revision 1.82
diff -u -r1.82 locore.s
--- arch/sparc64/sparc64/locore.s 22 Sep 2007 20:04:51 -0000 1.82
+++ arch/sparc64/sparc64/locore.s 25 Sep 2007 09:54:03 -0000
@@ -5578,350 +5578,39 @@
  retl
  mov EFAULT, %o0
 
-
- .data
- _ALIGN
-/*
- * Switch statistics (for later tweaking):
- * nswitchdiff = p1 => p2 (i.e., chose different process)
- * nswitchexit = number of calls to switchexit()
- * _cnt.v_swtch = total calls to swtch+swtchexit
- */
- .comm _C_LABEL(nswitchdiff), 4
- .comm _C_LABEL(nswitchexit), 4
- .text
-/*
- * REGISTER USAGE IN cpu_switch AND switchexit:
- * This is split into two phases, more or less
- * `before we locate a new proc' and `after'.
- * Some values are the same in both phases.
- * Note that the %o0-registers are not preserved across
- * the psr change when entering a new process, since this
- * usually changes the CWP field (hence heavy usage of %g's).
- *
- * %l1 = <free>; newpcb
- * %l2 = %hi(_whichqs); newpsr
- * %l3 = p
- * %l4 = lastproc
- * %l5 = oldpsr (excluding ipl bits)
- * %l6 = %hi(cpcb)
- * %l7 = %hi(curproc)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4; whichqs; vm
- * %o4 = tmp 4; which; sswap
- * %o5 = tmp 5; q; <free>
- */
-
-/*
- * switchexit is called only from cpu_exit() before the current process
- * has freed its vmspace and kernel stack; we must schedule them to be
- * freed.  (curproc is already NULL.)
- *
- * We lay the process to rest by changing to the `idle' kernel stack,
- * and note that the `last loaded process' is nonexistent.
- */
-ENTRY(switchexit)
- /*
- * Since we're exiting we don't need to save locals or ins, so
- * we won't need the next instruction.
- */
-! save %sp, -CC64FSZ, %sp
- flushw ! We don't have anything else to run, so why not
-#ifdef DEBUG
- save %sp, -CC64FSZ, %sp
- flushw
- restore
-#endif /* DEBUG */
- wrpr %g0, PSTATE_KERN, %pstate ! Make sure we're on the right globals
- mov %o0, %l2 ! save proc arg for exit2() call XXXXX
-
- /*
- * Change pcb to idle u. area, i.e., set %sp to top of stack
- * and %psr to PSR_S|PSR_ET, and set cpcb to point to _idle_u.
- * Once we have left the old stack, we can call kmem_free to
- * destroy it.  Call it any sooner and the register windows
- * go bye-bye.
- */
- set _C_LABEL(idle_u), %l1
- sethi %hi(CPCB), %l6
-#if 0
- /* Get rid of the stack */
- rdpr %ver, %o0
- wrpr %g0, 0, %canrestore ! Fixup window state regs
- and %o0, 0x0f, %o0
- wrpr %g0, 0, %otherwin
- wrpr %g0, %o0, %cleanwin ! kernel don't care, but user does
- dec 1, %o0 ! What happens if we don't subtract 2?
- wrpr %g0, %o0, %cansave
- flushw ! DEBUG
-#endif /* 0 */
-
- stx %l1, [%l6 + %lo(CPCB)] ! cpcb = &idle_u
- set _C_LABEL(idle_u) + USPACE - CC64FSZ, %o0 ! set new %sp
- sub %o0, BIAS, %sp ! Maybe this should be a save?
- wrpr %g0, 0, %canrestore
- wrpr %g0, 0, %otherwin
- rdpr %ver, %l7
- and %l7, CWP, %l7
- wrpr %l7, 0, %cleanwin
- dec 1, %l7 ! NWINDOWS-1-1
- wrpr %l7, %cansave
- clr %fp ! End of stack.
-#ifdef DEBUG
- flushw ! DEBUG
- set _C_LABEL(idle_u), %l6
- SET_SP_REDZONE %l6, %l5
-#endif /* DEBUG */
- wrpr %g0, PSTATE_INTR, %pstate ! and then enable traps
- call _C_LABEL(exit2) ! exit2(p)
- mov %l2, %o0
-
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle) ! Acquire sched_lock
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- wrpr %g0, PIL_SCHED, %pil ! Set splsched()
-
- /*
- * Now fall through to `the last switch'.  %g6 was set to
- * %hi(cpcb), but may have been clobbered in kmem_free,
- * so all the registers described below will be set here.
- *
- * Since the process has exited we can blow its context
- * out of the MMUs now to free up those TLB entries rather
- * than have more useful ones replaced.
- *
- * REGISTER USAGE AT THIS POINT:
- * %l2 = %hi(_whichqs)
- * %l4 = lastproc
- * %l5 = oldpsr (excluding ipl bits)
- * %l6 = %hi(cpcb)
- * %l7 = %hi(curproc)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o3 = whichqs
- */
-
- INCR _C_LABEL(nswitchexit) ! nswitchexit++;
- INCR _C_LABEL(uvmexp)+V_SWTCH ! cnt.v_switch++;
-
- mov CTX_SECONDARY, %o0
- sethi %hi(_C_LABEL(whichqs)), %l2
- sethi %hi(CPCB), %l6
- sethi %hi(CURPROC), %l7
- ldxa [%o0] ASI_DMMU, %l1 ! Don't demap the kernel
- ldx [%l6 + %lo(CPCB)], %l5
- clr %l4 ! lastproc = NULL;
- brz,pn %l1, 1f
- set DEMAP_CTX_SECONDARY, %l1 ! Demap secondary context
- stxa %g1, [%l1] ASI_DMMU_DEMAP
- stxa %g1, [%l1] ASI_IMMU_DEMAP
- membar #Sync
-1:
- stxa %g0, [%o0] ASI_DMMU ! Clear out our context
- membar #Sync
- /* FALLTHROUGH */
-
-/*
- * When no processes are on the runq, switch
- * idles here waiting for something to come ready.
- * The registers are set up as noted above.
- */
- .globl idle
-idle:
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_unlock_idle) ! Release sched_lock
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- stx %g0, [%l7 + %lo(CURPROC)] ! curproc = NULL;
-1: ! spin reading _whichqs until nonzero
- wrpr %g0, PSTATE_INTR, %pstate ! Make sure interrupts are enabled
- wrpr %g0, 0, %pil ! (void) spl0();
- ld [%l2 + %lo(_C_LABEL(whichqs))], %o3
- brnz,pt %o3, notidle ! Something to run
- nop
-#ifdef UVM_PAGE_IDLE_ZERO
- ! Check uvm.page_idle_zero
- sethi %hi(_C_LABEL(uvm) + UVM_PAGE_IDLE_ZERO), %o3
- ld [%o3 + %lo(_C_LABEL(uvm) + UVM_PAGE_IDLE_ZERO)], %o3
- brz,pn %o3, 1b
- nop
-
- ! zero some pages
- call _C_LABEL(uvm_pageidlezero)
- nop
-#endif /* UVM_PAGE_IDLE_ZERO */
- ba,a,pt %xcc, 1b
- nop ! spitfire bug
-notidle:
- wrpr %g0, PIL_SCHED, %pil ! (void) splhigh();
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- call _C_LABEL(sched_lock_idle) ! Grab sched_lock
- add %o7, (Lsw_scan-.-4), %o7 ! Return to Lsw_scan directly
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- ba,a,pt %xcc, Lsw_scan
- nop ! spitfire bug
-
-Lsw_panic_rq:
- sethi %hi(1f), %o0
- call _C_LABEL(panic)
- or %lo(1f), %o0, %o0
 Lsw_panic_wchan:
- sethi %hi(2f), %o0
- call _C_LABEL(panic)
- or %lo(2f), %o0, %o0
+        sethi   %hi(1f), %o0
+        call    _C_LABEL(panic)
+         or     %lo(1f), %o0, %o0
 Lsw_panic_srun:
- sethi %hi(3f), %o0
- call _C_LABEL(panic)
- or %lo(3f), %o0, %o0
- .data
-1: .asciz "switch rq"
-2: .asciz "switch wchan"
-3: .asciz "switch SRUN"
-idlemsg: .asciz "idle %x %x %x %x"
-idlemsg1: .asciz " %x %x %x\r\n"
- _ALIGN
+        sethi   %hi(2f), %o0
+        call    _C_LABEL(panic)
+         or     %lo(2f), %o0, %o0
+        .data
+1:      .asciz  "switch wchan"
+2:      .asciz  "switch SRUN"
+
  .text
 /*
- * cpu_switch() picks a process to run and runs it, saving the current
- * one away.  On the assumption that (since most workstations are
- * single user machines) the chances are quite good that the new
- * process will turn out to be the current process, we defer saving
- * it here until we have found someone to load.  If that someone
- * is the current process we avoid both store and load.
- *
- * cpu_switch() is always entered at splstatclock or splhigh.
- *
- * IT MIGHT BE WORTH SAVING BEFORE ENTERING idle TO AVOID HAVING TO
- * SAVE LATER WHEN SOMEONE ELSE IS READY ... MUST MEASURE!
+ * cpu_switchto(struct proc *old, struct proc *new)
  *
- * Apparently cpu_switch() is called with curproc as the first argument,
- * but no port seems to make use of that parameter.
+ * Save the context of "old" and switch to "new".
  */
- .globl _C_LABEL(time)
-ENTRY(cpu_switch)
+ENTRY(cpu_switchto)
  save %sp, -CC64FSZ, %sp
- /*
- * REGISTER USAGE AT THIS POINT:
- * %l1 = tmp 0
- * %l2 = %hi(_C_LABEL(whichqs))
- * %l3 = p
- * %l4 = lastproc
- * %l5 = cpcb
- * %l6 = %hi(CPCB)
- * %l7 = %hi(CURPROC)
- * %o0 = tmp 1
- * %o1 = tmp 2
- * %o2 = tmp 3
- * %o3 = tmp 4, then at Lsw_scan, whichqs
- * %o4 = tmp 5, then at Lsw_scan, which
- * %o5 = tmp 6, then at Lsw_scan, q
- */
-#ifdef DEBUG
- set swdebug, %o1
- ld [%o1], %o1
- brz,pt %o1, 2f
- set 1f, %o0
- call printf
- nop
- .data
-1: .asciz "s"
- _ALIGN
- .globl swdebug
-swdebug: .word 0
- .text
-2:
-#endif /* DEBUG */
  flushw ! We don't have anything else to run, so why not flush
-#ifdef DEBUG
- save %sp, -CC64FSZ, %sp
- flushw
- restore
-#endif /* DEBUG */
  rdpr %pstate, %o1 ! oldpstate = %pstate;
  wrpr %g0, PSTATE_INTR, %pstate ! make sure we're on normal globals
+
+ mov %i0, %l4 ! oldproc
+ mov %i1, %l3 ! newproc
+
  sethi %hi(CPCB), %l6
- sethi %hi(_C_LABEL(whichqs)), %l2 ! set up addr regs
  ldx [%l6 + %lo(CPCB)], %l5
- sethi %hi(CURPROC), %l7
+ sethi   %hi(CURPROC), %l7
  stx %o7, [%l5 + PCB_PC] ! cpcb->pcb_pc = pc;
- ldx [%l7 + %lo(CURPROC)], %l4 ! lastproc = curproc;
  sth %o1, [%l5 + PCB_PSTATE] ! cpcb->pcb_pstate = oldpstate;
 
- stx %g0, [%l7 + %lo(CURPROC)] ! curproc = NULL;
-
-Lsw_scan:
- ld [%l2 + %lo(_C_LABEL(whichqs))], %o3
-
-#ifndef POPC
- .globl _C_LABEL(__ffstab)
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- */
- set _C_LABEL(__ffstab), %o2
- andcc %o3, 0xff, %o1 ! byte 0 zero?
- bz,a,pn %icc, 1f ! yes, try byte 1
- srl %o3, 8, %o0
- ba,pt %icc, 2f ! ffs = ffstab[byte0]; which = ffs - 1;
- ldsb [%o2 + %o1], %o0
-1: andcc %o0, 0xff, %o1 ! byte 1 zero?
- bz,a,pn %icc, 1f ! yes, try byte 2
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte1] + 7;
- ba,pt %icc, 3f
- add %o0, 7, %o4
-1: andcc %o0, 0xff, %o1 ! byte 2 zero?
- bz,a,pn %icc, 1f ! yes, try byte 3
- srl %o0, 8, %o0
- ldsb [%o2 + %o1], %o0 ! which = ffstab[byte2] + 15;
- ba,pt %icc, 3f
- add %o0, 15, %o4
-1: ldsb [%o2 + %o0], %o0 ! ffs = ffstab[byte3] + 24
- addcc %o0, 24, %o0 ! (note that ffstab[0] == -24)
- bz,pn %icc, idle ! if answer was 0, go idle
-! XXX check no delay slot
-2: sub %o0, 1, %o4
-3: /* end optimized inline expansion */
-
-#else /* POPC */
- /*
- * Optimized inline expansion of `which = ffs(whichqs) - 1';
- * branches to idle if ffs(whichqs) was 0.
- *
- * This version uses popc.
- *
- * XXXX spitfires and blackbirds don't implement popc.
- *
- */
- brz,pn %o3, idle ! Don't bother if queues are empty
- neg %o3, %o1 ! %o1 = -zz
- xnor %o3, %o1, %o2 ! %o2 = zz ^ ~ -zz
- popc %o2, %o4 ! which = popc(whichqs)
- dec %o4 ! which = ffs(whichqs) - 1
-
-#endif /* POPC */
- /*
- * We found a nonempty run queue.  Take its first process.
- */
- set _C_LABEL(qs), %o5 ! q = &qs[which];
- sll %o4, 3+1, %o0
- add %o0, %o5, %o5
- ldx [%o5], %l3 ! p = q->ph_link;
- cmp %l3, %o5 ! if (p == q)
- be,pn %icc, Lsw_panic_rq ! panic("switch rq");
-! XXX check no delay slot
- ldx [%l3], %o0 ! tmp0 = p->p_forw;
- stx %o0, [%o5] ! q->ph_link = tmp0;
- stx %o5, [%o0 + 8] ! tmp0->p_back = q;
- cmp %o0, %o5 ! if (tmp0 == q)
- bne 1f
-! XXX check no delay slot
- mov 1, %o1 ! whichqs &= ~(1 << which);
- sll %o1, %o4, %o1
- andn %o3, %o1, %o3
- st %o3, [%l2 + %lo(_C_LABEL(whichqs))]
-1:
  /*
  * PHASE TWO: NEW REGISTER USAGE:
  * %l1 = newpcb
@@ -5950,7 +5639,6 @@
 
  /*
  * Committed to running process p.
- * It may be the same as the one we were running before.
  */
 #if defined(MULTIPROCESSOR)
  /*
@@ -5963,19 +5651,7 @@
  sethi %hi(CPUINFO_VA+CI_WANT_RESCHED), %o0
  st %g0, [%o0 + %lo(CPUINFO_VA+CI_WANT_RESCHED)] ! want_resched = 0;
  ldx [%l3 + P_ADDR], %l1 ! newpcb = p->p_addr;
- stx %g0, [%l3 + 8] ! p->p_back = NULL;
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
- /*
- * Done mucking with the run queues, release the
- * scheduler lock, but keep interrupts out.
- */
- call _C_LABEL(sched_unlock_idle)
-#endif /* defined(MULTIPROCESSOR) || defined(LOCKDEBUG) */
- stx %l4, [%l7 + %lo(CURPROC)] ! restore old proc so we can save it
-
- cmp %l3, %l4 ! p == lastproc?
- be,pt %xcc, Lsw_sameproc ! yes, go return 0
- nop
+ stx %l4, [%l7 + %lo(CURPROC)] ! restore old proc so we can save it
 
  /*
  * Not the old process.  Save the old process, if any;
@@ -5985,7 +5661,6 @@
  brz,pn %l4, Lsw_load ! if no old process, go load
  wrpr %g0, PSTATE_KERN, %pstate
 
- INCR _C_LABEL(nswitchdiff) ! clobbers %o0,%o1,%o2
 wb1:
  flushw ! save all register windows except this one
  stx %i7, [%l5 + PCB_PC] ! Save rpc
@@ -6065,17 +5740,24 @@
  membar #Sync ! Maybe we should use flush here?
  flush %sp
 
-Lsw_sameproc:
- /*
- * We are resuming the process that was running at the
- * call to switch().  Just set psr ipl and return.
- */
 ! wrpr %g0, 0, %cleanwin ! DEBUG
  clr %g4 ! This needs to point to the base of the data segment
  wr %g0, ASI_PRIMARY_NOFAULT, %asi ! Restore default ASI
  wrpr %g0, PSTATE_INTR, %pstate
  ret
  restore
+
+ENTRY(cpu_idle_enter)
+ retl
+ nop
+
+ENTRY(cpu_idle_cycle)
+ retl
+ nop
+
+ENTRY(cpu_idle_leave)
+ retl
+ nop
 
 /*
  * Snapshot the current process so that stack frames are up to date.
Index: arch/sparc64/sparc64/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/vm_machdep.c,v
retrieving revision 1.15
diff -u -r1.15 vm_machdep.c
--- arch/sparc64/sparc64/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.15
+++ arch/sparc64/sparc64/vm_machdep.c 25 Sep 2007 09:54:03 -0000
@@ -316,8 +316,7 @@
  * run.
  */
 void
-cpu_exit(p)
- struct proc *p;
+cpu_exit(struct proc *p)
 {
  register struct fpstate64 *fs;
 
@@ -328,8 +327,9 @@
  }
  free((void *)fs, M_SUBPROC);
  }
- switchexit(p);
- /* NOTREACHED */
+
+ pmap_deactivate(p);
+ sched_exit(p);
 }
 
 /*
Index: arch/vax/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/vax/include/cpu.h,v
retrieving revision 1.25
diff -u -r1.25 cpu.h
--- arch/vax/include/cpu.h 16 May 2007 05:19:13 -0000 1.25
+++ arch/vax/include/cpu.h 25 Sep 2007 09:54:03 -0000
@@ -129,6 +129,10 @@
  */
 #define need_proftick(p) mtpr(AST_OK,PR_ASTLVL)
 
+#define cpu_idle_enter() do { /* nothing */ } while (0)
+#define cpu_idle_cycle() do { /* nothing */ } while (0)
+#define cpu_idle_leave() do { /* nothing */ } while (0)
+
 /*
  * This defines the I/O device register space size in pages.
  */
Index: arch/vax/include/macros.h
===================================================================
RCS file: /cvs/src/sys/arch/vax/include/macros.h,v
retrieving revision 1.14
diff -u -r1.14 macros.h
--- arch/vax/include/macros.h 6 Nov 2006 21:31:36 -0000 1.14
+++ arch/vax/include/macros.h 25 Sep 2007 09:54:03 -0000
@@ -232,15 +232,10 @@
  return ret;
 }
 
-#define setrunqueue(p) \
- __asm__ __volatile("movl %0,r0;jsb Setrq":: "g"(p):"r0","r1","r2");
-
-#define remrunqueue(p) \
- __asm__ __volatile("movl %0,r0;jsb Remrq":: "g"(p):"r0","r1","r2");
-
-#define cpu_switch(p) \
- __asm__ __volatile("movl %0,r0;movpsl -(sp);jsb Swtch" \
-    ::"g"(p):"r0","r1","r2","r3");
+#define cpu_switchto(o, n) \
+ __asm__ __volatile__( \
+    "movl %0,r0; movl %1, r1; movpsl -(sp); jsb __cpu_switchto" \
+    :: "g"(o), "g"(n) : "r0", "r1");
 
 /*
  * Interlock instructions. Used both in multiprocessor environments to
Index: arch/vax/vax/subr.s
===================================================================
RCS file: /cvs/src/sys/arch/vax/vax/subr.s,v
retrieving revision 1.26
diff -u -r1.26 subr.s
--- arch/vax/vax/subr.s 16 May 2007 05:19:15 -0000 1.26
+++ arch/vax/vax/subr.s 25 Sep 2007 09:54:04 -0000
@@ -240,114 +240,37 @@
 #endif
 
 #
-# setrunqueue/remrunqueue fast variants.
+# void
+# cpu_switchto(struct proc *oldproc = r0, struct proc *newproc = r1);
 #
 
-JSBENTRY(Setrq)
-#ifdef DIAGNOSTIC
- tstl 4(r0) # Check that process actually are off the queue
- beql 1f
- pushab setrq
- calls $1,_panic
-setrq: .asciz "setrunqueue"
-#endif
-1: extzv $2,$6,P_PRIORITY(r0),r1 # get priority
- movaq _qs[r1],r2 # get address of queue
- insque (r0),*4(r2) # put proc last in queue
- bbss r1,_whichqs,1f # set queue bit.
-1: rsb
-
-JSBENTRY(Remrq)
- extzv $2,$6,P_PRIORITY(r0),r1
-#ifdef DIAGNOSTIC
- bbs r1,_whichqs,1f
- pushab remrq
- calls $1,_panic
-remrq: .asciz "remrunqueue"
-#endif
-1: remque (r0),r2
- bneq 1f # Not last process on queue
- bbsc r1,_whichqs,1f
-1: clrl 4(r0) # saftey belt
- rsb
-
-#
-# Idle loop. Here we could do something fun, maybe, like calculating
-# pi or something.
-#
-idle: mtpr $0,$PR_IPL # Enable all types of interrupts
-1: tstl _whichqs # Anything ready to run?
- beql 1b # no, continue to loop
- brb Swtch # Yes, goto switch again.
+#define CURPROC _cpu_info_store + CI_CURPROC
 
-#
-# cpu_switch, cpu_exit and the idle loop implemented in assembler
-# for efficiency. r0 contains pointer to last process.
-#
+JSBENTRY(__cpu_switchto)
+ svpctx
 
-#define CURPROC _cpu_info_store + CI_CURPROC
+ movb $SONPROC,P_STAT(r1) # p->p_stat = SONPROC
+ movl r1, CURPROC # set new process running
 
-JSBENTRY(Swtch)
- clrl CURPROC # Stop process accounting
-#bpt
- mtpr $0x1f,$PR_IPL # block all interrupts
- ffs $0,$32,_whichqs,r3 # Search for bit set
- beql idle # no bit set, go to idle loop
-
- movaq _qs[r3],r1 # get address of queue head
- remque *(r1),r2 # remove proc pointed to by queue head
-#ifdef DIAGNOSTIC
- bvc 1f # check if something on queue
- pushab noque
- calls $1,_panic
-noque: .asciz "swtch"
-#endif
-1: bneq 2f # more processes on queue?
- bbsc r3,_whichqs,2f # no, clear bit in whichqs
-2: clrl 4(r2) # clear proc backpointer
- clrl _want_resched # we are now changing process
- movb $SONPROC,P_STAT(r2) # p->p_stat = SONPROC
- movl r2,CURPROC # set new process running
- cmpl r0,r2 # Same process?
- bneq 1f # No, continue
- rsb
-xxd:
-1: movl P_ADDR(r2),r0 # Get pointer to new pcb.
+ movl P_ADDR(r1),r0 # Get pointer to new pcb.
  addl3 r0,$IFTRAP,pcbtrap # Save for copy* functions.
 
-#
-# Nice routine to get physical from virtual addresses.
-#
+ # inline kvtophys
  extzv $9,$21,r0,r1 # extract offset
  movl *_Sysmap[r1],r2 # get pte
  ashl $9,r2,r3 # shift to get phys address.
 
 #
 # Do the actual process switch. pc + psl are already on stack, from
-# the calling routine.
+# the beginning of this routine.
 #
- svpctx
  mtpr r3,$PR_PCBB
- ldpctx
- rei
 
-#
-# the last routine called by a process.
-#
-
-ENTRY(cpu_exit,0)
- movl 4(ap),r6 # Process pointer in r6
- mtpr $0x18,$PR_IPL # Block almost everything
- addl3 $512,_scratch,sp # Change stack, and schedule it to be freed
-
- pushl r6
- calls $1,_exit2
-
- clrl r0 # No process to switch from
- bicl3 $0xc0000000,_scratch,r1
- mtpr r1,$PR_PCBB
- brw Swtch
+ pushl CURPROC
+ calls $1, _C_LABEL(pmap_activate)
 
+ ldpctx
+ rei
 
 #
 # copy/fetch/store routines.
Index: arch/vax/vax/vm_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/vax/vax/vm_machdep.c,v
retrieving revision 1.34
diff -u -r1.34 vm_machdep.c
--- arch/vax/vax/vm_machdep.c 20 Jun 2007 17:29:36 -0000 1.34
+++ arch/vax/vax/vm_machdep.c 25 Sep 2007 09:54:04 -0000
@@ -58,6 +58,16 @@
 
 #include <sys/syscallargs.h>
 
+void
+cpu_exit(struct proc *p)
+{
+ int s;
+ s = splhigh(); /* splclock(); */
+
+ pmap_deactivate(p);
+ sched_exit(p);
+}
+
 /*
  * Finish a fork operation, with process p2 nearly set up.
  * Copy and update the pcb and trap frame, making the child ready to run.
@@ -109,13 +119,6 @@
  tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1;
  p2->p_addr->u_pcb.framep = tf;
  bcopy(p1->p_addr->u_pcb.framep, tf, sizeof(*tf));
-
- /*
- * Activate address space for the new process. The PTEs have
- * already been allocated by way of pmap_create().
- * This writes the page table registers to the PCB.
- */
- pmap_activate(p2);
 
  /* Mark guard page invalid in kernel stack */
  *kvtopte((u_int)p2->p_addr + REDZONEADDR) &= ~PG_V;
Index: conf/files
===================================================================
RCS file: /cvs/src/sys/conf/files,v
retrieving revision 1.410
diff -u -r1.410 files
--- conf/files 12 Sep 2007 12:59:55 -0000 1.410
+++ conf/files 25 Sep 2007 09:54:05 -0000
@@ -645,6 +645,7 @@
 file kern/kern_proc.c
 file kern/kern_prot.c
 file kern/kern_resource.c
+file kern/kern_sched.c
 file kern/kern_sensors.c !small_kernel
 file kern/kern_sig.c
 file kern/kern_subr.c
Index: kern/init_main.c
===================================================================
RCS file: /cvs/src/sys/kern/init_main.c,v
retrieving revision 1.144
diff -u -r1.144 init_main.c
--- kern/init_main.c 10 Sep 2007 18:49:45 -0000 1.144
+++ kern/init_main.c 25 Sep 2007 09:54:07 -0000
@@ -327,7 +327,9 @@
  (void)chgproccnt(0, 1);
 
  /* Initialize run queues */
- rqinit();
+ sched_init_runqueues();
+ sleep_queue_init();
+ sched_init_cpu(curcpu());
 
  /* Initialize work queues */
  workq_init();
Index: kern/kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.64
diff -u -r1.64 kern_clock.c
--- kern/kern_clock.c 16 May 2007 17:27:30 -0000 1.64
+++ kern/kern_clock.c 25 Sep 2007 09:54:07 -0000
@@ -546,7 +546,7 @@
  if (p != NULL)
  p->p_iticks++;
  spc->spc_cp_time[CP_INTR]++;
- } else if (p != NULL) {
+ } else if (p != NULL && p != spc->spc_idleproc) {
  p->p_sticks++;
  spc->spc_cp_time[CP_SYS]++;
  } else
Index: kern/kern_exit.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.71
diff -u -r1.71 kern_exit.c
--- kern/kern_exit.c 12 Apr 2007 22:14:15 -0000 1.71
+++ kern/kern_exit.c 25 Sep 2007 09:54:08 -0000
@@ -315,16 +315,8 @@
  sigactsfree(p);
 
  /*
- * Clear curproc after we've done all operations
- * that could block, and before tearing down the rest
- * of the process state that might be used from clock, etc.
- * Also, can't clear curproc while we're still runnable,
- * as we're not on a run queue (we are current, just not
- * a proper proc any longer!).
- *
- * Other substructures are freed from wait().
+ * Other substructures are freed from reaper and wait().
  */
- curproc = NULL;
 
  /*
  * If emulation has process exit hook, call it now.
@@ -373,15 +365,11 @@
 void
 exit2(struct proc *p)
 {
- int s;
-
  mtx_enter(&deadproc_mutex);
  LIST_INSERT_HEAD(&deadproc, p, p_hash);
  mtx_leave(&deadproc_mutex);
 
  wakeup(&deadproc);
-
- SCHED_LOCK(s);
 }
 
 /*
@@ -395,6 +383,8 @@
  struct proc *p;
 
  KERNEL_PROC_UNLOCK(curproc);
+
+ SCHED_ASSERT_UNLOCKED();
 
  for (;;) {
  mtx_enter(&deadproc_mutex);
Index: kern/kern_fork.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.92
diff -u -r1.92 kern_fork.c
--- kern/kern_fork.c 25 Jul 2007 23:11:52 -0000 1.92
+++ kern/kern_fork.c 25 Sep 2007 09:54:08 -0000
@@ -224,7 +224,6 @@
 
  p2->p_stat = SIDL; /* protect against others */
  p2->p_exitsig = exitsig;
- p2->p_forw = p2->p_back = NULL;
 
 #ifdef RTHREADS
  if (flags & FORK_THREAD) {
@@ -501,7 +500,12 @@
 
  p = curproc;
 
+ SCHED_ASSERT_LOCKED();
+ __mp_unlock(&sched_lock);
+ spl0();
  SCHED_ASSERT_UNLOCKED();
+ KASSERT(__mp_lock_held(&kernel_lock) == 0);
+
  KERNEL_PROC_LOCK(p);
 }
 #endif
Index: kern/kern_proc.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.35
diff -u -r1.35 kern_proc.c
--- kern/kern_proc.c 7 Sep 2007 15:00:20 -0000 1.35
+++ kern/kern_proc.c 25 Sep 2007 09:54:08 -0000
@@ -377,8 +377,8 @@
     p->p_comm, p->p_pid, pst, p->p_flag, P_BITS);
  (*pr)("    pri=%u, usrpri=%u, nice=%d\n",
     p->p_priority, p->p_usrpri, p->p_nice);
- (*pr)("    forw=%p, back=%p, list=%p,%p\n",
-    p->p_forw, p->p_back, p->p_list.le_next, p->p_list.le_prev);
+ (*pr)("    forw=%p, list=%p,%p\n",
+    TAILQ_NEXT(p, p_runq), p->p_list.le_next, p->p_list.le_prev);
  (*pr)("    user=%p, vmspace=%p\n",
     p->p_addr, p->p_vmspace);
  (*pr)("    estcpu=%u, cpticks=%d, pctcpu=%u.%u%, swtime=%u\n",
Index: kern/kern_sched.c
===================================================================
RCS file: kern/kern_sched.c
diff -N kern/kern_sched.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kern/kern_sched.c 25 Sep 2007 09:54:08 -0000
@@ -0,0 +1,242 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2007 Artur Grabowski <[hidden email]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+
+#include <sys/sched.h>
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/mutex.h>
+
+#include <uvm/uvm_extern.h>
+
+struct proc *sched_chooseproc(void);
+void sched_kthreads_create(void *);
+void sched_idle(void *);
+
+/*
+ * A few notes about cpu_switchto that is implemented in MD code.
+ *
+ * cpu_switchto takes two arguments, the old proc and the proc
+ * it should switch to. The new proc will never be NULL, so we always have
+ * a saved state that we need to switch to. The old proc however can
+ * be NULL if the process is exiting. NULL for the old proc simply
+ * means "don't bother saving old state".
+ *
+ * cpu_switchto is supposed to atomically load the new state of the process
+ * including the pcb, pmap and setting curproc, the p_cpu pointer in the
+ * proc and p_stat to SONPROC. Atomically with respect to interrupts, other
+ * cpus in the system must not depend on this state being consistent.
+ * Therefore no locking is necessary in cpu_switchto other than blocking
+ * interrupts during the context switch.
+ */
+
+/*
+ * sched_init_cpu is called from main() for the boot cpu, then it's the
+ * responsibility of the MD code to call it for all other cpus.
+ */
+void
+sched_init_cpu(struct cpu_info *ci)
+{
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+
+ spc->spc_idleproc = NULL;
+
+ kthread_create_deferred(sched_kthreads_create, ci);
+
+ LIST_INIT(&spc->spc_deadproc);
+}
+
+void
+sched_kthreads_create(void *v)
+{
+ struct cpu_info *ci = v;
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+ static int num;
+
+ if (kthread_create(sched_idle, ci, &spc->spc_idleproc, "idle%d", num))
+ panic("fork idle");
+
+ num++;
+}
+
+void
+sched_idle(void *v)
+{
+ struct proc *p = curproc;
+ struct cpu_info *ci = v;
+ int s;
+
+ KERNEL_PROC_UNLOCK(p);
+
+ /*
+ * First time we enter here, we're not supposed to idle,
+ * just go away for a while.
+ */
+ SCHED_LOCK(s);
+ p->p_stat = SSLEEP;
+ mi_switch();
+ SCHED_UNLOCK(s);
+
+ while (1) {
+ KASSERT(ci == curcpu());
+ KASSERT(curproc == ci->ci_schedstate.spc_idleproc);
+
+ while (!sched_is_idle()) {
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+ struct proc *dead;
+
+ SCHED_LOCK(s);
+ p->p_stat = SSLEEP;
+ mi_switch();
+ SCHED_UNLOCK(s);
+
+ while ((dead = LIST_FIRST(&spc->spc_deadproc))) {
+ LIST_REMOVE(dead, p_hash);
+ exit2(dead);
+ }
+ }
+
+ cpu_idle_enter();
+ while (sched_is_idle())
+ cpu_idle_cycle();
+ cpu_idle_leave();
+ }
+}
+
+/*
+ * To free our address space we have to jump through a few hoops.
+ * The freeing is done by the reaper, but until we have one reaper
+ * per cpu, we have no way of putting this proc on the deadproc list
+ * and waking up the reaper without risking having our address space and
+ * stack torn from under us before we manage to switch to another proc.
+ * Therefore we have a per-cpu list of dead processes where we put this
+ * proc and have idle clean up that list and move it to the reaper list.
+ * All this will be unnecessary once we can bind the reaper this cpu
+ * and not risk having it switch to another in case it sleeps.
+ */
+void
+sched_exit(struct proc *p)
+{
+ struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
+ struct timeval tv;
+ struct proc *idle;
+ int s;
+
+ microuptime(&tv);
+ timersub(&tv, &spc->spc_runtime, &tv);
+ timeradd(&p->p_rtime, &tv, &p->p_rtime);
+
+ LIST_INSERT_HEAD(&spc->spc_deadproc, p, p_hash);
+
+#ifdef MULTIPROCESSOR
+ KASSERT(__mp_lock_held(&kernel_lock) == 0);
+#endif
+
+ SCHED_LOCK(s);
+ idle = spc->spc_idleproc;
+ idle->p_stat = SRUN;
+ cpu_switchto(NULL, idle);
+}
+
+/*
+ * Run queue management.
+ *
+ * The run queue management is just like before, except that it's with
+ * a bit more modern queue handling.
+ */
+
+TAILQ_HEAD(prochead, proc) sched_qs[NQS];
+volatile int sched_whichqs;
+
+void
+sched_init_runqueues(void)
+{
+ int i;
+
+ for (i = 0; i < NQS; i++)
+ TAILQ_INIT(&sched_qs[i]);
+
+#ifdef MULTIPROCESSOR
+ SIMPLE_LOCK_INIT(&sched_lock);
+#endif
+}
+
+void
+setrunqueue(struct proc *p)
+{
+ int queue = p->p_priority >> 2;
+
+ SCHED_ASSERT_LOCKED();
+
+ TAILQ_INSERT_TAIL(&sched_qs[queue], p, p_runq);
+ sched_whichqs |= (1 << queue);
+}
+
+void
+remrunqueue(struct proc *p)
+{
+ int queue = p->p_priority >> 2;
+
+ SCHED_ASSERT_LOCKED();
+
+ TAILQ_REMOVE(&sched_qs[queue], p, p_runq);
+ if (TAILQ_EMPTY(&sched_qs[queue]))
+ sched_whichqs &= ~(1 << queue);
+}
+
+struct proc *
+sched_chooseproc(void)
+{
+ struct proc *p;
+ int queue;
+
+ SCHED_ASSERT_LOCKED();
+
+again:
+ if (sched_whichqs == 0) {
+ p = curcpu()->ci_schedstate.spc_idleproc;
+ if (p == NULL) {
+                        int s;
+ /*
+ * We get here if someone decides to switch during
+ * boot before forking kthreads, bleh.
+ * This is kind of like a stupid idle loop.
+ */
+#ifdef MULTIPROCESSOR
+ __mp_unlock(&sched_lock);
+#endif
+ spl0();
+ delay(10);
+ SCHED_LOCK(s);
+ goto again;
+                }
+ KASSERT(p);
+ p->p_stat = SRUN;
+ } else {
+ queue = ffs(sched_whichqs) - 1;
+ p = TAILQ_FIRST(&sched_qs[queue]);
+ TAILQ_REMOVE(&sched_qs[queue], p, p_runq);
+ if (TAILQ_EMPTY(&sched_qs[queue]))
+ sched_whichqs &= ~(1 << queue);
+ }
+
+ return (p);
+}
Index: kern/kern_synch.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.80
diff -u -r1.80 kern_synch.c
--- kern/kern_synch.c 16 May 2007 17:27:30 -0000 1.80
+++ kern/kern_synch.c 25 Sep 2007 09:54:08 -0000
@@ -67,10 +67,17 @@
  */
 #define TABLESIZE 128
 #define LOOKUP(x) (((long)(x) >> 8) & (TABLESIZE - 1))
-struct slpque {
- struct proc *sq_head;
- struct proc **sq_tailp;
-} slpque[TABLESIZE];
+TAILQ_HEAD(slpque,proc) slpque[TABLESIZE];
+
+void
+sleep_queue_init(void)
+{
+ int i;
+
+ for (i = 0; i < TABLESIZE; i++)
+ TAILQ_INIT(&slpque[i]);
+}
+
 
 /*
  * During autoconfiguration or after a panic, a sleep will simply
@@ -133,15 +140,12 @@
 sleep_setup(struct sleep_state *sls, void *ident, int prio, const char *wmesg)
 {
  struct proc *p = curproc;
- struct slpque *qp;
 
 #ifdef DIAGNOSTIC
  if (ident == NULL)
  panic("tsleep: no ident");
  if (p->p_stat != SONPROC)
  panic("tsleep: not SONPROC");
- if (p->p_back != NULL)
- panic("tsleep: p_back not NULL");
 #endif
 
 #ifdef KTRACE
@@ -159,12 +163,7 @@
  p->p_wmesg = wmesg;
  p->p_slptime = 0;
  p->p_priority = prio & PRIMASK;
- qp = &slpque[LOOKUP(ident)];
- if (qp->sq_head == 0)
- qp->sq_head = p;
- else
- *qp->sq_tailp = p;
- *(qp->sq_tailp = &p->p_forw) = NULL;
+ TAILQ_INSERT_TAIL(&slpque[LOOKUP(ident)], p, p_runq);
 }
 
 void
@@ -179,11 +178,12 @@
  mi_switch();
  } else if (!do_sleep) {
  unsleep(p);
+ }
+
 #ifdef DIAGNOSTIC
- if (p->p_stat != SONPROC)
- panic("sleep_finish !SONPROC");
+ if (p->p_stat != SONPROC)
+ panic("sleep_finish !SONPROC");
 #endif
- }
 
  p->p_cpu->ci_schedstate.spc_curpriority = p->p_usrpri;
  SCHED_UNLOCK(sls->sls_s);
@@ -296,17 +296,9 @@
 void
 unsleep(struct proc *p)
 {
- struct slpque *qp;
- struct proc **hp;
-
  if (p->p_wchan) {
- hp = &(qp = &slpque[LOOKUP(p->p_wchan)])->sq_head;
- while (*hp != p)
- hp = &(*hp)->p_forw;
- *hp = p->p_forw;
- if (qp->sq_tailp == &p->p_forw)
- qp->sq_tailp = hp;
- p->p_wchan = 0;
+ TAILQ_REMOVE(&slpque[LOOKUP(p->p_wchan)], p, p_runq);
+ p->p_wchan = NULL;
  }
 }
 
@@ -317,25 +309,22 @@
 wakeup_n(void *ident, int n)
 {
  struct slpque *qp;
- struct proc *p, **q;
+ struct proc *p;
+ struct proc *pnext;
  int s;
 
  SCHED_LOCK(s);
  qp = &slpque[LOOKUP(ident)];
-restart:
- for (q = &qp->sq_head; (p = *q) != NULL; ) {
+ for (p = TAILQ_FIRST(qp); p != NULL && n != 0; p = pnext) {
+ pnext = TAILQ_NEXT(p, p_runq);
 #ifdef DIAGNOSTIC
- if (p->p_back)
- panic("wakeup: p_back not NULL");
  if (p->p_stat != SSLEEP && p->p_stat != SSTOP)
  panic("wakeup: p_stat is %d", (int)p->p_stat);
 #endif
  if (p->p_wchan == ident) {
  --n;
  p->p_wchan = 0;
- *q = p->p_forw;
- if (qp->sq_tailp == &p->p_forw)
- qp->sq_tailp = q;
+ TAILQ_REMOVE(qp, p, p_runq);
  if (p->p_stat == SSLEEP) {
  /* OPTIMIZED EXPANSION OF setrunnable(p); */
  if (p->p_slptime > 1)
@@ -357,13 +346,8 @@
  need_resched(p->p_cpu);
  /* END INLINE EXPANSION */
 
- if (n != 0)
- goto restart;
- else
- break;
  }
- } else
- q = &p->p_forw;
+ }
  }
  SCHED_UNLOCK(s);
 }
Index: kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.157
diff -u -r1.157 kern_sysctl.c
--- kern/kern_sysctl.c 7 Sep 2007 15:00:20 -0000 1.157
+++ kern/kern_sysctl.c 25 Sep 2007 09:54:10 -0000
@@ -1280,9 +1280,7 @@
  ki->p_vm_tsize = vm->vm_tsize;
  ki->p_vm_dsize = vm->vm_dused;
  ki->p_vm_ssize = vm->vm_ssize;
-
- ki->p_forw = PTRTOINT64(p->p_forw);
- ki->p_back = PTRTOINT64(p->p_back);
+ ki->p_forw = ki->p_back = 0;
  ki->p_addr = PTRTOINT64(p->p_addr);
  ki->p_stat = p->p_stat;
  ki->p_swtime = p->p_swtime;
Index: kern/sched_bsd.c
===================================================================
RCS file: /cvs/src/sys/kern/sched_bsd.c,v
retrieving revision 1.12
diff -u -r1.12 sched_bsd.c
--- kern/sched_bsd.c 18 May 2007 16:10:15 -0000 1.12
+++ kern/sched_bsd.c 25 Sep 2007 09:54:10 -0000
@@ -57,9 +57,6 @@
 int lbolt; /* once a second sleep address */
 int rrticks_init; /* # of hardclock ticks per roundrobin() */
 
-int whichqs; /* Bit mask summary of non-empty Q's. */
-struct prochd qs[NQS];
-
 struct SIMPLELOCK sched_lock;
 
 void scheduler_start(void);
@@ -359,29 +356,26 @@
  SCHED_UNLOCK(s);
 }
 
-
-/*
- * Must be called at splstatclock() or higher.
- */
 void
 mi_switch(void)
 {
- struct proc *p = curproc; /* XXX */
+ struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
+ struct proc *p = curproc;
+ struct proc *nextproc;
  struct rlimit *rlim;
  struct timeval tv;
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
  int hold_count;
  int sched_count;
 #endif
- struct schedstate_percpu *spc = &p->p_cpu->ci_schedstate;
+
+ KASSERT(p->p_stat != SONPROC);
 
  SCHED_ASSERT_LOCKED();
 
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
  /*
  * Release the kernel_lock, as we are about to yield the CPU.
- * The scheduler lock is still held until cpu_switch()
- * selects a new process and removes it from the run queue.
  */
  sched_count = __mp_release_all_but_one(&sched_lock);
  if (p->p_flag & P_BIGLOCK)
@@ -391,7 +385,6 @@
  /*
  * Compute the amount of time during which the current
  * process was running, and add that to its total so far.
- * XXX - use microuptime here to avoid strangeness.
  */
  microuptime(&tv);
  if (timercmp(&tv, &spc->spc_runtime, <)) {
@@ -427,16 +420,27 @@
  */
  spc->spc_schedflags &= ~SPCF_SWITCHCLEAR;
 
- /*
- * Pick a new current process and record its start time.
- */
- uvmexp.swtch++;
- cpu_switch(p);
+ nextproc = sched_chooseproc();
+
+ if (p != nextproc) {
+ uvmexp.swtch++;
+ cpu_switchto(p, nextproc);
+ } else {
+ p->p_stat = SONPROC;
+ }
+
+ SCHED_ASSERT_LOCKED();
 
  /*
- * Make sure that MD code released the scheduler lock before
- * resuming us.
+ * To preserve lock ordering, we need to release the sched lock
+ * and grab it after we grab the big lock.
+ * In the future, when the sched lock isn't recursive, we'll
+ * just release it here.
  */
+#ifdef MULTIPROCESSOR
+ __mp_unlock(&sched_lock);
+#endif
+
  SCHED_ASSERT_UNLOCKED();
 
  /*
@@ -444,11 +448,11 @@
  * 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());
+ KASSERT(p->p_cpu == curcpu());
+
  microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
 
-#if defined(MULTIPROCESSOR)
+#ifdef MULTIPROCESSOR
  /*
  * Reacquire the kernel_lock now.  We do this after we've
  * released the scheduler lock to avoid deadlock, and before
@@ -458,20 +462,6 @@
  __mp_acquire_count(&kernel_lock, hold_count);
  __mp_acquire_count(&sched_lock, sched_count + 1);
 #endif
-}
-
-/*
- * Initialize the (doubly-linked) run queues
- * to be empty.
- */
-void
-rqinit(void)
-{
- int i;
-
- for (i = 0; i < NQS; i++)
- qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i];
- SIMPLE_LOCK_INIT(&sched_lock);
 }
 
 static __inline void
Index: sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.100
diff -u -r1.100 proc.h
--- sys/proc.h 25 Jul 2007 23:11:53 -0000 1.100
+++ sys/proc.h 25 Sep 2007 09:54:11 -0000
@@ -148,8 +148,7 @@
 #endif
 
 struct proc {
- struct proc *p_forw; /* Doubly-linked run/sleep queue. */
- struct proc *p_back;
+ TAILQ_ENTRY(proc) p_runq;
  LIST_ENTRY(proc) p_list; /* List of all processes. */
 
  struct process *p_p; /* The process of this thread. */
@@ -401,14 +400,6 @@
 extern struct pool session_pool; /* memory pool for sessions */
 extern struct pool pcred_pool; /* memory pool for pcreds */
 
-#define NQS 32 /* 32 run queues. */
-extern int whichqs; /* Bit mask summary of non-empty Q's. */
-struct prochd {
- struct proc *ph_link; /* Linked list of running processes. */
- struct proc *ph_rlink;
-};
-extern struct prochd qs[NQS];
-
 struct simplelock;
 
 struct proc *pfind(pid_t); /* Find process by id. */
@@ -423,17 +414,10 @@
 int leavepgrp(struct proc *p);
 void yield(void);
 void preempt(struct proc *);
-void mi_switch(void);
 void pgdelete(struct pgrp *pgrp);
 void procinit(void);
-#if !defined(remrunqueue)
-void remrunqueue(struct proc *);
-#endif
 void resetpriority(struct proc *);
 void setrunnable(struct proc *);
-#if !defined(setrunqueue)
-void setrunqueue(struct proc *);
-#endif
 void unsleep(struct proc *);
 void    wakeup_n(void *chan, int);
 void    wakeup(void *chan);
@@ -441,17 +425,13 @@
 void reaper(void);
 void exit1(struct proc *, int, int);
 void exit2(struct proc *);
+void cpu_exit(struct proc *);
 int fork1(struct proc *, int, int, void *, size_t, void (*)(void *),
     void *, register_t *, struct proc **);
-void rqinit(void);
 int groupmember(gid_t, struct ucred *);
-#if !defined(cpu_switch)
-void cpu_switch(struct proc *);
-#endif
 #if !defined(cpu_wait)
 void cpu_wait(struct proc *);
 #endif
-void cpu_exit(struct proc *);
 
 void child_return(void *);
 
@@ -471,6 +451,7 @@
 void sleep_finish(struct sleep_state *, int);
 int sleep_finish_timeout(struct sleep_state *);
 int sleep_finish_signal(struct sleep_state *);
+void sleep_queue_init(void);
 
 int tsleep(void *, int, const char *, int);
 #define ltsleep(c, p, w, t, l) tsleep(c, p, w, t)
Index: sys/sched.h
===================================================================
RCS file: /cvs/src/sys/sys/sched.h,v
retrieving revision 1.16
diff -u -r1.16 sched.h
--- sys/sched.h 18 May 2007 14:41:55 -0000 1.16
+++ sys/sched.h 25 Sep 2007 09:54:11 -0000
@@ -105,6 +105,11 @@
  int spc_rrticks; /* ticks until roundrobin() */
  int spc_pscnt; /* prof/stat counter */
  int spc_psdiv; /* prof/stat divisor */
+ struct proc *spc_idleproc; /* idle proc for this cpu */
+#ifdef notyet
+ struct proc *spc_reaper; /* dead proc reaper */
+#endif
+ LIST_HEAD(,proc) spc_deadproc;
 };
 
 #ifdef _KERNEL
@@ -114,6 +119,8 @@
 #define SPCF_SHOULDYIELD        0x0002  /* process should yield the CPU */
 #define SPCF_SWITCHCLEAR        (SPCF_SEENRR|SPCF_SHOULDYIELD)
 
+
+#define NQS 32 /* 32 run queues. */
 #define PPQ (128 / NQS) /* priorities per queue */
 #define NICE_WEIGHT 2 /* priorities per nice level */
 #define ESTCPULIM(e) min((e), NICE_WEIGHT * PRIO_MAX - PPQ)
@@ -126,7 +133,21 @@
 struct cpu_info;
 void roundrobin(struct cpu_info *);
 
-#define sched_is_idle() (whichqs == 0)
+void sched_init_cpu(struct cpu_info *);
+void sched_exit(struct proc *);
+void mi_switch(void);
+void cpu_switchto(struct proc *, struct proc *);
+struct proc *sched_chooseproc(void);
+void cpu_idle_enter(void);
+void cpu_idle_cycle(void);
+void cpu_idle_leave(void);
+
+extern volatile int sched_whichqs;
+#define sched_is_idle() (sched_whichqs == 0)
+
+void sched_init_runqueues(void);
+void setrunqueue(struct proc *);
+void remrunqueue(struct proc *);
 
 /* Inherit the parent's scheduler history */
 #define scheduler_fork_hook(parent, child) do { \
Index: uvm/uvm_meter.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_meter.c,v
retrieving revision 1.22
diff -u -r1.22 uvm_meter.c
--- uvm/uvm_meter.c 14 Feb 2007 00:53:48 -0000 1.22
+++ uvm/uvm_meter.c 25 Sep 2007 09:54:11 -0000
@@ -109,6 +109,8 @@
  continue;
  /* FALLTHROUGH */
  case SRUN:
+ if (p == p->p_cpu->ci_schedstate.spc_idleproc)
+ continue;
  case SIDL:
  case SONPROC:
  nrun++;

Reply | Threaded
Open this post in threaded view
|

Re: Scheduler diff needs wide testing.

Frank Denis (Jedi/Sector One)-5
   Hello Artur,
   
   I'm testing it since the diff was posted on x86 SMP, running KDE, Firefox,d
Amarok, Mplayer, PHP and Ruby.

   Everything's is perfect so far.

Reply | Threaded
Open this post in threaded view
|

Re: Scheduler diff needs wide testing.

Ingo Schwarze
In reply to this post by Artur Grabowski
Hi Art,

on i386/current, the kernel compiles and runs fine.

But.  You patch like this:

> --- sys/proc.h 25 Jul 2007 23:11:53 -0000 1.100
> +++ sys/proc.h 25 Sep 2007 09:54:11 -0000
> @@ -148,8 +148,7 @@
>  #endif
>  
>  struct proc {
> - struct proc *p_forw; /* Doubly-linked run/sleep queue. */
> - struct proc *p_back;
> + TAILQ_ENTRY(proc) p_runq;
>   LIST_ENTRY(proc) p_list; /* List of all processes. */

In
  /usr/src/lib/libkvm
we have
  #include <sys/proc.h>
  kvm_getproc2(...
    struct kinfo_proc *kp;
      /* kp->kp_proc is struct proc, see <sys/sysctl.h> */
      kp2p->p_forw = PTRTOINT64(kp->kp_proc.p_forw);

Consequently,
  cd /usr/src/lib/libkvm; make
dies from
  /usr/src/lib/libkvm/kvm_proc.c:481:
    error: structure has no member named `p_back'

Do i understand correctly that you are only working on the
kernel right now and plan to adapt userland later?
On the other hand, p_forw and p_back seem sparse in userland,
except for the single occurrence in the single file kvm_proc.c.

A quick grep revealed the following places where p_forw and p_back
still linger in the kernel sources:

sys/sys/sysctl.h /* fields in struct kinfo_proc2 - OK? */
sys/kern/kern_sysctl.c /* referencing struct kinfo_proc2 - OK? */
sys/arch/amd64/amd64/Locore.c /* referencing struct proc - OOPS? */
sys/arch/powerpc/powerpc/Locore.c /* referencing struct proc - OOPS? */
sys/arch/sparc64/sparc64/locore2.c /* referencing struct proc - OOPS? */
sys/arch/hppa64/hppa64/genassym.cf /* referencing struct proc - OOPS? */
sys/arch/mvmeppc/mvmeppc/genassym.cf /* referencing struct proc - OOPS? */

So far for now,
  Ingo

Reply | Threaded
Open this post in threaded view
|

Re: Scheduler diff needs wide testing.

Miod Vallat
> Consequently,
>   cd /usr/src/lib/libkvm; make
> dies from
>   /usr/src/lib/libkvm/kvm_proc.c:481:
>     error: structure has no member named `p_back'
>
> Do i understand correctly that you are only working on the
> kernel right now and plan to adapt userland later?

No, art keeps forgetting to send the userland part of the diff.

> A quick grep revealed the following places where p_forw and p_back
> still linger in the kernel sources:
>
> sys/sys/sysctl.h /* fields in struct kinfo_proc2 - OK? */
> sys/kern/kern_sysctl.c /* referencing struct kinfo_proc2 - OK? */

That's ok, kinfo_proc2 is a stable API and not supposed to change.

> sys/arch/amd64/amd64/Locore.c /* referencing struct proc - OOPS? */
> sys/arch/powerpc/powerpc/Locore.c /* referencing struct proc - OOPS? */
> sys/arch/sparc64/sparc64/locore2.c /* referencing struct proc - OOPS? */

These files are no longer referenced after the diff is applied, and will
be deleted.

> sys/arch/hppa64/hppa64/genassym.cf /* referencing struct proc - OOPS? */
> sys/arch/mvmeppc/mvmeppc/genassym.cf /* referencing struct proc - OOPS? */

These two platforms are currently not in buildable state, leaving them
untouched is intentional.

Miod

Reply | Threaded
Open this post in threaded view
|

Re: Scheduler diff needs wide testing.

Ingo Schwarze
Hi Miod,

Miod Vallat wrote on Thu, Sep 27, 2007 at 09:48:18AM +0000:

> No, art keeps forgetting to send the userland part of the diff.

Ok, so what i came up with so far is below.
I'm not quite sure this is complete and correct, but at least it
compiles - and so far, i do not see any regressions.

In private communication, Marco S. Hyman also sent me two patches,
saying those were from "mido@".  That's you, probably?  ;)
 - Regarding kvm_proc.c, the patches from Marco suggest to
   just drop the two lines without substituting anything else.
   Hm, well, indeed kinfo_proc2.p_{forw,back} do not appear
   to be in heavy use, anywhere.
 - Regarding i386nbsd-nat.c, Marco sent me nothing, so you
   need to blame me for any bugs in that one.  But as far as
   i see from sys/, sf_ppl was always 0 even before art@
   patched it away, so what i do should preserve the
   original behaviour.
 - The patch to top/display.c is from Marco.

Index: lib/libkvm/kvm_proc.c
===================================================================
RCS file: /cvs/src/lib/libkvm/kvm_proc.c,v
retrieving revision 1.34
diff -u -p -r1.34 kvm_proc.c
--- kvm_proc.c 18 Jun 2007 21:51:15 -0000 1.34
+++ kvm_proc.c 26 Sep 2007 21:02:28 -0000
@@ -477,8 +477,10 @@ kvm_getproc2(kvm_t *kd, int op, int arg,
  kp2p = &kp2;
  for (i = 0; i < nprocs; i++, kp++) {
  memset(kp2p, 0, sizeof(kp2));
- kp2p->p_forw = PTRTOINT64(kp->kp_proc.p_forw);
- kp2p->p_back = PTRTOINT64(kp->kp_proc.p_back);
+ kp2p->p_forw =
+    PTRTOINT64(TAILQ_NEXT(&kp->kp_proc, p_runq));
+ kp2p->p_back =
+    PTRTOINT64(*kp->kp_proc.p_runq.tqe_prev);
  kp2p->p_paddr = PTRTOINT64(kp->kp_eproc.e_paddr);
 
  kp2p->p_addr = PTRTOINT64(kp->kp_proc.p_addr);
Index: gnu/usr.bin/binutils/gdb/i386nbsd-nat.c
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c,v
retrieving revision 1.6
diff -u -p -r1.6 i386nbsd-nat.c
--- i386nbsd-nat.c 27 Feb 2005 19:03:18 -0000 1.6
+++ i386nbsd-nat.c 27 Sep 2007 17:53:48 -0000
@@ -60,26 +60,13 @@ i386nbsd_supply_pcb (struct regcache *re
   if (pcb->pcb_esp == 0)
     return 0;
 
-  /* Read the stack frame, and check its validity.  We do this by
-     checking if the saved interrupt priority level in the stack frame
-     looks reasonable..  */
+  /* Read the stack frame */
   read_memory (pcb->pcb_esp, (char *) &sf, sizeof sf);
-  if ((unsigned int) sf.sf_ppl < 0x100 && (sf.sf_ppl & 0xf) == 0)
-    {
-      /* Yes, we have a frame that matches cpu_switch().  */
       pcb->pcb_esp += sizeof (struct switchframe);
       regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
       regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
       regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
       regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
-    }
-  else
-    {
-      /* No, the pcb must have been last updated by savectx().  */
-      pcb->pcb_esp += 4;
-      regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf);
-    }
-
   regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
   regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
Index: usr.bin/top/display.c
===================================================================
RCS file: /cvs/src/usr.bin/top/display.c,v
retrieving revision 1.28
diff -u -p -r1.28 display.c
--- usr.bin/top/display.c 2007/07/27 14:01:16 1.28
+++ usr.bin/top/display.c 2007/09/22 09:33:02
@@ -46,6 +46,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/queue.h>
 #include <sys/sched.h>
 #include <curses.h>
 #include <errno.h>