changeset 12943:2acab560865a

6967825 panic "sync initiated" can hang attempting a crash dump
author Dave Plauger <Dave.Plauger@Sun.COM>
date Wed, 28 Jul 2010 12:25:47 -0400
parents e50abc8ca9fa
children f73b349ded5b
files usr/src/uts/common/os/dumpsubr.c usr/src/uts/common/sys/dumphdr.h usr/src/uts/i86pc/os/machdep.c usr/src/uts/sun4/os/machdep.c usr/src/uts/sun4/os/startup.c usr/src/uts/sun4u/opl/os/opl.c
diffstat 6 files changed, 48 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/dumpsubr.c	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/common/os/dumpsubr.c	Wed Jul 28 12:25:47 2010 -0400
@@ -130,6 +130,10 @@
 uint_t dump_ncpu_low = 4;	/* minimum config for parallel lzjb */
 uint_t dump_bzip2_level = 1;	/* bzip2 level (1-9) */
 
+/* Use dump_plat_mincpu_default unless this variable is set by /etc/system */
+#define	MINCPU_NOT_SET	((uint_t)-1)
+uint_t dump_plat_mincpu = MINCPU_NOT_SET;
+
 /* tunables for pre-reserved heap */
 uint_t dump_kmem_permap = 1024;
 uint_t dump_kmem_pages = 8;
@@ -401,6 +405,7 @@
 	char	*maxvm;		/* reserved VM for spare pages */
 	lock_t	helper_lock;	/* protect helper state */
 	char	helpers_wanted;	/* flag to enable parallelism */
+	char	helper_present;	/* at least one helper showed up */
 } dumpcfg_t;
 
 static dumpcfg_t dumpcfg;	/* config vars */
@@ -583,6 +588,10 @@
 	if (new->nhelper > DUMP_MAX_NHELPER)
 		new->nhelper = DUMP_MAX_NHELPER;
 
+	/* use platform default, unless /etc/system overrides */
+	if (dump_plat_mincpu == MINCPU_NOT_SET)
+		dump_plat_mincpu = dump_plat_mincpu_default;
+
 	/* increase threshold for faster disks */
 	new->threshold = dump_plat_mincpu;
 	if (dumpbuf.iosize >= DUMP_1MB)
@@ -866,6 +875,25 @@
 	dumpmlw_t mlw;
 	int k;
 
+	/*
+	 * Fall back to doing a serial dump if no helpers showed
+	 * up. It is possible for other CPUs to be stuck in PROM, or
+	 * DRd out. panic("sync initiated") in sync_handler() is one
+	 * case. A parallel dump will hang (dump time out) unless
+	 * there is at least one helper CPU. At this point dumpsys()
+	 * has done some I/O, which means there has been plenty of
+	 * time for helpers to arrive.
+	 */
+	if (!cfg->helper_present) {
+		cfg->clevel = 0;
+		return;
+	}
+
+	/*
+	 * There may be no point in looking for spare memory. If
+	 * dumping all memory, then none is spare. If doing a serial
+	 * dump, then already have buffers.
+	 */
 	if (cfg->maxsize == 0 || cfg->clevel < DUMP_CLEVEL_LZJB ||
 	    (dump_conflags & DUMP_ALL) != 0) {
 		if (cfg->clevel > DUMP_CLEVEL_LZJB)
@@ -2109,6 +2137,8 @@
 void
 dumpsys_helper()
 {
+	if (!dumpcfg.helper_present)
+		dumpcfg.helper_present = 1;
 	dumpsys_spinlock(&dumpcfg.helper_lock);
 	if (dumpcfg.helpers_wanted) {
 		helper_t *hp, *hpend = &dumpcfg.helper[dumpcfg.nhelper];
@@ -2147,6 +2177,8 @@
 void
 dumpsys_helper_nw()
 {
+	if (!dumpcfg.helper_present)
+		dumpcfg.helper_present = 1;
 	if (dumpcfg.helpers_wanted)
 		dumpsys_helper();
 }
--- a/usr/src/uts/common/sys/dumphdr.h	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/common/sys/dumphdr.h	Wed Jul 28 12:25:47 2010 -0400
@@ -193,11 +193,9 @@
 
 /*
  * Define a CPU count threshold that determines when to employ
- * bzip2. The values are defined per-platform in dump_plat_mincpu, and
- * may be changed with /etc/system. The value 0 disables parallelism,
- * and the old format dump is produced.
+ * bzip2. This value is defined per-platform.
  */
-extern uint_t dump_plat_mincpu;
+extern uint_t dump_plat_mincpu_default;
 
 #define	DUMP_PLAT_SUN4U_MINCPU		51
 #define	DUMP_PLAT_SUN4U_OPL_MINCPU	8
@@ -206,6 +204,13 @@
 #define	DUMP_PLAT_X86_32_MINCPU		0
 
 /*
+ * Override the per-platform default by setting this variable with
+ * /etc/system.  The value 0 disables parallelism, and the old format
+ * dump is produced.
+ */
+extern uint_t dump_plat_mincpu;
+
+/*
  * Pages may be stolen at dump time. Prevent the pages from ever being
  * allocated while dump is running.
  */
--- a/usr/src/uts/i86pc/os/machdep.c	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/i86pc/os/machdep.c	Wed Jul 28 12:25:47 2010 -0400
@@ -1226,9 +1226,9 @@
 
 /* cpu threshold for compressed dumps */
 #ifdef _LP64
-uint_t dump_plat_mincpu = DUMP_PLAT_X86_64_MINCPU;
+uint_t dump_plat_mincpu_default = DUMP_PLAT_X86_64_MINCPU;
 #else
-uint_t dump_plat_mincpu = DUMP_PLAT_X86_32_MINCPU;
+uint_t dump_plat_mincpu_default = DUMP_PLAT_X86_32_MINCPU;
 #endif
 
 int
--- a/usr/src/uts/sun4/os/machdep.c	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/sun4/os/machdep.c	Wed Jul 28 12:25:47 2010 -0400
@@ -831,9 +831,9 @@
 
 /* cpu threshold for compressed dumps */
 #ifdef sun4v
-uint_t dump_plat_mincpu = DUMP_PLAT_SUN4V_MINCPU;
+uint_t dump_plat_mincpu_default = DUMP_PLAT_SUN4V_MINCPU;
 #else
-uint_t dump_plat_mincpu = DUMP_PLAT_SUN4U_MINCPU;
+uint_t dump_plat_mincpu_default = DUMP_PLAT_SUN4U_MINCPU;
 #endif
 
 int
--- a/usr/src/uts/sun4/os/startup.c	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/sun4/os/startup.c	Wed Jul 28 12:25:47 2010 -0400
@@ -1497,8 +1497,7 @@
 	size_t hme8blk_sz, hme1blk_sz;
 
 	/*
-	 * Let the platforms have a chance to change default
-	 * values before reading system file.
+	 * The system file /etc/system was read already under startup_memlist.
 	 */
 	if (&set_platform_defaults)
 		set_platform_defaults();
--- a/usr/src/uts/sun4u/opl/os/opl.c	Wed Jul 28 16:37:44 2010 +0100
+++ b/usr/src/uts/sun4u/opl/os/opl.c	Wed Jul 28 12:25:47 2010 -0400
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/cpuvar.h>
@@ -224,7 +223,7 @@
 	set_max_mmu_ctxdoms();
 
 	/* set OPL threshold for compressed dumps */
-	dump_plat_mincpu = DUMP_PLAT_SUN4U_OPL_MINCPU;
+	dump_plat_mincpu_default = DUMP_PLAT_SUN4U_OPL_MINCPU;
 }
 
 /*