changeset 12994:a2d5e2db1c76

6942564 BAD TRAP occurs when halting a zone stuck in 'down' state 6856797 kstat unix:0:system_misc:nproc not zone aware
author Vamsi Nagineni <Vamsi.Krishna@Sun.COM>
date Sun, 01 Aug 2010 21:50:54 -0700
parents 2ec828581df0
children 03e7109ccca0
files usr/src/uts/common/os/acct.c usr/src/uts/common/os/exacct.c usr/src/uts/common/os/kstat_fr.c
diffstat 3 files changed, 26 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/acct.c	Mon Aug 02 11:09:26 2010 +0800
+++ b/usr/src/uts/common/os/acct.c	Sun Aug 01 21:50:54 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
@@ -385,7 +384,13 @@
 	int error;
 	struct acct_globals *ag;
 
+	/*
+	 * If sysacct module is loaded when zone is in down state then
+	 * the following function can return NULL.
+	 */
 	ag = zone_getspecific(acct_zone_key, curproc->p_zone);
+	if (ag == NULL)
+		return;
 
 	mutex_enter(&ag->aclock);
 	if ((vp = ag->acctvp) == NULL) {
--- a/usr/src/uts/common/os/exacct.c	Mon Aug 02 11:09:26 2010 +0800
+++ b/usr/src/uts/common/os/exacct.c	Sun Aug 01 21:50:54 2010 -0700
@@ -720,9 +720,13 @@
 
 	/*
 	 * Don't do any extra work if the acctctl module isn't loaded.
+	 * If acctctl module is loaded when zone is in down state then
+	 * zone_getspecific can return NULL for that zone.
 	 */
 	if (exacct_zone_key != ZONE_KEY_UNINITIALIZED) {
 		acg = zone_getspecific(exacct_zone_key, zone);
+		if (acg == NULL)
+			goto err;
 		(void) exacct_assemble_task_usage(&acg->ac_task, tk,
 		    exacct_commit_callback, NULL, 0, &size, EW_FINAL);
 		if (tk->tk_zone != global_zone) {
@@ -734,6 +738,7 @@
 	/*
 	 * Release associated project and finalize task.
 	 */
+err:
 	task_end(tk);
 }
 
@@ -1151,7 +1156,14 @@
 		 */
 		return;
 	}
+
+	/*
+	 * If acctctl module is loaded when zone is in down state then
+	 * zone_getspecific can return NULL for that zone.
+	 */
 	acg = zone_getspecific(exacct_zone_key, zone);
+	if (acg == NULL)
+		return;
 	exacct_do_commit_proc(&acg->ac_proc, p, wstat);
 	if (zone != global_zone) {
 		gacg = zone_getspecific(exacct_zone_key, global_zone);
--- a/usr/src/uts/common/os/kstat_fr.c	Mon Aug 02 11:09:26 2010 +0800
+++ b/usr/src/uts/common/os/kstat_fr.c	Sun Aug 01 21:50:54 2010 -0700
@@ -807,6 +807,7 @@
 	time_t zone_boot_time;
 	clock_t zone_lbolt;
 	hrtime_t zone_hrtime;
+	size_t zone_nproc;
 
 	if (rw == KSTAT_WRITE)
 		return (EACCES);
@@ -832,9 +833,10 @@
 		mutex_exit(&cpu_lock);
 	}
 
-	if (curproc->p_zone->zone_id == 0) {
+	if (INGLOBALZONE(curproc)) {
 		zone_boot_time = boot_time;
 		zone_lbolt = ddi_get_lbolt();
+		zone_nproc = nproc;
 	} else {
 		struct timeval tvp;
 		hrt2tv(curproc->p_zone->zone_zsched->p_mstart, &tvp);
@@ -843,6 +845,9 @@
 		zone_hrtime = gethrtime();
 		zone_lbolt = (clock_t)(NSEC_TO_TICK(zone_hrtime) -
 		    NSEC_TO_TICK(curproc->p_zone->zone_zsched->p_mstart));
+		mutex_enter(&curproc->p_zone->zone_nlwps_lock);
+		zone_nproc = curproc->p_zone->zone_nprocs;
+		mutex_exit(&curproc->p_zone->zone_nlwps_lock);
 	}
 
 	system_misc_kstat.ncpus.value.ui32		= (uint32_t)myncpus;
@@ -850,7 +855,7 @@
 	system_misc_kstat.deficit.value.ui32		= (uint32_t)deficit;
 	system_misc_kstat.clk_intr.value.ui32		= (uint32_t)zone_lbolt;
 	system_misc_kstat.vac.value.ui32		= (uint32_t)vac;
-	system_misc_kstat.nproc.value.ui32		= (uint32_t)nproc;
+	system_misc_kstat.nproc.value.ui32		= (uint32_t)zone_nproc;
 	system_misc_kstat.avenrun_1min.value.ui32	= (uint32_t)loadavgp[0];
 	system_misc_kstat.avenrun_5min.value.ui32	= (uint32_t)loadavgp[1];
 	system_misc_kstat.avenrun_15min.value.ui32	= (uint32_t)loadavgp[2];