diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_fork.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 8 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 1 |
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++; |