xref: /titanic_44/usr/src/uts/common/cpr/cpr_main.c (revision 0ed5c46e82c989cfa9726d9dae452e3d24ef83be)
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