summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_fork.c6
-rw-r--r--sys/kern/kern_synch.c8
-rw-r--r--sys/kern/subr_trap.c1
3 files changed, 14 insertions, 1 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index ee5b602..c754e5d 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -651,6 +651,11 @@ fork_exit(callout, arg, frame)
{
struct proc *p;
+ /*
+ * Setup the sched_lock state so that we can release it.
+ */
+ sched_lock.mtx_lock = curproc;
+ sched_lock.mtx_recurse = 0;
mtx_unlock_spin(&sched_lock);
/*
* XXX: We really shouldn't have to do this.
@@ -668,6 +673,7 @@ fork_exit(callout, arg, frame)
* have this call a non-return function to stay in kernel mode.
* initproc has its own fork handler, but it does return.
*/
+ KASSERT(callout != NULL, ("NULL callout in fork_exit"));
callout(arg, frame);
/*
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 694bdf1..1f21422 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -848,6 +848,7 @@ mi_switch()
register struct rlimit *rlim;
#endif
int x;
+ u_int sched_nest;
/*
* XXX this spl is almost unnecessary. It is partly to allow for
@@ -922,7 +923,14 @@ mi_switch()
PCPU_SET(switchtime, new_switchtime);
CTR4(KTR_PROC, "mi_switch: old proc %p (pid %d, %s), schedlock %p",
p, p->p_pid, p->p_comm, (void *) sched_lock.mtx_lock);
+ sched_nest = sched_lock.mtx_recurse;
+ curproc->p_lastcpu = curproc->p_oncpu;
+ curproc->p_oncpu = NOCPU;
+ clear_resched();
cpu_switch();
+ curproc->p_oncpu = PCPU_GET(cpuid);
+ sched_lock.mtx_recurse = sched_nest;
+ sched_lock.mtx_lock = curproc;
CTR4(KTR_PROC, "mi_switch: new proc %p (pid %d, %s), schedlock %p",
p, p->p_pid, p->p_comm, (void *) sched_lock.mtx_lock);
if (PCPU_GET(switchtime.tv_sec) == 0)
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index da4f1db..ddf3d77 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -189,7 +189,6 @@ userret(p, frame, oticks)
* mi_switch()'ed, we might not be on the queue indicated by
* our priority.
*/
- clear_resched();
DROP_GIANT_NOSWITCH();
setrunqueue(p);
p->p_stats->p_ru.ru_nivcsw++;
OpenPOWER on IntegriCloud