Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164318699
D32829.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D32829.id.diff
View Options
diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c
--- a/sys/arm/arm/mp_machdep.c
+++ b/sys/arm/arm/mp_machdep.c
@@ -217,7 +217,7 @@
CTR0(KTR_SMP, "go into scheduler");
/* Enter the scheduler */
- sched_throw(NULL);
+ sched_ap_entry();
panic("scheduler returned us to %s", __func__);
/* NOTREACHED */
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -293,7 +293,7 @@
MPASS(PCPU_GET(curpcb) == NULL);
/* Enter the scheduler */
- sched_throw(NULL);
+ sched_ap_entry();
panic("scheduler returned us to init_secondary");
/* NOTREACHED */
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1662,12 +1662,22 @@
}
}
+static void
+sched_throw_tail(struct thread *td)
+{
+
+ mtx_assert(&sched_lock, MA_OWNED);
+ KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
+ cpu_throw(td, choosethread()); /* doesn't return */
+}
+
/*
- * A CPU is entering for the first time or a thread is exiting.
+ * A CPU is entering for the first time.
*/
void
-sched_throw(struct thread *td)
+sched_ap_entry(void)
{
+
/*
* Correct spinlock nesting. The idle thread context that we are
* borrowing was created so that it would start out with a single
@@ -1677,20 +1687,29 @@
* spinlock_exit() will simply adjust the counts without allowing
* spin lock using code to interrupt us.
*/
- if (td == NULL) {
- mtx_lock_spin(&sched_lock);
- spinlock_exit();
- PCPU_SET(switchtime, cpu_ticks());
- PCPU_SET(switchticks, ticks);
- } else {
- lock_profile_release_lock(&sched_lock.lock_object, true);
- MPASS(td->td_lock == &sched_lock);
- td->td_lastcpu = td->td_oncpu;
- td->td_oncpu = NOCPU;
- }
- mtx_assert(&sched_lock, MA_OWNED);
- KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
- cpu_throw(td, choosethread()); /* doesn't return */
+ mtx_lock_spin(&sched_lock);
+ spinlock_exit();
+ PCPU_SET(switchtime, cpu_ticks());
+ PCPU_SET(switchticks, ticks);
+
+ sched_throw_tail(NULL);
+}
+
+/*
+ * A thread is exiting.
+ */
+void
+sched_throw(struct thread *td)
+{
+
+ MPASS(td != NULL);
+ MPASS(td->td_lock == &sched_lock);
+
+ lock_profile_release_lock(&sched_lock.lock_object, true);
+ td->td_lastcpu = td->td_oncpu;
+ td->td_oncpu = NOCPU;
+
+ sched_throw_tail(td);
}
void
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -2985,39 +2985,74 @@
}
/*
- * A CPU is entering for the first time or a thread is exiting.
+ * sched_throw_grab() chooses a thread from the queue to switch to
+ * next. It returns with the tdq lock dropped in a spinlock section to
+ * keep interrupts disabled until the CPU is running in a proper threaded
+ * context.
*/
-void
-sched_throw(struct thread *td)
+static struct thread *
+sched_throw_grab(struct tdq *tdq)
{
struct thread *newtd;
- struct tdq *tdq;
- tdq = TDQ_SELF();
- if (__predict_false(td == NULL)) {
- TDQ_LOCK(tdq);
- /* Correct spinlock nesting. */
- spinlock_exit();
- PCPU_SET(switchtime, cpu_ticks());
- PCPU_SET(switchticks, ticks);
- } else {
- THREAD_LOCK_ASSERT(td, MA_OWNED);
- THREAD_LOCKPTR_ASSERT(td, TDQ_LOCKPTR(tdq));
- tdq_load_rem(tdq, td);
- td->td_lastcpu = td->td_oncpu;
- td->td_oncpu = NOCPU;
- thread_lock_block(td);
- }
newtd = choosethread();
spinlock_enter();
TDQ_UNLOCK(tdq);
KASSERT(curthread->td_md.md_spinlock_count == 1,
("invalid count %d", curthread->td_md.md_spinlock_count));
+ return (newtd);
+}
+
+/*
+ * A CPU is entering for the first time.
+ */
+void
+sched_ap_entry(void)
+{
+ struct thread *newtd;
+ struct tdq *tdq;
+
+ tdq = TDQ_SELF();
+
+ /* This should have been setup in schedinit_ap(). */
+ THREAD_LOCKPTR_ASSERT(curthread, TDQ_LOCKPTR(tdq));
+
+ TDQ_LOCK(tdq);
+ /* Correct spinlock nesting. */
+ spinlock_exit();
+ PCPU_SET(switchtime, cpu_ticks());
+ PCPU_SET(switchticks, ticks);
+
+ newtd = sched_throw_grab(tdq);
+
/* doesn't return */
- if (__predict_false(td == NULL))
- cpu_throw(td, newtd); /* doesn't return */
- else
- cpu_switch(td, newtd, TDQ_LOCKPTR(tdq));
+ cpu_throw(NULL, newtd);
+}
+
+/*
+ * A thread is exiting.
+ */
+void
+sched_throw(struct thread *td)
+{
+ struct thread *newtd;
+ struct tdq *tdq;
+
+ tdq = TDQ_SELF();
+
+ MPASS(td != NULL);
+ THREAD_LOCK_ASSERT(td, MA_OWNED);
+ THREAD_LOCKPTR_ASSERT(td, TDQ_LOCKPTR(tdq));
+
+ tdq_load_rem(tdq, td);
+ td->td_lastcpu = td->td_oncpu;
+ td->td_oncpu = NOCPU;
+ thread_lock_block(td);
+
+ newtd = sched_throw_grab(tdq);
+
+ /* doesn't return */
+ cpu_switch(td, newtd, TDQ_LOCKPTR(tdq));
}
/*
diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c
--- a/sys/mips/mips/mp_machdep.c
+++ b/sys/mips/mips/mp_machdep.c
@@ -335,7 +335,7 @@
cpu_initclocks_ap();
/* enter the scheduler */
- sched_throw(NULL);
+ sched_ap_entry();
panic("scheduler returned us to %s", __func__);
/* NOTREACHED */
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -112,7 +112,7 @@
cpu_initclocks_ap();
/* Announce ourselves awake, and enter the scheduler */
- sched_throw(NULL);
+ sched_ap_entry();
}
void
diff --git a/sys/riscv/riscv/mp_machdep.c b/sys/riscv/riscv/mp_machdep.c
--- a/sys/riscv/riscv/mp_machdep.c
+++ b/sys/riscv/riscv/mp_machdep.c
@@ -291,7 +291,7 @@
MPASS(PCPU_GET(curpcb) == NULL);
/* Enter the scheduler */
- sched_throw(NULL);
+ sched_ap_entry();
panic("scheduler returned us to init_secondary");
/* NOTREACHED */
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -91,6 +91,7 @@
* Threads are switched in and out, block on resources, have temporary
* priorities inherited from their procs, and use up cpu time.
*/
+void sched_ap_entry(void);
void sched_exit_thread(struct thread *td, struct thread *child);
u_int sched_estcpu(struct thread *td);
void sched_fork_thread(struct thread *td, struct thread *child);
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -1099,7 +1099,7 @@
*/
MPASS(PCPU_GET(curpcb) == NULL);
- sched_throw(NULL);
+ sched_ap_entry();
panic("scheduler returned us to %s", __func__);
/* NOTREACHED */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 31, 6:06 PM (1 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35792508
Default Alt Text
D32829.id.diff (6 KB)
Attached To
Mode
D32829: sched: spit sched_ap_entry() out of sched_throw()
Attached
Detach File
Event Timeline
Log In to Comment