Print this page
XXXX pass in cpu_pause_func via pause_cpus
*** 165,181 ****
int cp_spl; /* spl saved in pause_cpus() */
volatile int cp_go; /* Go signal sent after all ready */
int cp_count; /* # of CPUs to pause */
ksema_t cp_sem; /* synch pause_cpus & cpu_pause */
kthread_id_t cp_paused;
} cpu_pause_info;
static kmutex_t pause_free_mutex;
static kcondvar_t pause_free_cv;
- void *(*cpu_pause_func)(void *) = NULL;
-
static struct cpu_sys_stats_ks_data {
kstat_named_t cpu_ticks_idle;
kstat_named_t cpu_ticks_user;
kstat_named_t cpu_ticks_kernel;
--- 165,180 ----
int cp_spl; /* spl saved in pause_cpus() */
volatile int cp_go; /* Go signal sent after all ready */
int cp_count; /* # of CPUs to pause */
ksema_t cp_sem; /* synch pause_cpus & cpu_pause */
kthread_id_t cp_paused;
+ void *(*cp_func)(void *);
} cpu_pause_info;
static kmutex_t pause_free_mutex;
static kcondvar_t pause_free_cv;
static struct cpu_sys_stats_ks_data {
kstat_named_t cpu_ticks_idle;
kstat_named_t cpu_ticks_user;
kstat_named_t cpu_ticks_kernel;
*** 790,808 ****
* an intr doesn't come in, wake up a thread, and call
* setbackdq/setfrontdq.
*/
s = splhigh();
/*
! * if cpu_pause_func() has been set then call it using
! * index as the argument, currently only used by
! * cpr_suspend_cpus(). This function is used as the
! * code to execute on the "paused" cpu's when a machine
! * comes out of a sleep state and CPU's were powered off.
! * (could also be used for hotplugging CPU's).
*/
! if (cpu_pause_func != NULL)
! (*cpu_pause_func)((void *)lindex);
mach_cpu_pause(safe);
splx(s);
/*
--- 789,807 ----
* an intr doesn't come in, wake up a thread, and call
* setbackdq/setfrontdq.
*/
s = splhigh();
/*
! * if cp_func has been set then call it using index as the
! * argument, currently only used by cpr_suspend_cpus().
! * This function is used as the code to execute on the
! * "paused" cpu's when a machine comes out of a sleep state
! * and CPU's were powered off. (could also be used for
! * hotplugging CPU's).
*/
! if (cpi->cp_func != NULL)
! (*cpi->cp_func)((void *)lindex);
mach_cpu_pause(safe);
splx(s);
/*
*** 986,996 ****
* With a few exceptions, the restrictions on code executed with CPUs
* paused match those for code executed at high-level interrupt
* context.
*/
void
! pause_cpus(cpu_t *off_cp)
{
processorid_t cpu_id;
int i;
struct _cpu_pause_info *cpi = &cpu_pause_info;
--- 985,995 ----
* With a few exceptions, the restrictions on code executed with CPUs
* paused match those for code executed at high-level interrupt
* context.
*/
void
! pause_cpus(cpu_t *off_cp, void *(*func)(void *))
{
processorid_t cpu_id;
int i;
struct _cpu_pause_info *cpi = &cpu_pause_info;
*** 1000,1009 ****
--- 999,1010 ----
cpi->cp_go = 0;
for (i = 0; i < NCPU; i++)
safe_list[i] = PAUSE_IDLE;
kpreempt_disable();
+ cpi->cp_func = func;
+
/*
* If running on the cpu that is going offline, get off it.
* This is so that it won't be necessary to rechoose a CPU
* when done.
*/
*** 1204,1214 ****
* No mutexes can be entered while CPUs are paused.
*/
error = mp_cpu_start(cp); /* arch-dep hook */
if (error == 0) {
pg_cpupart_in(cp, cp->cpu_part);
! pause_cpus(NULL);
cpu_add_active_internal(cp);
if (cp->cpu_flags & CPU_FAULTED) {
cp->cpu_flags &= ~CPU_FAULTED;
mp_cpu_faulted_exit(cp);
}
--- 1205,1215 ----
* No mutexes can be entered while CPUs are paused.
*/
error = mp_cpu_start(cp); /* arch-dep hook */
if (error == 0) {
pg_cpupart_in(cp, cp->cpu_part);
! pause_cpus(NULL, NULL);
cpu_add_active_internal(cp);
if (cp->cpu_flags & CPU_FAULTED) {
cp->cpu_flags &= ~CPU_FAULTED;
mp_cpu_faulted_exit(cp);
}
*** 1403,1413 ****
if (error == 0) {
/*
* Put all the cpus into a known safe place.
* No mutexes can be entered while CPUs are paused.
*/
! pause_cpus(cp);
/*
* Repeat the operation, if necessary, to make sure that
* all outstanding low-level interrupts run to completion
* before we set the CPU_QUIESCED flag. It's also possible
* that a thread has weak bound to the cpu despite our raising
--- 1404,1414 ----
if (error == 0) {
/*
* Put all the cpus into a known safe place.
* No mutexes can be entered while CPUs are paused.
*/
! pause_cpus(cp, NULL);
/*
* Repeat the operation, if necessary, to make sure that
* all outstanding low-level interrupts run to completion
* before we set the CPU_QUIESCED flag. It's also possible
* that a thread has weak bound to the cpu despite our raising
*** 1756,1766 ****
* Note that the clock code walks the cpu list dereferencing
* the cpu_part pointer, so we need to initialize it before
* adding the cpu to the list.
*/
cp->cpu_part = &cp_default;
! (void) pause_cpus(NULL);
cp->cpu_next = cpu_list;
cp->cpu_prev = cpu_list->cpu_prev;
cpu_list->cpu_prev->cpu_next = cp;
cpu_list->cpu_prev = cp;
start_cpus();
--- 1757,1767 ----
* Note that the clock code walks the cpu list dereferencing
* the cpu_part pointer, so we need to initialize it before
* adding the cpu to the list.
*/
cp->cpu_part = &cp_default;
! (void) pause_cpus(NULL, NULL);
cp->cpu_next = cpu_list;
cp->cpu_prev = cpu_list->cpu_prev;
cpu_list->cpu_prev->cpu_next = cp;
cpu_list->cpu_prev = cp;
start_cpus();
*** 1851,1861 ****
*
* Note that this MUST be done AFTER cpu_available
* has been updated so that we don't waste time
* trying to pause the cpu we're trying to delete.
*/
! (void) pause_cpus(NULL);
cpnext = cp->cpu_next;
cp->cpu_prev->cpu_next = cp->cpu_next;
cp->cpu_next->cpu_prev = cp->cpu_prev;
if (cp == cpu_list)
--- 1852,1862 ----
*
* Note that this MUST be done AFTER cpu_available
* has been updated so that we don't waste time
* trying to pause the cpu we're trying to delete.
*/
! (void) pause_cpus(NULL, NULL);
cpnext = cp->cpu_next;
cp->cpu_prev->cpu_next = cp->cpu_next;
cp->cpu_next->cpu_prev = cp->cpu_prev;
if (cp == cpu_list)
*** 1923,1933 ****
void
cpu_add_active(cpu_t *cp)
{
pg_cpupart_in(cp, cp->cpu_part);
! pause_cpus(NULL);
cpu_add_active_internal(cp);
start_cpus();
cpu_stats_kstat_create(cp);
cpu_create_intrstat(cp);
--- 1924,1934 ----
void
cpu_add_active(cpu_t *cp)
{
pg_cpupart_in(cp, cp->cpu_part);
! pause_cpus(NULL, NULL);
cpu_add_active_internal(cp);
start_cpus();
cpu_stats_kstat_create(cp);
cpu_create_intrstat(cp);