X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/89b3af67bb32e691275bf6fa803d1834b2284115..c7d2c2c6ee645e10cbccdd01c6191873ec77239d:/osfmk/kern/machine.c diff --git a/osfmk/kern/machine.c b/osfmk/kern/machine.c index 40aa5c0b2..dfe33564d 100644 --- a/osfmk/kern/machine.c +++ b/osfmk/kern/machine.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2009 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -88,9 +87,17 @@ #include #include +#include + +#if HIBERNATION #include +#endif #include +#if CONFIG_DTRACE +extern void (*dtrace_cpu_state_changed_hook)(int, boolean_t); +#endif + /* * Exported variables: */ @@ -109,24 +116,30 @@ void processor_doshutdown( */ void processor_up( - processor_t processor) + processor_t processor) { - processor_set_t pset = &default_pset; + processor_set_t pset; spl_t s; s = splsched(); - processor_lock(processor); init_ast_check(processor); - simple_lock(&pset->sched_lock); - pset_add_processor(pset, processor); + pset = processor->processor_set; + pset_lock(pset); + ++pset->online_processor_count; enqueue_tail(&pset->active_queue, (queue_entry_t)processor); processor->state = PROCESSOR_RUNNING; - simple_unlock(&pset->sched_lock); - hw_atomic_add(&machine_info.avail_cpus, 1); + (void)hw_atomic_add(&processor_avail_count, 1); + commpage_update_active_cpus(); + pset_unlock(pset); ml_cpu_up(); - processor_unlock(processor); splx(s); + +#if CONFIG_DTRACE + if (dtrace_cpu_state_changed_hook) + (*dtrace_cpu_state_changed_hook)(processor->cpu_id, TRUE); +#endif } +#include kern_return_t host_reboot( @@ -138,10 +151,12 @@ host_reboot( assert(host_priv == &realhost); +#if DEVELOPMENT || DEBUG if (options & HOST_REBOOT_DEBUGGER) { Debugger("Debugger"); return (KERN_SUCCESS); } +#endif if (options & HOST_REBOOT_UPSDELAY) { // UPS power cutoff path @@ -170,12 +185,13 @@ processor_shutdown( spl_t s; s = splsched(); - processor_lock(processor); + pset = processor->processor_set; + pset_lock(pset); if (processor->state == PROCESSOR_OFF_LINE) { /* * Success if already shutdown. */ - processor_unlock(processor); + pset_unlock(pset); splx(s); return (KERN_SUCCESS); @@ -185,172 +201,128 @@ processor_shutdown( /* * Failure if currently being started. */ - processor_unlock(processor); + pset_unlock(pset); splx(s); return (KERN_FAILURE); } /* - * Must lock the scheduling lock - * to get at the processor state. + * If the processor is dispatching, let it finish. */ - pset = processor->processor_set; - if (pset != PROCESSOR_SET_NULL) { - simple_lock(&pset->sched_lock); - - /* - * If the processor is dispatching, let it finish. - */ - while (processor->state == PROCESSOR_DISPATCHING) { - simple_unlock(&pset->sched_lock); - delay(1); - simple_lock(&pset->sched_lock); - } - - /* - * Success if already being shutdown. - */ - if (processor->state == PROCESSOR_SHUTDOWN) { - simple_unlock(&pset->sched_lock); - processor_unlock(processor); - splx(s); - - return (KERN_SUCCESS); - } + while (processor->state == PROCESSOR_DISPATCHING) { + pset_unlock(pset); + splx(s); + delay(1); + s = splsched(); + pset_lock(pset); } - else { - /* - * Success, already being shutdown. - */ - processor_unlock(processor); + + /* + * Success if already being shutdown. + */ + if (processor->state == PROCESSOR_SHUTDOWN) { + pset_unlock(pset); splx(s); return (KERN_SUCCESS); } - if (processor->state == PROCESSOR_IDLE) { - remqueue(&pset->idle_queue, (queue_entry_t)processor); - pset->idle_count--; - } + if (processor->state == PROCESSOR_IDLE) + remqueue((queue_entry_t)processor); else if (processor->state == PROCESSOR_RUNNING) - remqueue(&pset->active_queue, (queue_entry_t)processor); - else - panic("processor_shutdown"); + remqueue((queue_entry_t)processor); processor->state = PROCESSOR_SHUTDOWN; - simple_unlock(&pset->sched_lock); - - processor_unlock(processor); + pset_unlock(pset); processor_doshutdown(processor); splx(s); - cpu_exit_wait(PROCESSOR_DATA(processor, slot_num)); + cpu_exit_wait(processor->cpu_id); return (KERN_SUCCESS); } /* - * Called at splsched. + * Called with interrupts disabled. */ void processor_doshutdown( processor_t processor) { thread_t old_thread, self = current_thread(); - processor_set_t pset; processor_t prev; - int pcount; + processor_set_t pset; /* * Get onto the processor to shutdown */ - prev = thread_bind(self, processor); + prev = thread_bind(processor); thread_block(THREAD_CONTINUE_NULL); - processor_lock(processor); - pset = processor->processor_set; - simple_lock(&pset->sched_lock); + assert(processor->state == PROCESSOR_SHUTDOWN); - if ((pcount = pset->processor_count) == 1) { - simple_unlock(&pset->sched_lock); - processor_unlock(processor); +#if CONFIG_DTRACE + if (dtrace_cpu_state_changed_hook) + (*dtrace_cpu_state_changed_hook)(processor->cpu_id, FALSE); +#endif - hibernate_vm_lock(); + ml_cpu_down(); - processor_lock(processor); - simple_lock(&pset->sched_lock); +#if HIBERNATION + if (processor_avail_count < 2) { + hibernate_vm_lock(); + hibernate_vm_unlock(); } +#endif - assert(processor->state == PROCESSOR_SHUTDOWN); - - pset_remove_processor(pset, processor); - simple_unlock(&pset->sched_lock); - processor_unlock(processor); - - if (pcount == 1) - hibernate_vm_unlock(); + pset = processor->processor_set; + pset_lock(pset); + processor->state = PROCESSOR_OFF_LINE; + --pset->online_processor_count; + (void)hw_atomic_sub(&processor_avail_count, 1); + commpage_update_active_cpus(); + SCHED(processor_queue_shutdown)(processor); + /* pset lock dropped */ /* * Continue processor shutdown in shutdown context. */ - thread_bind(self, prev); + thread_bind(prev); old_thread = machine_processor_shutdown(self, processor_offline, processor); - thread_begin(self, self->last_processor); - - thread_dispatch(old_thread); - - /* - * If we just shutdown another processor, move the - * timer call outs to the current processor. - */ - if (processor != current_processor()) { - processor_lock(processor); - if ( processor->state == PROCESSOR_OFF_LINE || - processor->state == PROCESSOR_SHUTDOWN ) - timer_call_shutdown(processor); - processor_unlock(processor); - } + thread_dispatch(old_thread, self); } /* - * Complete the shutdown and place the processor offline. + *Complete the shutdown and place the processor offline. * * Called at splsched in the shutdown context. */ void processor_offline( - processor_t processor) + processor_t processor) { - thread_t thread, old_thread = processor->active_thread; + thread_t new_thread, old_thread = processor->active_thread; - thread = processor->idle_thread; - processor->active_thread = thread; + new_thread = processor->idle_thread; + processor->active_thread = new_thread; processor->current_pri = IDLEPRI; + processor->current_thmode = TH_MODE_NONE; + processor->deadline = UINT64_MAX; + new_thread->last_processor = processor; processor->last_dispatch = mach_absolute_time(); - timer_switch((uint32_t)processor->last_dispatch, - &PROCESSOR_DATA(processor, offline_timer)); - - thread_done(old_thread, thread, processor); - - machine_set_current_thread(thread); + timer_stop(PROCESSOR_DATA(processor, thread_timer), processor->last_dispatch); - thread_begin(thread, processor); + machine_set_current_thread(new_thread); - thread_dispatch(old_thread); + thread_dispatch(old_thread, new_thread); - PMAP_DEACTIVATE_KERNEL(PROCESSOR_DATA(processor, slot_num)); - - processor_lock(processor); - processor->state = PROCESSOR_OFF_LINE; - hw_atomic_sub(&machine_info.avail_cpus, 1); - ml_cpu_down(); - processor_unlock(processor); + PMAP_DEACTIVATE_KERNEL(processor->cpu_id); cpu_sleep(); panic("zombie processor");