Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177409909
D6069.1794309421.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
19 KB
Referenced Files
None
Subscribers
None
D6069.1794309421.diff
View Options
Index: sys/cddl/dev/dtrace/amd64/dtrace_subr.c
===================================================================
--- sys/cddl/dev/dtrace/amd64/dtrace_subr.c
+++ sys/cddl/dev/dtrace/amd64/dtrace_subr.c
@@ -246,6 +246,26 @@
/* See below for the explanation of this macro. */
#define SCALE_SHIFT 28
+static void
+dtrace_gethrtime_init_cpu(void *arg)
+{
+ uintptr_t cpu = (uintptr_t) arg;
+
+ if (cpu == curcpu)
+ tgt_cpu_tsc = rdtsc();
+ else
+ hst_cpu_tsc = rdtsc();
+}
+
+#ifdef EARLY_AP_STARTUP
+static void
+dtrace_gethrtime_init(void *arg)
+{
+ struct pcpu *pc;
+ uint64_t tsc_f;
+ cpuset_t map;
+ int i;
+#else
/*
* Get the frequency and scale factor as early as possible so that they can be
* used for boot-time tracing.
@@ -254,6 +274,7 @@
dtrace_gethrtime_init_early(void *arg)
{
uint64_t tsc_f;
+#endif
/*
* Get TSC frequency known at this moment.
@@ -282,27 +303,18 @@
* (terahertz) values;
*/
nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
+#ifndef EARLY_AP_STARTUP
}
SYSINIT(dtrace_gethrtime_init_early, SI_SUB_CPU, SI_ORDER_ANY,
dtrace_gethrtime_init_early, NULL);
static void
-dtrace_gethrtime_init_cpu(void *arg)
-{
- uintptr_t cpu = (uintptr_t) arg;
-
- if (cpu == curcpu)
- tgt_cpu_tsc = rdtsc();
- else
- hst_cpu_tsc = rdtsc();
-}
-
-static void
dtrace_gethrtime_init(void *arg)
{
struct pcpu *pc;
cpuset_t map;
int i;
+#endif
/* The current CPU is the reference one. */
sched_pin();
@@ -323,8 +335,13 @@
}
sched_unpin();
}
+#ifdef EARLY_AP_STARTUP
+SYSINIT(dtrace_gethrtime_init, SI_SUB_DTRACE, SI_ORDER_ANY,
+ dtrace_gethrtime_init, NULL);
+#else
SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
NULL);
+#endif
/*
* DTrace needs a high resolution time function which can
Index: sys/cddl/dev/dtrace/dtrace_load.c
===================================================================
--- sys/cddl/dev/dtrace/dtrace_load.c
+++ sys/cddl/dev/dtrace/dtrace_load.c
@@ -22,6 +22,7 @@
*
*/
+#ifndef EARLY_AP_STARTUP
static void
dtrace_ap_start(void *dummy)
{
@@ -41,11 +42,15 @@
}
SYSINIT(dtrace_ap_start, SI_SUB_SMP, SI_ORDER_ANY, dtrace_ap_start, NULL);
+#endif
static void
dtrace_load(void *dummy)
{
dtrace_provider_id_t id;
+#ifdef EARLY_AP_STARTUP
+ int i;
+#endif
/* Hook into the trap handler. */
dtrace_trap_func = dtrace_trap;
@@ -142,8 +147,14 @@
mutex_enter(&cpu_lock);
+#ifdef EARLY_AP_STARTUP
+ CPU_FOREACH(i) {
+ (void) dtrace_cpu_setup(CPU_CONFIG, i);
+ }
+#else
/* Setup the boot CPU */
(void) dtrace_cpu_setup(CPU_CONFIG, 0);
+#endif
mutex_exit(&cpu_lock);
Index: sys/cddl/dev/dtrace/i386/dtrace_subr.c
===================================================================
--- sys/cddl/dev/dtrace/i386/dtrace_subr.c
+++ sys/cddl/dev/dtrace/i386/dtrace_subr.c
@@ -248,6 +248,26 @@
/* See below for the explanation of this macro. */
#define SCALE_SHIFT 28
+static void
+dtrace_gethrtime_init_cpu(void *arg)
+{
+ uintptr_t cpu = (uintptr_t) arg;
+
+ if (cpu == curcpu)
+ tgt_cpu_tsc = rdtsc();
+ else
+ hst_cpu_tsc = rdtsc();
+}
+
+#ifdef EARLY_AP_STARTUP
+static void
+dtrace_gethrtime_init(void *arg)
+{
+ struct pcpu *pc;
+ uint64_t tsc_f;
+ cpuset_t map;
+ int i;
+#else
/*
* Get the frequency and scale factor as early as possible so that they can be
* used for boot-time tracing.
@@ -256,6 +276,7 @@
dtrace_gethrtime_init_early(void *arg)
{
uint64_t tsc_f;
+#endif
/*
* Get TSC frequency known at this moment.
@@ -284,27 +305,18 @@
* (terahertz) values;
*/
nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
+#ifndef EARLY_AP_STARTUP
}
SYSINIT(dtrace_gethrtime_init_early, SI_SUB_CPU, SI_ORDER_ANY,
dtrace_gethrtime_init_early, NULL);
static void
-dtrace_gethrtime_init_cpu(void *arg)
-{
- uintptr_t cpu = (uintptr_t) arg;
-
- if (cpu == curcpu)
- tgt_cpu_tsc = rdtsc();
- else
- hst_cpu_tsc = rdtsc();
-}
-
-static void
dtrace_gethrtime_init(void *arg)
{
cpuset_t map;
struct pcpu *pc;
int i;
+#endif
/* The current CPU is the reference one. */
sched_pin();
@@ -325,8 +337,13 @@
}
sched_unpin();
}
+#ifdef EARLY_AP_STARTUP
+SYSINIT(dtrace_gethrtime_init, SI_SUB_DTRACE, SI_ORDER_ANY,
+ dtrace_gethrtime_init, NULL);
+#else
SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
NULL);
+#endif
/*
* DTrace needs a high resolution time function which can
Index: sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
===================================================================
--- sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
+++ sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
@@ -218,8 +218,13 @@
}
sched_unpin();
}
-
-SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init, NULL);
+#ifdef EARLY_AP_STARTUP
+SYSINIT(dtrace_gethrtime_init, SI_SUB_DTRACE, SI_ORDER_ANY,
+ dtrace_gethrtime_init, NULL);
+#else
+SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
+ NULL);
+#endif
/*
* DTrace needs a high resolution time function which can
Index: sys/conf/NOTES
===================================================================
--- sys/conf/NOTES
+++ sys/conf/NOTES
@@ -223,6 +223,12 @@
# Mandatory:
options SMP # Symmetric MultiProcessor Kernel
+# EARLY_AP_STARTUP releases the Application Processors earlier in the
+# kernel startup process (before devices are probed) rather than at the
+# end. This is a temporary option for use during the transition from
+# late to early AP startup.
+options EARLY_AP_STARTUP
+
# MAXCPU defines the maximum number of CPUs that can boot in the system.
# A default value should be already present, for every architecture.
options MAXCPU=32
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -619,6 +619,7 @@
DEBUG_REDZONE opt_vm.h
# Standard SMP options
+EARLY_AP_STARTUP opt_global.h
SMP opt_global.h
# Size of the kernel message buffer
Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c
+++ sys/dev/acpica/acpi.c
@@ -2810,11 +2810,18 @@
stop_all_proc();
EVENTHANDLER_INVOKE(power_suspend);
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+ thread_lock(curthread);
+ sched_bind(curthread, 0);
+ thread_unlock(curthread);
+#else
if (smp_started) {
thread_lock(curthread);
sched_bind(curthread, 0);
thread_unlock(curthread);
}
+#endif
/*
* Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
@@ -2945,11 +2952,17 @@
mtx_unlock(&Giant);
+#ifdef EARLY_AP_STARTUP
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+#else
if (smp_started) {
thread_lock(curthread);
sched_unbind(curthread);
thread_unlock(curthread);
}
+#endif
resume_all_proc();
Index: sys/dev/acpica/acpi_cpu.c
===================================================================
--- sys/dev/acpica/acpi_cpu.c
+++ sys/dev/acpica/acpi_cpu.c
@@ -438,8 +438,12 @@
free(devices, M_TEMP);
if (attached) {
+#ifdef EARLY_AP_STARTUP
+ acpi_cpu_startup(NULL);
+#else
/* Queue post cpu-probing task handler */
AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_cpu_startup, NULL);
+#endif
}
}
Index: sys/dev/hwpmc/hwpmc_mod.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mod.c
+++ sys/dev/hwpmc/hwpmc_mod.c
@@ -334,7 +334,11 @@
&pmc_syscall_mod
};
+#ifdef EARLY_AP_STARTUP
+DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SYSCALLS, SI_ORDER_ANY);
+#else
DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SMP, SI_ORDER_ANY);
+#endif
MODULE_VERSION(pmc, PMC_VERSION);
#ifdef HWPMC_DEBUG
Index: sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -516,6 +516,7 @@
device_printf(dev, "VMBUS: attach dev: %p\n", dev);
vmbus_devp = dev;
+#ifndef EARLY_AP_STARTUP
/*
* If the system has already booted and thread
* scheduling is possible indicated by the global
@@ -523,6 +524,7 @@
* initialization directly.
*/
if (!cold)
+#endif
vmbus_bus_init();
return (0);
@@ -534,6 +536,7 @@
if (vm_guest != VM_GUEST_HV)
return;
+#ifndef EARLY_AP_STARTUP
/*
* If the system has already booted and thread
* scheduling is possible, as indicated by the
@@ -541,6 +544,7 @@
* initialization directly.
*/
if (!cold)
+#endif
vmbus_bus_init();
}
@@ -607,6 +611,9 @@
switch (what) {
case MOD_LOAD:
+#ifdef EARLY_AP_STARTUP
+ vmbus_init();
+#endif
vmbus_mod_load();
break;
case MOD_UNLOAD:
@@ -645,6 +652,7 @@
MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
MODULE_VERSION(vmbus, 1);
+#ifndef EARLY_AP_STARTUP
/* We want to be started after SMP is initialized */
SYSINIT(vmb_init, SI_SUB_SMP + 1, SI_ORDER_FIRST, vmbus_init, NULL);
-
+#endif
Index: sys/dev/xen/control/control.c
===================================================================
--- sys/dev/xen/control/control.c
+++ sys/dev/xen/control/control.c
@@ -199,11 +199,18 @@
EVENTHANDLER_INVOKE(power_suspend);
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+ thread_lock(curthread);
+ sched_bind(curthread, 0);
+ thread_unlock(curthread);
+#else
if (smp_started) {
thread_lock(curthread);
sched_bind(curthread, 0);
thread_unlock(curthread);
}
+#endif
KASSERT((PCPU_GET(cpuid) == 0), ("Not running on CPU#0"));
/*
@@ -225,6 +232,17 @@
mtx_unlock(&Giant);
#ifdef SMP
+#ifdef EARLY_AP_STARTUP
+ /*
+ * Suspend other CPUs. This prevents IPIs while we
+ * are resuming, and will allow us to reset per-cpu
+ * vcpu_info on resume.
+ */
+ cpu_suspend_map = all_cpus;
+ CPU_CLR(PCPU_GET(cpuid), &cpu_suspend_map);
+ if (!CPU_EMPTY(&cpu_suspend_map))
+ suspend_cpus(cpu_suspend_map);
+#else
CPU_ZERO(&cpu_suspend_map); /* silence gcc */
if (smp_started) {
/*
@@ -238,6 +256,7 @@
suspend_cpus(cpu_suspend_map);
}
#endif
+#endif
/*
* Prevent any races with evtchn_interrupt() handler.
@@ -277,11 +296,17 @@
DEVICE_RESUME(root_bus);
mtx_unlock(&Giant);
+#ifdef EARLY_AP_STARTUP
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+#else
if (smp_started) {
thread_lock(curthread);
sched_unbind(curthread);
thread_unlock(curthread);
}
+#endif
EVENTHANDLER_INVOKE(power_resume);
Index: sys/geom/eli/g_eli.c
===================================================================
--- sys/geom/eli/g_eli.c
+++ sys/geom/eli/g_eli.c
@@ -479,7 +479,9 @@
wr = arg;
sc = wr->w_softc;
-#ifdef SMP
+#ifdef EARLY_AP_STARTUP
+ MPASS(!sc->sc_cpubind || smp_started);
+#elif defined(SMP)
/* Before sched_bind() to a CPU, wait for all CPUs to go on-line. */
if (sc->sc_cpubind) {
while (!smp_started)
Index: sys/kern/kern_clock.c
===================================================================
--- sys/kern/kern_clock.c
+++ sys/kern/kern_clock.c
@@ -391,6 +391,10 @@
initclocks(dummy)
void *dummy;
{
+#ifdef EARLY_AP_STARTUP
+ struct proc *p;
+ struct thread *td;
+#endif
register int i;
/*
@@ -415,6 +419,35 @@
* sign problems sooner.
*/
ticks = INT_MAX - (hz * 10 * 60);
+
+#ifdef EARLY_AP_STARTUP
+ /*
+ * Fixup the tick counts in any blocked or sleeping threads to
+ * account for the jump above.
+ */
+ sx_slock(&allproc_lock);
+ FOREACH_PROC_IN_SYSTEM(p) {
+ PROC_LOCK(p);
+ if (p->p_state == PRS_NEW) {
+ PROC_UNLOCK(p);
+ continue;
+ }
+ FOREACH_THREAD_IN_PROC(p, td) {
+ thread_lock(td);
+ if (TD_ON_LOCK(td)) {
+ MPASS(td->td_blktick == 0);
+ td->td_blktick = ticks;
+ }
+ if (TD_ON_SLEEPQ(td)) {
+ MPASS(td->td_slptick == 0);
+ td->td_slptick = ticks;
+ }
+ thread_unlock(td);
+ }
+ PROC_UNLOCK(p);
+ }
+ sx_sunlock(&allproc_lock);
+#endif
}
/*
Index: sys/kern/kern_clocksource.c
===================================================================
--- sys/kern/kern_clocksource.c
+++ sys/kern/kern_clocksource.c
@@ -322,9 +322,16 @@
curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff));
#ifdef SMP
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+#endif
/* Prepare broadcasting to other CPUs for non-per-CPU timers. */
bcast = 0;
+#ifdef EARLY_AP_STARTUP
+ if ((et->et_flags & ET_FLAGS_PERCPU) == 0) {
+#else
if ((et->et_flags & ET_FLAGS_PERCPU) == 0 && smp_started) {
+#endif
CPU_FOREACH(cpu) {
state = DPCPU_ID_PTR(cpu, timerstate);
ET_HW_LOCK(state);
@@ -485,12 +492,17 @@
nexttick = next;
else
nexttick = -1;
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+#endif
CPU_FOREACH(cpu) {
state = DPCPU_ID_PTR(cpu, timerstate);
state->now = now;
+#ifndef EARLY_AP_STARTUP
if (!smp_started && cpu != CPU_FIRST())
state->nextevent = SBT_MAX;
else
+#endif
state->nextevent = next;
if (periodic)
state->nexttick = next;
@@ -513,8 +525,13 @@
}
ET_HW_UNLOCK(DPCPU_PTR(timerstate));
#ifdef SMP
+#ifdef EARLY_AP_STARTUP
+ /* If timer is global we are done. */
+ if ((timer->et_flags & ET_FLAGS_PERCPU) == 0) {
+#else
/* If timer is global or there is no other CPUs yet - we are done. */
if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 || !smp_started) {
+#endif
critical_exit();
return;
}
Index: sys/kern/kern_cpu.c
===================================================================
--- sys/kern/kern_cpu.c
+++ sys/kern/kern_cpu.c
@@ -259,6 +259,9 @@
CF_MTX_LOCK(&sc->lock);
#ifdef SMP
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+#else
/*
* If still booting and secondary CPUs not started yet, don't allow
* changing the frequency until they're online. This is because we
@@ -271,6 +274,7 @@
error = ENXIO;
goto out;
}
+#endif
#endif /* SMP */
/*
Index: sys/net/netisr.c
===================================================================
--- sys/net/netisr.c
+++ sys/net/netisr.c
@@ -1119,6 +1119,10 @@
static void
netisr_init(void *arg)
{
+#ifdef EARLY_AP_STARTUP
+ struct pcpu *pc;
+#endif
+
KASSERT(curcpu == 0, ("%s: not on CPU 0", __func__));
NETISR_LOCK_INIT();
@@ -1149,10 +1153,20 @@
netisr_bindthreads = 0;
}
#endif
+
+#ifdef EARLY_AP_STARTUP
+ STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
+ if (nws_count >= netisr_maxthreads)
+ break;
+ netisr_start_swi(pc->pc_cpuid, pc);
+ }
+#else
netisr_start_swi(curcpu, pcpu_find(curcpu));
+#endif
}
SYSINIT(netisr_init, SI_SUB_SOFTINTR, SI_ORDER_FIRST, netisr_init, NULL);
+#ifndef EARLY_AP_STARTUP
/*
* Start worker threads for additional CPUs. No attempt to gracefully handle
* work reassignment, we don't yet support dynamic reconfiguration.
@@ -1172,6 +1186,7 @@
}
}
SYSINIT(netisr_start, SI_SUB_SMP, SI_ORDER_MIDDLE, netisr_start, NULL);
+#endif
/*
* Sysctl monitoring for netisr: query a list of registered protocols.
Index: sys/sys/kernel.h
===================================================================
--- sys/sys/kernel.h
+++ sys/sys/kernel.h
@@ -118,7 +118,10 @@
SI_SUB_SCHED_IDLE = 0x2600000, /* required idle procs */
SI_SUB_MBUF = 0x2700000, /* mbuf subsystem */
SI_SUB_INTR = 0x2800000, /* interrupt threads */
- SI_SUB_SOFTINTR = 0x2800001, /* start soft interrupt thread */
+#ifdef EARLY_AP_STARTUP
+ SI_SUB_SMP = 0x2900000, /* start the APs*/
+#endif
+ SI_SUB_SOFTINTR = 0x2A00000, /* start soft interrupt thread */
SI_SUB_DEVFS = 0x2F00000, /* devfs ready for devices */
SI_SUB_INIT_IF = 0x3000000, /* prep for net interfaces */
SI_SUB_NETGRAPH = 0x3010000, /* Let Netgraph initialize */
@@ -154,7 +157,9 @@
SI_SUB_KTHREAD_BUF = 0xea00000, /* buffer daemon*/
SI_SUB_KTHREAD_UPDATE = 0xec00000, /* update daemon*/
SI_SUB_KTHREAD_IDLE = 0xee00000, /* idle procs*/
+#ifndef EARLY_AP_STARTUP
SI_SUB_SMP = 0xf000000, /* start the APs*/
+#endif
SI_SUB_RACCTD = 0xf100000, /* start racctd*/
SI_SUB_LAST = 0xfffffff /* final initialization */
};
Index: sys/x86/isa/clock.c
===================================================================
--- sys/x86/isa/clock.c
+++ sys/x86/isa/clock.c
@@ -475,8 +475,27 @@
void
cpu_initclocks(void)
{
+#ifdef EARLY_AP_STARTUP
+ struct thread *td;
+ int i;
+ td = curthread;
cpu_initclocks_bsp();
+ CPU_FOREACH(i) {
+ if (i == 0)
+ continue;
+ thread_lock(td);
+ sched_bind(td, i);
+ thread_unlock(td);
+ cpu_initclocks_ap();
+ }
+ thread_lock(td);
+ if (sched_is_bound(td))
+ sched_unbind(td);
+ thread_unlock(td);
+#else
+ cpu_initclocks_bsp();
+#endif
}
static int
Index: sys/x86/x86/intr_machdep.c
===================================================================
--- sys/x86/x86/intr_machdep.c
+++ sys/x86/x86/intr_machdep.c
@@ -77,7 +77,7 @@
static struct mtx intrcnt_lock;
static TAILQ_HEAD(pics_head, pic) pics;
-#ifdef SMP
+#if defined(SMP) && !defined(EARLY_AP_STARTUP)
static int assign_cpu;
#endif
@@ -320,11 +320,16 @@
struct intsrc *isrc;
int error;
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+ if (cpu != NOCPU) {
+#else
/*
* Don't do anything during early boot. We will pick up the
* assignment once the APs are started.
*/
if (assign_cpu && cpu != NOCPU) {
+#endif
isrc = arg;
mtx_lock(&intr_table_lock);
error = isrc->is_pic->pic_assign_cpu(isrc, cpu_apic_ids[cpu]);
@@ -502,9 +507,13 @@
{
u_int apic_id;
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+#else
/* Leave all interrupts on the BSP during boot. */
if (!assign_cpu)
return (PCPU_GET(apic_id));
+#endif
mtx_lock_spin(&icu_lock);
apic_id = cpu_apic_ids[current_cpu];
@@ -546,6 +555,7 @@
CPU_SET(cpu, &intr_cpus);
}
+#ifndef EARLY_AP_STARTUP
/*
* Distribute all the interrupt sources among the available CPUs once the
* AP's have been launched.
@@ -586,6 +596,7 @@
}
SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs,
NULL);
+#endif
#else
/*
* Always route interrupts to the current processor in the UP case.
Index: sys/x86/x86/local_apic.c
===================================================================
--- sys/x86/x86/local_apic.c
+++ sys/x86/x86/local_apic.c
@@ -749,6 +749,10 @@
lvts[APIC_LVT_PMC].lvt_masked = 0;
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+ smp_rendezvous(NULL, lapic_update_pmc, NULL, NULL);
+#else
#ifdef SMP
/*
* If hwpmc was loaded at boot time then the APs may not be
@@ -760,6 +764,7 @@
else
#endif
lapic_update_pmc(NULL);
+#endif
return (1);
#else
return (0);
Index: sys/x86/x86/mca.c
===================================================================
--- sys/x86/x86/mca.c
+++ sys/x86/x86/mca.c
@@ -725,7 +725,11 @@
callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, NULL);
}
+#ifdef EARLY_AP_STARTUP
+SYSINIT(mca_startup, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, mca_startup, NULL);
+#else
SYSINIT(mca_startup, SI_SUB_SMP, SI_ORDER_ANY, mca_startup, NULL);
+#endif
#ifdef DEV_APIC
static void
Index: sys/x86/x86/mp_x86.c
===================================================================
--- sys/x86/x86/mp_x86.c
+++ sys/x86/x86/mp_x86.c
@@ -933,8 +933,10 @@
while (atomic_load_acq_int(&smp_started) == 0)
ia32_pause();
+#ifndef EARLY_AP_STARTUP
/* Start per-CPU event timers. */
cpu_initclocks_ap();
+#endif
sched_throw(NULL);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 10, 11:17 AM (4 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41637667
Default Alt Text
D6069.1794309421.diff (19 KB)
Attached To
Mode
D6069: Add an EARLY_AP_STARTUP option to start APs earlier during boot.
Attached
Detach File
Event Timeline