summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-06-20 09:12:12 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-06-20 09:12:12 +0000
commitfc5cfc90b555ef39d68c80f55ee809b4382bdcd1 (patch)
tree62c2902e56b4d57cd1b2672edbffcb6b0fea8805 /sys/kern
parente5ce0c046f73b21456cfe796fb2431293b063e75 (diff)
downloadFreeBSD-src-fc5cfc90b555ef39d68c80f55ee809b4382bdcd1.zip
FreeBSD-src-fc5cfc90b555ef39d68c80f55ee809b4382bdcd1.tar.gz
cpu_set_upcall_kse needs to access userspace, release schedule lock
before calling it for bound thread. To avoid this problem, change thread_schedule_upcall to not put new thread on run queue, let caller do it, so we can tweak the new thread before setting it to run. Reported by: pho
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_kse.c14
-rw-r--r--sys/kern/kern_thread.c14
2 files changed, 20 insertions, 8 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index c71b74d..7695643 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -735,13 +735,18 @@ kse_create(struct thread *td, struct kse_create_args *uap)
}
}
if (!sa) {
- if (newtd != td)
- cpu_set_upcall_kse(newtd, newku);
newtd->td_mailbox = mbx.km_curthread;
newtd->td_flags &= ~TDF_SA;
+ if (newtd != td) {
+ mtx_unlock_spin(&sched_lock);
+ cpu_set_upcall_kse(newtd, newku);
+ mtx_lock_spin(&sched_lock);
+ }
} else {
newtd->td_flags |= TDF_SA;
}
+ if (newtd != td)
+ setrunqueue(newtd);
mtx_unlock_spin(&sched_lock);
return (0);
}
@@ -1394,7 +1399,6 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku)
td2->td_kse = NULL;
td2->td_state = TDS_CAN_RUN;
td2->td_inhibitors = 0;
- setrunqueue(td2);
return (td2); /* bogus.. should be a void function */
}
@@ -1447,6 +1451,7 @@ void
thread_switchout(struct thread *td)
{
struct kse_upcall *ku;
+ struct thread *td2;
mtx_assert(&sched_lock, MA_OWNED);
@@ -1471,7 +1476,8 @@ thread_switchout(struct thread *td)
ku->ku_owner = NULL;
td->td_upcall = NULL;
td->td_flags &= ~TDF_CAN_UNBIND;
- thread_schedule_upcall(td, ku);
+ td2 = thread_schedule_upcall(td, ku);
+ setrunqueue(td2);
}
}
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index c71b74d..7695643 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -735,13 +735,18 @@ kse_create(struct thread *td, struct kse_create_args *uap)
}
}
if (!sa) {
- if (newtd != td)
- cpu_set_upcall_kse(newtd, newku);
newtd->td_mailbox = mbx.km_curthread;
newtd->td_flags &= ~TDF_SA;
+ if (newtd != td) {
+ mtx_unlock_spin(&sched_lock);
+ cpu_set_upcall_kse(newtd, newku);
+ mtx_lock_spin(&sched_lock);
+ }
} else {
newtd->td_flags |= TDF_SA;
}
+ if (newtd != td)
+ setrunqueue(newtd);
mtx_unlock_spin(&sched_lock);
return (0);
}
@@ -1394,7 +1399,6 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku)
td2->td_kse = NULL;
td2->td_state = TDS_CAN_RUN;
td2->td_inhibitors = 0;
- setrunqueue(td2);
return (td2); /* bogus.. should be a void function */
}
@@ -1447,6 +1451,7 @@ void
thread_switchout(struct thread *td)
{
struct kse_upcall *ku;
+ struct thread *td2;
mtx_assert(&sched_lock, MA_OWNED);
@@ -1471,7 +1476,8 @@ thread_switchout(struct thread *td)
ku->ku_owner = NULL;
td->td_upcall = NULL;
td->td_flags &= ~TDF_CAN_UNBIND;
- thread_schedule_upcall(td, ku);
+ td2 = thread_schedule_upcall(td, ku);
+ setrunqueue(td2);
}
}
OpenPOWER on IntegriCloud