]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/mp.c
xnu-7195.60.75.tar.gz
[apple/xnu.git] / osfmk / i386 / mp.c
index 428f6151cca5b225fa34c1648a8aacc70247ade5..ee54613667617861808ad0294464f298bf763127 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -32,7 +32,6 @@
 #include <mach_kdp.h>
 #include <kdp/kdp_internal.h>
 #include <mach_ldebug.h>
-#include <gprof.h>
 
 #include <mach/mach_types.h>
 #include <mach/kern_return.h>
 #include <kern/pms.h>
 #include <kern/misc_protos.h>
 #include <kern/timer_call.h>
-#include <kern/kalloc.h>
+#include <kern/zalloc.h>
 #include <kern/queue.h>
 #include <prng/random.h>
 
 #include <vm/vm_map.h>
 #include <vm/vm_kern.h>
 
-#include <profiling/profile-mk.h>
-
 #include <i386/bit_routines.h>
 #include <i386/proc_reg.h>
 #include <i386/cpu_threads.h>
@@ -127,14 +124,14 @@ boolean_t               mp_interrupt_watchdog_enabled = TRUE;
 uint32_t                mp_interrupt_watchdog_events = 0;
 #endif
 
-decl_simple_lock_data(, debugger_callback_lock);
+SIMPLE_LOCK_DECLARE(debugger_callback_lock, 0);
 struct debugger_callback *debugger_callback = NULL;
 
-decl_lck_mtx_data(static, mp_cpu_boot_lock);
-lck_mtx_ext_t   mp_cpu_boot_lock_ext;
+static LCK_GRP_DECLARE(smp_lck_grp, "i386_smp");
+static LCK_MTX_EARLY_DECLARE(mp_cpu_boot_lock, &smp_lck_grp);
 
 /* Variables needed for MP rendezvous. */
-decl_simple_lock_data(, mp_rv_lock);
+SIMPLE_LOCK_DECLARE(mp_rv_lock, 0);
 static void     (*mp_rv_setup_func)(void *arg);
 static void     (*mp_rv_action_func)(void *arg);
 static void     (*mp_rv_teardown_func)(void *arg);
@@ -166,8 +163,7 @@ static void        (*mp_bc_action_func)(void *arg);
 static void        *mp_bc_func_arg;
 static int      mp_bc_ncpus;
 static volatile long   mp_bc_count;
-decl_lck_mtx_data(static, mp_bc_lock);
-lck_mtx_ext_t   mp_bc_lock_ext;
+static LCK_MTX_EARLY_DECLARE(mp_bc_lock, &smp_lck_grp);
 static  volatile int    debugger_cpu = -1;
 volatile long    NMIPI_acks = 0;
 volatile long    NMI_count = 0;
