1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * This module contains the guts of checkpoint-resume mechanism.
28 * All code in this module is platform independent.
29 */
30
31 #include <sys/types.h>
32 #include <sys/errno.h>
33 #include <sys/callb.h>
34 #include <sys/processor.h>
35 #include <sys/machsystm.h>
36 #include <sys/clock.h>
37 #include <sys/vfs.h>
38 #include <sys/kmem.h>
39 #include <nfs/lm.h>
40 #include <sys/systm.h>
41 #include <sys/cpr.h>
42 #include <sys/bootconf.h>
43 #include <sys/cyclic.h>
44 #include <sys/filio.h>
45 #include <sys/fs/ufs_filio.h>
46 #include <sys/epm.h>
47 #include <sys/modctl.h>
48 #include <sys/reboot.h>
49 #include <sys/kdi.h>
50 #include <sys/promif.h>
51 #include <sys/srn.h>
52 #include <sys/cpr_impl.h>
53
54 #define PPM(dip) ((dev_info_t *)DEVI(dip)->devi_pm_ppm)
55
56 extern struct cpr_terminator cpr_term;
57
58 extern int cpr_alloc_statefile(int);
59 extern void cpr_start_kernel_threads(void);
60 extern void cpr_abbreviate_devpath(char *, char *);
61 extern void cpr_convert_promtime(cpr_time_t *);
62 extern void cpr_send_notice(void);
63 extern void cpr_set_bitmap_size(void);
64 extern void cpr_stat_init();
65 extern void cpr_statef_close(void);
66 extern void flush_windows(void);
67 extern void (*srn_signal)(int, int);
68 extern void init_cpu_syscall(struct cpu *);
69 extern void i_cpr_pre_resume_cpus();
70 extern void i_cpr_post_resume_cpus();
71 extern int cpr_is_ufs(struct vfs *);
72
73 extern int pm_powering_down;
74 extern kmutex_t srn_clone_lock;
75 extern int srn_inuse;
76
77 static int cpr_suspend(int);
78 static int cpr_resume(int);
79 static void cpr_suspend_init(int);
80 #if defined(__x86)
81 static int cpr_suspend_cpus(void);
82 static void cpr_resume_cpus(void);
83 #endif
84 static int cpr_all_online(void);
85 static void cpr_restore_offline(void);
86
87 cpr_time_t wholecycle_tv;
88 int cpr_suspend_succeeded;
89 pfn_t curthreadpfn;
90 int curthreadremapped;
91
92 extern cpuset_t cpu_ready_set;
93
94 extern processorid_t i_cpr_bootcpuid(void);
95 extern cpu_t *i_cpr_bootcpu(void);
96 extern void tsc_adjust_delta(hrtime_t tdelta);
97 extern void tsc_resume(void);
98 extern int tsc_resume_in_cyclic;
99
100 /*
101 * Set this variable to 1, to have device drivers resume in an
102 * uniprocessor environment. This is to allow drivers that assume
103 * that they resume on a UP machine to continue to work. Should be
104 * deprecated once the broken drivers are fixed
105 */
106 int cpr_resume_uniproc = 0;
107
108 /*
109 * save or restore abort_enable; this prevents a drop
110 * to kadb or prom during cpr_resume_devices() when
111 * there is no kbd present; see abort_sequence_enter()
112 */
113 static void
cpr_sae(int stash)114 cpr_sae(int stash)
115 {
116 static int saved_ae = -1;
117
118 if (stash) {
119 saved_ae = abort_enable;
120 abort_enable = 0;
121 } else if (saved_ae != -1) {
122 abort_enable = saved_ae;
123 saved_ae = -1;
124 }
125 }
126
127
128 /*
129 * The main switching point for cpr, this routine starts the ckpt
130 * and state file saving routines; on resume the control is
131 * returned back to here and it then calls the resume routine.
132 */
133 int
cpr_main(int sleeptype)134 cpr_main(int sleeptype)
135 {
136 int rc, rc2;
137 label_t saveq;
138 klwp_t *tlwp = ttolwp(curthread);
139
140 if (sleeptype == CPR_TODISK) {
141 if ((rc = cpr_default_setup(1)) != 0)
142 return (rc);
143 ASSERT(tlwp);
144 saveq = tlwp->lwp_qsav;
145 }
146
147 if (sleeptype == CPR_TORAM) {
148 rc = cpr_suspend(sleeptype);
149 PMD(PMD_SX, ("cpr_suspend rets %x\n", rc))
150 if (rc == 0) {
151 int i_cpr_power_down(int sleeptype);
152
153 /*
154 * From this point on, we should be at a high
155 * spl, interrupts disabled, and all but one
156 * cpu's paused (effectively UP/single threaded).
157 * So this is were we want to put ASSERTS()
158 * to let us know otherwise.
159 */
160 ASSERT(cpus_paused());
161
162 /*
163 * Now do the work of actually putting this
164 * machine to sleep!
165 */
166 rc = i_cpr_power_down(sleeptype);
167 if (rc == 0) {
168 PMD(PMD_SX, ("back from successful suspend\n"))
169 }
170 /*
171 * We do care about the return value from cpr_resume
172 * at this point, as it will tell us if one of the
173 * resume functions failed (cpr_resume_devices())
174 * However, for this to return and _not_ panic, means
175 * that we must be in one of the test functions. So
176 * check for that and return an appropriate message.
177 */
178 rc2 = cpr_resume(sleeptype);
179 if (rc2 != 0) {
180 ASSERT(cpr_test_point > 0);
181 cmn_err(CE_NOTE,
182 "cpr_resume returned non-zero: %d\n", rc2);
183 PMD(PMD_SX, ("cpr_resume rets %x\n", rc2))
184 }
185 ASSERT(!cpus_paused());
186 } else {
187 PMD(PMD_SX, ("failed suspend, resuming\n"))
188 rc = cpr_resume(sleeptype);
189 }
190 return (rc);
191 }
192 /*
193 * Remember where we are for resume after reboot
194 */
195 if (!setjmp(&tlwp->lwp_qsav)) {
196 /*
197 * try to checkpoint the system, if failed return back
198 * to userland, otherwise power off.
199 */
200 rc = cpr_suspend(sleeptype);
201 if (rc || cpr_reusable_mode) {
202 /*
203 * We don't really want to go down, or
204 * something went wrong in suspend, do what we can
205 * to put the system back to an operable state then
206 * return back to userland.
207 */
208 PMD(PMD_SX, ("failed suspend, resuming\n"))
209 (void) cpr_resume(sleeptype);
210 PMD(PMD_SX, ("back from failed suspend resume\n"))
211 }
212 } else {
213 /*
214 * This is the resumed side of longjmp, restore the previous
215 * longjmp pointer if there is one so this will be transparent
216 * to the world.
217 * This path is only for CPR_TODISK, where we reboot
218 */
219 ASSERT(sleeptype == CPR_TODISK);
220 tlwp->lwp_qsav = saveq;
221 CPR->c_flags &= ~C_SUSPENDING;
222 CPR->c_flags |= C_RESUMING;
223
224 /*
225 * resume the system back to the original state
226 */
227 rc = cpr_resume(sleeptype);
228 PMD(PMD_SX, ("back from successful suspend; resume rets %x\n",
229 rc))
230 }
231
232 (void) cpr_default_setup(0);
233
234 return (rc);
235 }
236
237
238 #if defined(__sparc)
239
240 /*
241 * check/disable or re-enable UFS logging
242 */
243 static void
cpr_log_status(int enable,int * svstat,vnode_t * vp)244 cpr_log_status(int enable, int *svstat, vnode_t *vp)
245 {
246 int cmd, status, error;
247 char *str, *able;
248 fiolog_t fl;
249 refstr_t *mntpt;
250
251 str = "cpr_log_status";
252 bzero(&fl, sizeof (fl));
253 fl.error = FIOLOG_ENONE;
254
255 /*
256 * when disabling, first get and save logging status (0 or 1)
257 */
258 if (enable == 0) {
259 if (error = VOP_IOCTL(vp, _FIOISLOG,
260 (uintptr_t)&status, FKIOCTL, CRED(), NULL, NULL)) {
261 mntpt = vfs_getmntpoint(vp->v_vfsp);
262 prom_printf("%s: \"%s\", cant get logging "
263 "status, error %d\n", str, refstr_value(mntpt),
264 error);
265 refstr_rele(mntpt);
266 return;
267 }
268 *svstat = status;
269 if (cpr_debug & CPR_DEBUG5) {
270 mntpt = vfs_getmntpoint(vp->v_vfsp);
271 errp("%s: \"%s\", logging status = %d\n",
272 str, refstr_value(mntpt), status);
273 refstr_rele(mntpt);
274 };
275
276 able = "disable";
277 cmd = _FIOLOGDISABLE;
278 } else {
279 able = "enable";
280 cmd = _FIOLOGENABLE;
281 }
282
283 /*
284 * disable or re-enable logging when the saved status is 1
285 */
286 if (*svstat == 1) {
287 error = VOP_IOCTL(vp, cmd, (uintptr_t)&fl,
288 FKIOCTL, CRED(), NULL, NULL);
289 if (error) {
290 mntpt = vfs_getmntpoint(vp->v_vfsp);
291 prom_printf("%s: \"%s\", cant %s logging, error %d\n",
292 str, refstr_value(mntpt), able, error);
293 refstr_rele(mntpt);
294 } else {
295 if (cpr_debug & CPR_DEBUG5) {
296 mntpt = vfs_getmntpoint(vp->v_vfsp);
297 errp("%s: \"%s\", logging is now %sd\n",
298 str, refstr_value(mntpt), able);
299 refstr_rele(mntpt);
300 };
301 }
302 }
303
304 /*
305 * when enabling logging, reset the saved status
306 * to unknown for next time
307 */
308 if (enable)
309 *svstat = -1;
310 }
311
312 /*
313 * enable/disable UFS logging on filesystems containing cpr_default_path
314 * and cpr statefile. since the statefile can be on any fs, that fs
315 * needs to be handled separately. this routine and cprboot expect that
316 * CPR_CONFIG and CPR_DEFAULT both reside on the same fs, rootfs. cprboot
317 * is loaded from the device with rootfs and uses the same device to open
318 * both CPR_CONFIG and CPR_DEFAULT (see common/support.c). moving either
319 * file outside of rootfs would cause errors during cprboot, plus cpr and
320 * fsck problems with the new fs if logging were enabled.
321 */
322
323 static int
cpr_ufs_logging(int enable)324 cpr_ufs_logging(int enable)
325 {
326 static int def_status = -1, sf_status = -1;
327 struct vfs *vfsp;
328 char *fname;
329 vnode_t *vp;
330 int error;
331
332 if (cpr_reusable_mode)
333 return (0);
334
335 if (error = cpr_open_deffile(FREAD, &vp))
336 return (error);
337 vfsp = vp->v_vfsp;
338 if (!cpr_is_ufs(vfsp)) {
339 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
340 VN_RELE(vp);
341 return (0);
342 }
343
344 cpr_log_status(enable, &def_status, vp);
345 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
346 VN_RELE(vp);
347
348 fname = cpr_build_statefile_path();
349 if (fname == NULL)
350 return (ENOENT);
351 if (error = vn_open(fname, UIO_SYSSPACE, FCREAT|FWRITE,
352 0600, &vp, CRCREAT, 0)) {
353 prom_printf("cpr_ufs_logging: cant open/create \"%s\", "
354 "error %d\n", fname, error);
355 return (error);
356 }
357
358 /*
359 * check logging status for the statefile if it resides
360 * on a different fs and the type is a regular file
361 */
362 if (vp->v_vfsp != vfsp && vp->v_type == VREG)
363 cpr_log_status(enable, &sf_status, vp);
364 (void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
365 VN_RELE(vp);
366
367 return (0);
368 }
369 #endif
370
371
372 /*
373 * Check if klmmod is loaded and call a lock manager service; if klmmod
374 * is not loaded, the services aren't needed and a call would trigger a
375 * modload, which would block since another thread would never run.
376 */
377 static void
cpr_lock_mgr(void (* service)(void))378 cpr_lock_mgr(void (*service)(void))
379 {
380 if (mod_find_by_filename(NULL, "misc/klmmod") != NULL)
381 (*service)();
382 }
383
384 int
cpr_suspend_cpus(void)385 cpr_suspend_cpus(void)
386 {
387 int ret = 0;
388 extern void *i_cpr_save_context(void *arg);
389
390 mutex_enter(&cpu_lock);
391
392 /*
393 * the machine could not have booted without a bootcpu
394 */
395 ASSERT(i_cpr_bootcpu() != NULL);
396
397 /*
398 * bring all the offline cpus online
399 */
400 if ((ret = cpr_all_online())) {
401 mutex_exit(&cpu_lock);
402 return (ret);
403 }
404
405 /*
406 * Set the affinity to be the boot processor
407 * This is cleared in either cpr_resume_cpus() or cpr_unpause_cpus()
408 */
409 affinity_set(i_cpr_bootcpuid());
410
411 ASSERT(CPU->cpu_id == 0);
412
413 PMD(PMD_SX, ("curthread running on bootcpu\n"))
414
415 /*
416 * pause all other running CPUs and save the CPU state at the sametime
417 */
418 pause_cpus(NULL, i_cpr_save_context);
419
420 mutex_exit(&cpu_lock);
421
422 return (0);
423 }
424
425 /*
426 * Take the system down to a checkpointable state and write
427 * the state file, the following are sequentially executed:
428 *
429 * - Request all user threads to stop themselves
430 * - push out and invalidate user pages
431 * - bring statefile inode incore to prevent a miss later
432 * - request all daemons to stop
433 * - check and make sure all threads are stopped
434 * - sync the file system
435 * - suspend all devices
436 * - block intrpts
437 * - dump system state and memory to state file
438 * - SPARC code will not be called with CPR_TORAM, caller filters
439 */
440 static int
cpr_suspend(int sleeptype)441 cpr_suspend(int sleeptype)
442 {
443 #if defined(__sparc)
444 int sf_realloc, nverr;
445 #endif
446 int rc = 0;
447 int skt_rc = 0;
448
449 PMD(PMD_SX, ("cpr_suspend %x\n", sleeptype))
450 cpr_set_substate(C_ST_SUSPEND_BEGIN);
451
452 cpr_suspend_init(sleeptype);
453
454 cpr_save_time();
455
456 cpr_tod_get(&wholecycle_tv);
457 CPR_STAT_EVENT_START("Suspend Total");
458
459 i_cpr_alloc_cpus();
460
461 #if defined(__sparc)
462 ASSERT(sleeptype == CPR_TODISK);
463 if (!cpr_reusable_mode) {
464 /*
465 * We need to validate default file before fs
466 * functionality is disabled.
467 */
468 if (rc = cpr_validate_definfo(0))
469 return (rc);
470 }
471 i_cpr_save_machdep_info();
472 #endif
473
474 PMD(PMD_SX, ("cpr_suspend: stop scans\n"))
475 /* Stop PM scans ASAP */
476 (void) callb_execute_class(CB_CL_CPR_PM, CB_CODE_CPR_CHKPT);
477
478 pm_dispatch_to_dep_thread(PM_DEP_WK_CPR_SUSPEND,
479 NULL, NULL, PM_DEP_WAIT, NULL, 0);
480
481 #if defined(__sparc)
482 ASSERT(sleeptype == CPR_TODISK);
483 cpr_set_substate(C_ST_MP_OFFLINE);
484 if (rc = cpr_mp_offline())
485 return (rc);
486 #endif
487 /*
488 * Ask Xorg to suspend the frame buffer, and wait for it to happen
489 */
490 mutex_enter(&srn_clone_lock);
491 if (srn_signal) {
492 PMD(PMD_SX, ("cpr_suspend: (*srn_signal)(..., "
493 "SRN_SUSPEND_REQ)\n"))
494 srn_inuse = 1; /* because *(srn_signal) cv_waits */
495 (*srn_signal)(SRN_TYPE_APM, SRN_SUSPEND_REQ);
496 srn_inuse = 0;
497 } else {
498 PMD(PMD_SX, ("cpr_suspend: srn_signal NULL\n"))
499 }
500 mutex_exit(&srn_clone_lock);
501
502 /*
503 * Ask the user threads to stop by themselves, but
504 * if they don't or can't after 3 retries, we give up on CPR.
505 * The 3 retry is not a random number because 2 is possible if
506 * a thread has been forked before the parent thread is stopped.
507 */
508 CPR_DEBUG(CPR_DEBUG1, "\nstopping user threads...");
509 CPR_STAT_EVENT_START(" stop users");
510 cpr_set_substate(C_ST_STOP_USER_THREADS);
511 PMD(PMD_SX, ("cpr_suspend: stop user threads\n"))
512 if (rc = cpr_stop_user_threads())
513 return (rc);
514 CPR_STAT_EVENT_END(" stop users");
515 CPR_DEBUG(CPR_DEBUG1, "done\n");
516
517 PMD(PMD_SX, ("cpr_suspend: save direct levels\n"))
518 pm_save_direct_levels();
519
520 /*
521 * User threads are stopped. We will start communicating with the
522 * user via prom_printf (some debug output may have already happened)
523 * so let anybody who cares know about this (bug 4096122)
524 */
525 (void) callb_execute_class(CB_CL_CPR_PROMPRINTF, CB_CODE_CPR_CHKPT);
526
527 PMD(PMD_SX, ("cpr_suspend: send notice\n"))
528 #ifndef DEBUG
529 cpr_send_notice();
530 if (cpr_debug)
531 prom_printf("\n");
532 #endif
533
534 PMD(PMD_SX, ("cpr_suspend: POST USER callback\n"))
535 (void) callb_execute_class(CB_CL_CPR_POST_USER, CB_CODE_CPR_CHKPT);
536
537 /*
538 * Reattach any drivers which originally exported the
539 * no-involuntary-power-cycles property. We need to do this before
540 * stopping kernel threads because modload is implemented using
541 * a kernel thread.
542 */
543 cpr_set_substate(C_ST_PM_REATTACH_NOINVOL);
544 PMD(PMD_SX, ("cpr_suspend: reattach noinvol\n"))
545 if (!pm_reattach_noinvol())
546 return (ENXIO);
547
548 #if defined(__sparc)
549 ASSERT(sleeptype == CPR_TODISK);
550 /*
551 * if ufs logging is enabled, we need to disable before
552 * stopping kernel threads so that ufs delete and roll
553 * threads can do the work.
554 */
555 cpr_set_substate(C_ST_DISABLE_UFS_LOGGING);
556 if (rc = cpr_ufs_logging(0))
557 return (rc);
558
559 /*
560 * Use sync_all to swap out all user pages and find out how much
561 * extra space needed for user pages that don't have back store
562 * space left.
563 */
564 CPR_STAT_EVENT_START(" swapout upages");
565 vfs_sync(SYNC_ALL);
566 CPR_STAT_EVENT_END(" swapout upages");
567
568 cpr_set_bitmap_size();
569
570 alloc_statefile:
571 /*
572 * If our last state was C_ST_DUMP_NOSPC, we're trying to
573 * realloc the statefile, otherwise this is the first attempt.
574 */
575 sf_realloc = (CPR->c_substate == C_ST_DUMP_NOSPC) ? 1 : 0;
576
577 CPR_STAT_EVENT_START(" alloc statefile");
578 cpr_set_substate(C_ST_STATEF_ALLOC);
579 if (rc = cpr_alloc_statefile(sf_realloc)) {
580 if (sf_realloc)
581 errp("realloc failed\n");
582 return (rc);
583 }
584 CPR_STAT_EVENT_END(" alloc statefile");
585
586 /*
587 * Sync the filesystem to preserve its integrity.
588 *
589 * This sync is also used to flush out all B_DELWRI buffers
590 * (fs cache) which are mapped and neither dirty nor referenced
591 * before cpr_invalidate_pages destroys them.
592 * fsflush does similar thing.
593 */
594 sync();
595
596 /*
597 * destroy all clean file mapped kernel pages
598 */
599 CPR_STAT_EVENT_START(" clean pages");
600 CPR_DEBUG(CPR_DEBUG1, ("cleaning up mapped pages..."));
601 (void) callb_execute_class(CB_CL_CPR_VM, CB_CODE_CPR_CHKPT);
602 CPR_DEBUG(CPR_DEBUG1, ("done\n"));
603 CPR_STAT_EVENT_END(" clean pages");
604 #endif
605
606
607 /*
608 * Hooks needed by lock manager prior to suspending.
609 * Refer to code for more comments.
610 */
611 PMD(PMD_SX, ("cpr_suspend: lock mgr\n"))
612 cpr_lock_mgr(lm_cprsuspend);
613
614 /*
615 * Now suspend all the devices
616 */
617 CPR_STAT_EVENT_START(" stop drivers");
618 CPR_DEBUG(CPR_DEBUG1, "suspending drivers...");
619 cpr_set_substate(C_ST_SUSPEND_DEVICES);
620 pm_powering_down = 1;
621 PMD(PMD_SX, ("cpr_suspend: suspending devices\n"))
622 rc = cpr_suspend_devices(ddi_root_node());
623 pm_powering_down = 0;
624 if (rc)
625 return (rc);
626 CPR_DEBUG(CPR_DEBUG1, "done\n");
627 CPR_STAT_EVENT_END(" stop drivers");
628
629 /*
630 * Stop all daemon activities
631 */
632 cpr_set_substate(C_ST_STOP_KERNEL_THREADS);
633 PMD(PMD_SX, ("cpr_suspend: stopping kernel threads\n"))
634 if (skt_rc = cpr_stop_kernel_threads())
635 return (skt_rc);
636
637 PMD(PMD_SX, ("cpr_suspend: POST KERNEL callback\n"))
638 (void) callb_execute_class(CB_CL_CPR_POST_KERNEL, CB_CODE_CPR_CHKPT);
639
640 PMD(PMD_SX, ("cpr_suspend: reattach noinvol fini\n"))
641 pm_reattach_noinvol_fini();
642
643 cpr_sae(1);
644
645 PMD(PMD_SX, ("cpr_suspend: CPR CALLOUT callback\n"))
646 (void) callb_execute_class(CB_CL_CPR_CALLOUT, CB_CODE_CPR_CHKPT);
647
648 if (sleeptype == CPR_TODISK) {
649 /*
650 * It's safer to do tod_get before we disable all intr.
651 */
652 CPR_STAT_EVENT_START(" write statefile");
653 }
654
655 /*
656 * it's time to ignore the outside world, stop the real time
657 * clock and disable any further intrpt activity.
658 */
659 PMD(PMD_SX, ("cpr_suspend: handle xc\n"))
660 i_cpr_handle_xc(1); /* turn it on to disable xc assertion */
661
662 mutex_enter(&cpu_lock);
663 PMD(PMD_SX, ("cpr_suspend: cyclic suspend\n"))
664 cyclic_suspend();
665 mutex_exit(&cpu_lock);
666
667 /*
668 * Due to the different methods of resuming the system between
669 * CPR_TODISK (boot cprboot on SPARC, which reloads kernel image)
670 * and CPR_TORAM (restart via reset into existing kernel image)
671 * cpus are not suspended and restored in the SPARC case, since it
672 * is necessary to restart the cpus and pause them before restoring
673 * the OBP image
674 */
675
676 #if defined(__x86)
677
678 /* pause aux cpus */
679 PMD(PMD_SX, ("pause aux cpus\n"))
680
681 cpr_set_substate(C_ST_MP_PAUSED);
682
683 if ((rc = cpr_suspend_cpus()) != 0)
684 return (rc);
685 #endif
686
687 PMD(PMD_SX, ("cpr_suspend: stop intr\n"))
688 i_cpr_stop_intr();
689 CPR_DEBUG(CPR_DEBUG1, "interrupt is stopped\n");
690
691 /*
692 * Since we will now disable the mechanism that causes prom_printfs
693 * to power up (if needed) the console fb/monitor, we assert that
694 * it must be up now.
695 */
696 ASSERT(pm_cfb_is_up());
697 PMD(PMD_SX, ("cpr_suspend: prom suspend prepost\n"))
698 prom_suspend_prepost();
699
700 #if defined(__sparc)
701 /*
702 * getting ready to write ourself out, flush the register
703 * windows to make sure that our stack is good when we
704 * come back on the resume side.
705 */
706 flush_windows();
707 #endif
708
709 /*
710 * For S3, we're done
711 */
712 if (sleeptype == CPR_TORAM) {
713 PMD(PMD_SX, ("cpr_suspend rets %x\n", rc))
714 cpr_set_substate(C_ST_NODUMP);
715 return (rc);
716 }
717 #if defined(__sparc)
718 /*
719 * FATAL: NO MORE MEMORY ALLOCATION ALLOWED AFTER THIS POINT!!!
720 *
721 * The system is quiesced at this point, we are ready to either dump
722 * to the state file for a extended sleep or a simple shutdown for
723 * systems with non-volatile memory.
724 */
725
726 /*
727 * special handling for reusable:
728 */
729 if (cpr_reusable_mode) {
730 cpr_set_substate(C_ST_SETPROPS_1);
731 if (nverr = cpr_set_properties(1))
732 return (nverr);
733 }
734
735 cpr_set_substate(C_ST_DUMP);
736 rc = cpr_dump(C_VP);
737
738 /*
739 * if any error occurred during dump, more
740 * special handling for reusable:
741 */
742 if (rc && cpr_reusable_mode) {
743 cpr_set_substate(C_ST_SETPROPS_0);
744 if (nverr = cpr_set_properties(0))
745 return (nverr);
746 }
747
748 if (rc == ENOSPC) {
749 cpr_set_substate(C_ST_DUMP_NOSPC);
750 (void) cpr_resume(sleeptype);
751 goto alloc_statefile;
752 } else if (rc == 0) {
753 if (cpr_reusable_mode) {
754 cpr_set_substate(C_ST_REUSABLE);
755 longjmp(&ttolwp(curthread)->lwp_qsav);
756 } else
757 rc = cpr_set_properties(1);
758 }
759 #endif
760 PMD(PMD_SX, ("cpr_suspend: return %d\n", rc))
761 return (rc);
762 }
763
764 void
cpr_resume_cpus(void)765 cpr_resume_cpus(void)
766 {
767 /*
768 * this is a cut down version of start_other_cpus()
769 * just do the initialization to wake the other cpus
770 */
771
772 #if defined(__x86)
773 /*
774 * Initialize our syscall handlers
775 */
776 init_cpu_syscall(CPU);
777
778 #endif
779
780 i_cpr_pre_resume_cpus();
781
782 /*
783 * Restart the paused cpus
784 */
785 mutex_enter(&cpu_lock);
786 start_cpus();
787 mutex_exit(&cpu_lock);
788
789 i_cpr_post_resume_cpus();
790
791 mutex_enter(&cpu_lock);
792 /*
793 * clear the affinity set in cpr_suspend_cpus()
794 */
795 affinity_clear();
796
797 /*
798 * offline all the cpus that were brought online during suspend
799 */
800 cpr_restore_offline();
801
802 mutex_exit(&cpu_lock);
803 }
804
805 void
cpr_unpause_cpus(void)806 cpr_unpause_cpus(void)
807 {
808 /*
809 * Now restore the system back to what it was before we suspended
810 */
811
812 PMD(PMD_SX, ("cpr_unpause_cpus: restoring system\n"))
813
814 mutex_enter(&cpu_lock);
815 /*
816 * Restart the paused cpus
817 */
818 start_cpus();
819
820 /*
821 * clear the affinity set in cpr_suspend_cpus()
822 */
823 affinity_clear();
824
825 /*
826 * offline all the cpus that were brought online during suspend
827 */
828 cpr_restore_offline();
829
830 mutex_exit(&cpu_lock);
831 }
832
833 /*
834 * Bring the system back up from a checkpoint, at this point
835 * the VM has been minimally restored by boot, the following
836 * are executed sequentially:
837 *
838 * - machdep setup and enable interrupts (mp startup if it's mp)
839 * - resume all devices
840 * - restart daemons
841 * - put all threads back on run queue
842 */
843 static int
cpr_resume(int sleeptype)844 cpr_resume(int sleeptype)
845 {
846 cpr_time_t pwron_tv, *ctp;
847 char *str;
848 int rc = 0;
849
850 /*
851 * The following switch is used to resume the system
852 * that was suspended to a different level.
853 */
854 CPR_DEBUG(CPR_DEBUG1, "\nEntering cpr_resume...\n");
855 PMD(PMD_SX, ("cpr_resume %x\n", sleeptype))
856
857 /*
858 * Note:
859 *
860 * The rollback labels rb_xyz do not represent the cpr resume
861 * state when event 'xyz' has happened. Instead they represent
862 * the state during cpr suspend when event 'xyz' was being
863 * entered (and where cpr suspend failed). The actual call that
864 * failed may also need to be partially rolled back, since they
865 * aren't atomic in most cases. In other words, rb_xyz means
866 * "roll back all cpr suspend events that happened before 'xyz',
867 * and the one that caused the failure, if necessary."
868 */
869 switch (CPR->c_substate) {
870 #if defined(__sparc)
871 case C_ST_DUMP:
872 /*
873 * This is most likely a full-fledged cpr_resume after
874 * a complete and successful cpr suspend. Just roll back
875 * everything.
876 */
877 ASSERT(sleeptype == CPR_TODISK);
878 break;
879
880 case C_ST_REUSABLE:
881 case C_ST_DUMP_NOSPC:
882 case C_ST_SETPROPS_0:
883 case C_ST_SETPROPS_1:
884 /*
885 * C_ST_REUSABLE and C_ST_DUMP_NOSPC are the only two
886 * special switch cases here. The other two do not have
887 * any state change during cpr_suspend() that needs to
888 * be rolled back. But these are exit points from
889 * cpr_suspend, so theoretically (or in the future), it
890 * is possible that a need for roll back of a state
891 * change arises between these exit points.
892 */
893 ASSERT(sleeptype == CPR_TODISK);
894 goto rb_dump;
895 #endif
896
897 case C_ST_NODUMP:
898 PMD(PMD_SX, ("cpr_resume: NODUMP\n"))
899 goto rb_nodump;
900
901 case C_ST_STOP_KERNEL_THREADS:
902 PMD(PMD_SX, ("cpr_resume: STOP_KERNEL_THREADS\n"))
903 goto rb_stop_kernel_threads;
904
905 case C_ST_SUSPEND_DEVICES:
906 PMD(PMD_SX, ("cpr_resume: SUSPEND_DEVICES\n"))
907 goto rb_suspend_devices;
908
909 #if defined(__sparc)
910 case C_ST_STATEF_ALLOC:
911 ASSERT(sleeptype == CPR_TODISK);
912 goto rb_statef_alloc;
913
914 case C_ST_DISABLE_UFS_LOGGING:
915 ASSERT(sleeptype == CPR_TODISK);
916 goto rb_disable_ufs_logging;
917 #endif
918
919 case C_ST_PM_REATTACH_NOINVOL:
920 PMD(PMD_SX, ("cpr_resume: REATTACH_NOINVOL\n"))
921 goto rb_pm_reattach_noinvol;
922
923 case C_ST_STOP_USER_THREADS:
924 PMD(PMD_SX, ("cpr_resume: STOP_USER_THREADS\n"))
925 goto rb_stop_user_threads;
926
927 #if defined(__sparc)
928 case C_ST_MP_OFFLINE:
929 PMD(PMD_SX, ("cpr_resume: MP_OFFLINE\n"))
930 goto rb_mp_offline;
931 #endif
932
933 #if defined(__x86)
934 case C_ST_MP_PAUSED:
935 PMD(PMD_SX, ("cpr_resume: MP_PAUSED\n"))
936 goto rb_mp_paused;
937 #endif
938
939
940 default:
941 PMD(PMD_SX, ("cpr_resume: others\n"))
942 goto rb_others;
943 }
944
945 rb_all:
946 /*
947 * perform platform-dependent initialization
948 */
949 if (cpr_suspend_succeeded)
950 i_cpr_machdep_setup();
951
952 /*
953 * system did not really go down if we jump here
954 */
955 rb_dump:
956 /*
957 * IMPORTANT: SENSITIVE RESUME SEQUENCE
958 *
959 * DO NOT ADD ANY INITIALIZATION STEP BEFORE THIS POINT!!
960 */
961 rb_nodump:
962 /*
963 * If we did suspend to RAM, we didn't generate a dump
964 */
965 PMD(PMD_SX, ("cpr_resume: CPR DMA callback\n"))
966 (void) callb_execute_class(CB_CL_CPR_DMA, CB_CODE_CPR_RESUME);
967 if (cpr_suspend_succeeded) {
968 PMD(PMD_SX, ("cpr_resume: CPR RPC callback\n"))
969 (void) callb_execute_class(CB_CL_CPR_RPC, CB_CODE_CPR_RESUME);
970 }
971
972 prom_resume_prepost();
973 #if !defined(__sparc)
974 /*
975 * Need to sync the software clock with the hardware clock.
976 * On Sparc, this occurs in the sparc-specific cbe. However
977 * on x86 this needs to be handled _before_ we bring other cpu's
978 * back online. So we call a resume function in timestamp.c
979 */
980 if (tsc_resume_in_cyclic == 0)
981 tsc_resume();
982
983 #endif
984
985 #if defined(__sparc)
986 if (cpr_suspend_succeeded && (boothowto & RB_DEBUG))
987 kdi_dvec_cpr_restart();
988 #endif
989
990
991 #if defined(__x86)
992 rb_mp_paused:
993 PT(PT_RMPO);
994 PMD(PMD_SX, ("resume aux cpus\n"))
995
996 if (cpr_suspend_succeeded) {
997 cpr_resume_cpus();
998 } else {
999 cpr_unpause_cpus();
1000 }
1001 #endif
1002
1003 /*
1004 * let the tmp callout catch up.
1005 */
1006 PMD(PMD_SX, ("cpr_resume: CPR CALLOUT callback\n"))
1007 (void) callb_execute_class(CB_CL_CPR_CALLOUT, CB_CODE_CPR_RESUME);
1008
1009 i_cpr_enable_intr();
1010
1011 mutex_enter(&cpu_lock);
1012 PMD(PMD_SX, ("cpr_resume: cyclic resume\n"))
1013 cyclic_resume();
1014 mutex_exit(&cpu_lock);
1015
1016 PMD(PMD_SX, ("cpr_resume: handle xc\n"))
1017 i_cpr_handle_xc(0); /* turn it off to allow xc assertion */
1018
1019 PMD(PMD_SX, ("cpr_resume: CPR POST KERNEL callback\n"))
1020 (void) callb_execute_class(CB_CL_CPR_POST_KERNEL, CB_CODE_CPR_RESUME);
1021
1022 /*
1023 * statistics gathering
1024 */
1025 if (cpr_suspend_succeeded) {
1026 /*
1027 * Prevent false alarm in tod_validate() due to tod
1028 * value change between suspend and resume
1029 */
1030 cpr_tod_status_set(TOD_CPR_RESUME_DONE);
1031
1032 cpr_convert_promtime(&pwron_tv);
1033
1034 ctp = &cpr_term.tm_shutdown;
1035 if (sleeptype == CPR_TODISK)
1036 CPR_STAT_EVENT_END_TMZ(" write statefile", ctp);
1037 CPR_STAT_EVENT_END_TMZ("Suspend Total", ctp);
1038
1039 CPR_STAT_EVENT_START_TMZ("Resume Total", &pwron_tv);
1040
1041 str = " prom time";
1042 CPR_STAT_EVENT_START_TMZ(str, &pwron_tv);
1043 ctp = &cpr_term.tm_cprboot_start;
1044 CPR_STAT_EVENT_END_TMZ(str, ctp);
1045
1046 str = " read statefile";
1047 CPR_STAT_EVENT_START_TMZ(str, ctp);
1048 ctp = &cpr_term.tm_cprboot_end;
1049 CPR_STAT_EVENT_END_TMZ(str, ctp);
1050 }
1051
1052 rb_stop_kernel_threads:
1053 /*
1054 * Put all threads back to where they belong; get the kernel
1055 * daemons straightened up too. Note that the callback table
1056 * locked during cpr_stop_kernel_threads() is released only
1057 * in cpr_start_kernel_threads(). Ensure modunloading is
1058 * disabled before starting kernel threads, we don't want
1059 * modunload thread to start changing device tree underneath.
1060 */
1061 PMD(PMD_SX, ("cpr_resume: modunload disable\n"))
1062 modunload_disable();
1063 PMD(PMD_SX, ("cpr_resume: start kernel threads\n"))
1064 cpr_start_kernel_threads();
1065
1066 rb_suspend_devices:
1067 CPR_DEBUG(CPR_DEBUG1, "resuming devices...");
1068 CPR_STAT_EVENT_START(" start drivers");
1069
1070 PMD(PMD_SX,
1071 ("cpr_resume: rb_suspend_devices: cpr_resume_uniproc = %d\n",
1072 cpr_resume_uniproc))
1073
1074 #if defined(__x86)
1075 /*
1076 * If cpr_resume_uniproc is set, then pause all the other cpus
1077 * apart from the current cpu, so that broken drivers that think
1078 * that they are on a uniprocessor machine will resume
1079 */
1080 if (cpr_resume_uniproc) {
1081 mutex_enter(&cpu_lock);
1082 pause_cpus(NULL, NULL);
1083 mutex_exit(&cpu_lock);
1084 }
1085 #endif
1086
1087 /*
1088 * The policy here is to continue resume everything we can if we did
1089 * not successfully finish suspend; and panic if we are coming back
1090 * from a fully suspended system.
1091 */
1092 PMD(PMD_SX, ("cpr_resume: resume devices\n"))
1093 rc = cpr_resume_devices(ddi_root_node(), 0);
1094
1095 cpr_sae(0);
1096
1097 str = "Failed to resume one or more devices.";
1098
1099 if (rc) {
1100 if (CPR->c_substate == C_ST_DUMP ||
1101 (sleeptype == CPR_TORAM &&
1102 CPR->c_substate == C_ST_NODUMP)) {
1103 if (cpr_test_point == FORCE_SUSPEND_TO_RAM) {
1104 PMD(PMD_SX, ("cpr_resume: resume device "
1105 "warn\n"))
1106 cpr_err(CE_WARN, str);
1107 } else {
1108 PMD(PMD_SX, ("cpr_resume: resume device "
1109 "panic\n"))
1110 cpr_err(CE_PANIC, str);
1111 }
1112 } else {
1113 PMD(PMD_SX, ("cpr_resume: resume device warn\n"))
1114 cpr_err(CE_WARN, str);
1115 }
1116 }
1117
1118 CPR_STAT_EVENT_END(" start drivers");
1119 CPR_DEBUG(CPR_DEBUG1, "done\n");
1120
1121 #if defined(__x86)
1122 /*
1123 * If cpr_resume_uniproc is set, then unpause all the processors
1124 * that were paused before resuming the drivers
1125 */
1126 if (cpr_resume_uniproc) {
1127 mutex_enter(&cpu_lock);
1128 start_cpus();
1129 mutex_exit(&cpu_lock);
1130 }
1131 #endif
1132
1133 /*
1134 * If we had disabled modunloading in this cpr resume cycle (i.e. we
1135 * resumed from a state earlier than C_ST_SUSPEND_DEVICES), re-enable
1136 * modunloading now.
1137 */
1138 if (CPR->c_substate != C_ST_SUSPEND_DEVICES) {
1139 PMD(PMD_SX, ("cpr_resume: modload enable\n"))
1140 modunload_enable();
1141 }
1142
1143 /*
1144 * Hooks needed by lock manager prior to resuming.
1145 * Refer to code for more comments.
1146 */
1147 PMD(PMD_SX, ("cpr_resume: lock mgr\n"))
1148 cpr_lock_mgr(lm_cprresume);
1149
1150 #if defined(__sparc)
1151 /*
1152 * This is a partial (half) resume during cpr suspend, we
1153 * haven't yet given up on the suspend. On return from here,
1154 * cpr_suspend() will try to reallocate and retry the suspend.
1155 */
1156 if (CPR->c_substate == C_ST_DUMP_NOSPC) {
1157 return (0);
1158 }
1159
1160 if (sleeptype == CPR_TODISK) {
1161 rb_statef_alloc:
1162 cpr_statef_close();
1163
1164 rb_disable_ufs_logging:
1165 /*
1166 * if ufs logging was disabled, re-enable
1167 */
1168 (void) cpr_ufs_logging(1);
1169 }
1170 #endif
1171
1172 rb_pm_reattach_noinvol:
1173 /*
1174 * When pm_reattach_noinvol() succeeds, modunload_thread will
1175 * remain disabled until after cpr suspend passes the
1176 * C_ST_STOP_KERNEL_THREADS state. If any failure happens before
1177 * cpr suspend reaches this state, we'll need to enable modunload
1178 * thread during rollback.
1179 */
1180 if (CPR->c_substate == C_ST_DISABLE_UFS_LOGGING ||
1181 CPR->c_substate == C_ST_STATEF_ALLOC ||
1182 CPR->c_substate == C_ST_SUSPEND_DEVICES ||
1183 CPR->c_substate == C_ST_STOP_KERNEL_THREADS) {
1184 PMD(PMD_SX, ("cpr_resume: reattach noinvol fini\n"))
1185 pm_reattach_noinvol_fini();
1186 }
1187
1188 PMD(PMD_SX, ("cpr_resume: CPR POST USER callback\n"))
1189 (void) callb_execute_class(CB_CL_CPR_POST_USER, CB_CODE_CPR_RESUME);
1190 PMD(PMD_SX, ("cpr_resume: CPR PROMPRINTF callback\n"))
1191 (void) callb_execute_class(CB_CL_CPR_PROMPRINTF, CB_CODE_CPR_RESUME);
1192
1193 PMD(PMD_SX, ("cpr_resume: restore direct levels\n"))
1194 pm_restore_direct_levels();
1195
1196 rb_stop_user_threads:
1197 CPR_DEBUG(CPR_DEBUG1, "starting user threads...");
1198 PMD(PMD_SX, ("cpr_resume: starting user threads\n"))
1199 cpr_start_user_threads();
1200 CPR_DEBUG(CPR_DEBUG1, "done\n");
1201 /*
1202 * Ask Xorg to resume the frame buffer, and wait for it to happen
1203 */
1204 mutex_enter(&srn_clone_lock);
1205 if (srn_signal) {
1206 PMD(PMD_SX, ("cpr_suspend: (*srn_signal)(..., "
1207 "SRN_NORMAL_RESUME)\n"))
1208 srn_inuse = 1; /* because (*srn_signal) cv_waits */
1209 (*srn_signal)(SRN_TYPE_APM, SRN_NORMAL_RESUME);
1210 srn_inuse = 0;
1211 } else {
1212 PMD(PMD_SX, ("cpr_suspend: srn_signal NULL\n"))
1213 }
1214 mutex_exit(&srn_clone_lock);
1215
1216 #if defined(__sparc)
1217 rb_mp_offline:
1218 if (cpr_mp_online())
1219 cpr_err(CE_WARN, "Failed to online all the processors.");
1220 #endif
1221
1222 rb_others:
1223 PMD(PMD_SX, ("cpr_resume: dep thread\n"))
1224 pm_dispatch_to_dep_thread(PM_DEP_WK_CPR_RESUME, NULL, NULL,
1225 PM_DEP_WAIT, NULL, 0);
1226
1227 PMD(PMD_SX, ("cpr_resume: CPR PM callback\n"))
1228 (void) callb_execute_class(CB_CL_CPR_PM, CB_CODE_CPR_RESUME);
1229
1230 if (cpr_suspend_succeeded) {
1231 cpr_stat_record_events();
1232 }
1233
1234 #if defined(__sparc)
1235 if (sleeptype == CPR_TODISK && !cpr_reusable_mode)
1236 cpr_clear_definfo();
1237 #endif
1238
1239 i_cpr_free_cpus();
1240 CPR_DEBUG(CPR_DEBUG1, "Sending SIGTHAW...");
1241 PMD(PMD_SX, ("cpr_resume: SIGTHAW\n"))
1242 cpr_signal_user(SIGTHAW);
1243 CPR_DEBUG(CPR_DEBUG1, "done\n");
1244
1245 CPR_STAT_EVENT_END("Resume Total");
1246
1247 CPR_STAT_EVENT_START_TMZ("WHOLE CYCLE", &wholecycle_tv);
1248 CPR_STAT_EVENT_END("WHOLE CYCLE");
1249
1250 if (cpr_debug & CPR_DEBUG1)
1251 cmn_err(CE_CONT, "\nThe system is back where you left!\n");
1252
1253 CPR_STAT_EVENT_START("POST CPR DELAY");
1254
1255 #ifdef CPR_STAT
1256 ctp = &cpr_term.tm_shutdown;
1257 CPR_STAT_EVENT_START_TMZ("PWROFF TIME", ctp);
1258 CPR_STAT_EVENT_END_TMZ("PWROFF TIME", &pwron_tv);
1259
1260 CPR_STAT_EVENT_PRINT();
1261 #endif /* CPR_STAT */
1262
1263 PMD(PMD_SX, ("cpr_resume returns %x\n", rc))
1264 return (rc);
1265 }
1266
1267 static void
cpr_suspend_init(int sleeptype)1268 cpr_suspend_init(int sleeptype)
1269 {
1270 cpr_time_t *ctp;
1271
1272 cpr_stat_init();
1273
1274 /*
1275 * If cpr_suspend() failed before cpr_dump() gets a chance
1276 * to reinitialize the terminator of the statefile,
1277 * the values of the old terminator will still linger around.
1278 * Since the terminator contains information that we need to
1279 * decide whether suspend succeeded or not, we need to
1280 * reinitialize it as early as possible.
1281 */
1282 cpr_term.real_statef_size = 0;
1283 ctp = &cpr_term.tm_shutdown;
1284 bzero(ctp, sizeof (*ctp));
1285 ctp = &cpr_term.tm_cprboot_start;
1286 bzero(ctp, sizeof (*ctp));
1287 ctp = &cpr_term.tm_cprboot_end;
1288 bzero(ctp, sizeof (*ctp));
1289
1290 if (sleeptype == CPR_TODISK) {
1291 /*
1292 * Lookup the physical address of our thread structure.
1293 * This should never be invalid and the entire thread structure
1294 * is expected to reside within the same pfn.
1295 */
1296 curthreadpfn = hat_getpfnum(kas.a_hat, (caddr_t)curthread);
1297 ASSERT(curthreadpfn != PFN_INVALID);
1298 ASSERT(curthreadpfn == hat_getpfnum(kas.a_hat,
1299 (caddr_t)curthread + sizeof (kthread_t) - 1));
1300 }
1301
1302 cpr_suspend_succeeded = 0;
1303 }
1304
1305 /*
1306 * bring all the offline cpus online
1307 */
1308 static int
cpr_all_online(void)1309 cpr_all_online(void)
1310 {
1311 int rc = 0;
1312
1313 #ifdef __sparc
1314 /*
1315 * do nothing
1316 */
1317 #else
1318
1319 cpu_t *cp;
1320
1321 ASSERT(MUTEX_HELD(&cpu_lock));
1322
1323 cp = cpu_list;
1324 do {
1325 cp->cpu_cpr_flags &= ~CPU_CPR_ONLINE;
1326 if (!CPU_ACTIVE(cp)) {
1327 if ((rc = cpu_online(cp)) != 0)
1328 break;
1329 CPU_SET_CPR_FLAGS(cp, CPU_CPR_ONLINE);
1330 }
1331 } while ((cp = cp->cpu_next) != cpu_list);
1332
1333 if (rc) {
1334 /*
1335 * an online operation failed so offline the cpus
1336 * that were onlined above to restore the system
1337 * to its original state
1338 */
1339 cpr_restore_offline();
1340 }
1341 #endif
1342 return (rc);
1343 }
1344
1345 /*
1346 * offline all the cpus that were brought online by cpr_all_online()
1347 */
1348 static void
cpr_restore_offline(void)1349 cpr_restore_offline(void)
1350 {
1351
1352 #ifdef __sparc
1353 /*
1354 * do nothing
1355 */
1356 #else
1357
1358 cpu_t *cp;
1359 int rc = 0;
1360
1361 ASSERT(MUTEX_HELD(&cpu_lock));
1362
1363 cp = cpu_list;
1364 do {
1365 if (CPU_CPR_IS_ONLINE(cp)) {
1366 rc = cpu_offline(cp, 0);
1367 /*
1368 * this offline should work, since the cpu was
1369 * offline originally and was successfully onlined
1370 * by cpr_all_online()
1371 */
1372 ASSERT(rc == 0);
1373 cp->cpu_cpr_flags &= ~CPU_CPR_ONLINE;
1374 }
1375 } while ((cp = cp->cpu_next) != cpu_list);
1376
1377 #endif
1378
1379 }
1380