@@ -188,27 +184,6 @@ boolean_t i386_smp_init(int nmi_vector, i386_intr_func_t nmi_handler,
 void i386_start_cpu(int lapic_id, int cpu_num);
 void i386_send_NMI(int cpu);
 void NMIPI_enable(boolean_t);
-#if GPROF
-/*
- * Initialize dummy structs for profiling. These aren't used but
- * allows hertz_tick() to be built with GPROF defined.
- */
-struct profile_vars _profile_vars;
-struct profile_vars *_profile_vars_cpus[MAX_CPUS] = { &_profile_vars };
-#define GPROF_INIT()                                                    \
-{                                                                       \
-       int     i;                                                      \
-                                                                        \
-       /* Hack to initialize pointers to unused profiling structs */   \
-       for (i = 1; i < MAX_CPUS; i++)                          \
-               _profile_vars_cpus[i] = &_profile_vars;                 \
-}
-#else
-#define GPROF_INIT()
-#endif /* GPROF */
-
-static lck_grp_t        smp_lck_grp;
-static lck_grp_attr_t   smp_lck_grp_attr;
 
 #define NUM_CPU_WARM_CALLS      20
 struct timer_call       cpu_warm_call_arr[NUM_CPU_WARM_CALLS];
@@ -222,7 +197,7 @@ typedef struct cpu_warm_data {
 } *cpu_warm_data_t;
 
 static void             cpu_prewarm_init(void);
-static void             cpu_warm_timer_call_func(call_entry_param_t p0, call_entry_param_t p1);
+static void             cpu_warm_timer_call_func(timer_call_param_t p0, timer_call_param_t p1);
 static void             _cpu_warm_setup(void *arg);
 static timer_call_t     grab_warm_timer_call(void);
 static void             free_warm_timer_call(timer_call_t call);
@@ -230,12 +205,6 @@ static void             free_warm_timer_call(timer_call_t call);
 void
 smp_init(void)
 {
-       simple_lock_init(&mp_rv_lock, 0);
-       simple_lock_init(&debugger_callback_lock, 0);
-       lck_grp_attr_setdefault(&smp_lck_grp_attr);
-       lck_grp_init(&smp_lck_grp, "i386_smp", &smp_lck_grp_attr);
-       lck_mtx_init_ext(&mp_cpu_boot_lock, &mp_cpu_boot_lock_ext, &smp_lck_grp, LCK_ATTR_NULL);
-       lck_mtx_init_ext(&mp_bc_lock, &mp_bc_lock_ext, &smp_lck_grp, LCK_ATTR_NULL);
        console_init();
 
        if (!i386_smp_init(LAPIC_NMI_INTERRUPT, NMIInterruptHandler,
@@ -245,7 +214,6 @@ smp_init(void)
 
        cpu_thread_init();
 
-       GPROF_INIT();
        DBGLOG_CPU_INIT(master_cpu);
 
        mp_cpus_call_init();
@@ -432,11 +400,18 @@ start_cpu(void *arg)
                tsc_delta = tsc_target - tsc_starter;
                kprintf("TSC sync for cpu %d: 0x%016llx delta 0x%llx (%lld)\n",
                    psip->target_cpu, tsc_target, tsc_delta, tsc_delta);
+#if DEBUG || DEVELOPMENT
+               /*
+                * Stash the delta for inspection later, since we can no
+                * longer print/log it with interrupts disabled.
+                */
+               cpu_datap(psip->target_cpu)->tsc_sync_delta = tsc_delta;
+#endif
                if (ABS(tsc_delta) > (int64_t) TSC_sync_margin) {
 #if DEBUG
                        panic(
 #else
-                       printf(
+                       kprintf(
 #endif
                                "Unsynchronized  TSC for cpu %d: "
                                "0x%016llx, delta 0x%llx\n",
@@ -525,7 +500,7 @@ cpu_signal_handler(x86_saved_state_t *regs)
        int             my_cpu;
        volatile int    *my_word;
 
-       SCHED_STATS_IPI(current_processor());
+       SCHED_STATS_INC(ipi_count);
 
        my_cpu = cpu_number();
        my_word = &cpu_data_ptr[my_cpu]->cpu_signals;
@@ -1197,7 +1172,7 @@ mp_cpus_call_cpu_init(int cpu)
        simple_lock_init(&cqp->lock, 0);
        queue_init(&cqp->queue);
        for (i = 0; i < MP_CPUS_CALL_BUFS_PER_CPU; i++) {
-               callp = (mp_call_t *) kalloc(sizeof(mp_call_t));
+               callp = zalloc_permanent_type(mp_call_t);
                mp_call_free(callp);
        }
 
@@ -1500,12 +1475,9 @@ mp_broadcast(
         * signal other processors, which will call mp_broadcast_action()
         */
        mp_bc_count = real_ncpus;                       /* assume max possible active */
-       mp_bc_ncpus = mp_cpus_call(CPUMASK_OTHERS, NOSYNC, *mp_broadcast_action, NULL) + 1;
+       mp_bc_ncpus = mp_cpus_call(CPUMASK_ALL, NOSYNC, *mp_broadcast_action, NULL);
        atomic_decl(&mp_bc_count, real_ncpus - mp_bc_ncpus); /* subtract inactive */
 
-       /* call executor function on this cpu */
-       mp_broadcast_action(NULL);
-
        /* block for other cpus to have run action_func */
        if (mp_bc_ncpus > 1) {
                thread_block(THREAD_CONTINUE_NULL);
@@ -1527,8 +1499,7 @@ mp_cpus_kick(cpumask_t cpus)
        mp_safe_spin_lock(&x86_topo_lock);
 
        for (cpu = 0; cpu < (cpu_t) real_ncpus; cpu++) {
-               if ((cpu == (cpu_t) cpu_number())
-                   || ((cpu_to_cpumask(cpu) & cpus) == 0)
+               if (((cpu_to_cpumask(cpu) & cpus) == 0)
                    || !cpu_is_running(cpu)) {
                        continue;
                }
@@ -1970,6 +1941,12 @@ cpu_number(void)
        return get_cpu_number();
 }
 
+vm_offset_t
+current_percpu_base(void)
+{
+       return get_current_percpu_base();
+}
+
 static void
 cpu_prewarm_init()
 {
@@ -2016,8 +1993,8 @@ free_warm_timer_call(timer_call_t call)
  */
 static void
 cpu_warm_timer_call_func(
-       call_entry_param_t p0,
-       __unused call_entry_param_t p1)
+       timer_call_param_t p0,
+       __unused timer_call_param_t p1)
 {
        free_warm_timer_call((timer_call_t)p0);
        return;