changeset 3676:4975133d76f2

6521026 panic: assertion failed: bitset_is_null(&pp->cp_cmt_pgs) 6521502 6461311 didn't do enough for mc-amd 6522133 opl needs updated PG definitions 6523011 panic during CPU unconfigure on null_proc_lpa 15k config
author esaxe
date Sun, 18 Feb 2007 22:37:35 -0800
parents 6f06fd354fd3
children b34b45f03271
files usr/src/uts/common/disp/cmt.c usr/src/uts/common/os/lgrp.c usr/src/uts/common/os/pg.c usr/src/uts/i86pc/io/mc/mcamd.h usr/src/uts/i86pc/io/mc/mcamd_drv.c usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c usr/src/uts/i86pc/io/mc/mcamd_subr.c usr/src/uts/sun4u/os/cmp.c
diffstat 8 files changed, 151 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/disp/cmt.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/common/disp/cmt.c	Sun Feb 18 22:37:35 2007 -0800
@@ -89,9 +89,16 @@
 	struct cmt_lgrp *cl_next;	/* next cmt_lgrp */
 } cmt_lgrp_t;
 
-static cmt_lgrp_t	*cmt_lgrps = NULL;
+static cmt_lgrp_t	*cmt_lgrps = NULL;	/* cmt_lgrps list head */
+static cmt_lgrp_t	*cpu0_lgrp = NULL;	/* boot CPU's initial lgrp */
+						/* used for null_proc_lpa */
 
-static int		is_cpu0 = 1;
+static int		is_cpu0 = 1; /* true if this is boot CPU context */
+
+/*
+ * Set this to non-zero to disable CMT scheduling
+ * This must be done via kmdb -d, as /etc/system will be too late
+ */
 static int		cmt_sched_disabled = 0;
 
 static pg_cid_t		pg_cmt_class_id;		/* PG class id */
@@ -108,6 +115,7 @@
 static int		pg_cmt_cpu_belongs(pg_t *, cpu_t *);
 static int		pg_cmt_hw(pghw_type_t);
 static cmt_lgrp_t	*pg_cmt_find_lgrp(lgrp_handle_t);
+static cmt_lgrp_t	*pg_cmt_lgrp_create(lgrp_handle_t);
 
 /*
  * Macro to test if PG is managed by the CMT PG class
@@ -364,6 +372,8 @@
 	 */
 	lgrp_handle = lgrp_plat_cpu_to_hand(cp->cpu_id);
 	lgrp = pg_cmt_find_lgrp(lgrp_handle);
+	if (lgrp == NULL)
+		lgrp = pg_cmt_lgrp_create(lgrp_handle);
 
 	for (level = 0; level < nlevels; level++) {
 		uint_t		children;
@@ -430,6 +440,7 @@
 	if (is_cpu0) {
 		pg_cmt_cpu_startup(cp);
 		is_cpu0 = 0;
+		cpu0_lgrp = lgrp;
 	}
 
 }
@@ -453,7 +464,20 @@
 	 * Find the lgroup that encapsulates this CPU's CMT hierarchy
 	 */
 	lgrp_handle = lgrp_plat_cpu_to_hand(cp->cpu_id);
+
 	lgrp = pg_cmt_find_lgrp(lgrp_handle);
+	if (lgrp == NULL) {
+		/*
+		 * This is a bit of a special case.
+		 * The only way this can happen is if the CPU's lgrp
+		 * handle changed out from underneath us, which is what
+		 * happens with null_proc_lpa on starcat systems.
+		 *
+		 * Use the initial boot CPU lgrp, since this is what
+		 * we need to tear down.
+		 */
+		lgrp = cpu0_lgrp;
+	}
 
 	/*
 	 * First, clean up anything load balancing specific for each of
@@ -589,7 +613,8 @@
 		while ((cpp = pg_cpu_next(&cpu_iter)) != NULL) {
 			if (cpp == cp)
 				continue;
-			if (cpp->cpu_part->cp_id == oldpp->cp_id) {
+			if (CPU_ACTIVE(cpp) &&
+			    cpp->cpu_part->cp_id == oldpp->cp_id) {
 				found = B_TRUE;
 				break;
 			}
@@ -710,7 +735,8 @@
 		while ((cpp = pg_cpu_next(&cpu_itr)) != NULL) {
 			if (cpp == cp)
 				continue;
-			if (cpp->cpu_part->cp_id == cp->cpu_part->cp_id) {
+			if (CPU_ACTIVE(cpp) &&
+			    cpp->cpu_part->cp_id == cp->cpu_part->cp_id) {
 				found = B_TRUE;
 				break;
 			}
@@ -772,8 +798,6 @@
 
 /*
  * Return a cmt_lgrp_t * given an lgroup handle.
- * If the right one doesn't yet exist, create one
- * by growing the cmt_lgrps array
  */
 static cmt_lgrp_t *
 pg_cmt_find_lgrp(lgrp_handle_t hand)
@@ -785,13 +809,22 @@
 	lgrp = cmt_lgrps;
 	while (lgrp != NULL) {
 		if (lgrp->cl_hand == hand)
-			return (lgrp);
+			break;
 		lgrp = lgrp->cl_next;
 	}
+	return (lgrp);
+}
 
-	/*
-	 * Haven't seen this lgrp yet
-	 */
+/*
+ * Create a cmt_lgrp_t with the specified handle.
+ */
+static cmt_lgrp_t *
+pg_cmt_lgrp_create(lgrp_handle_t hand)
+{
+	cmt_lgrp_t	*lgrp;
+
+	ASSERT(MUTEX_HELD(&cpu_lock));
+
 	lgrp = kmem_zalloc(sizeof (cmt_lgrp_t), KM_SLEEP);
 
 	lgrp->cl_hand = hand;
--- a/usr/src/uts/common/os/lgrp.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/common/os/lgrp.c	Sun Feb 18 22:37:35 2007 -0800
@@ -404,6 +404,8 @@
 	cpu_t		*cp = CPU;
 	lgrp_id_t	lgrpid;
 	int		i;
+	extern void	pg_cpu0_reinit();
+
 	/*
 	 * Enforce a valid lgrp_mem_default_policy
 	 */
@@ -434,6 +436,12 @@
 		ASSERT(cp->cpu_lpl->lpl_lgrpid == LGRP_ROOTID);
 
 		/*
+		 * Notify the PG subsystem that the CPU's lgrp
+		 * association has changed
+		 */
+		pg_cpu0_reinit();
+
+		/*
 		 * Destroy all lgroups except for root
 		 */
 		for (i = 0; i <= lgrp_alloc_max; i++) {
--- a/usr/src/uts/common/os/pg.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/common/os/pg.c	Sun Feb 18 22:37:35 2007 -0800
@@ -241,6 +241,27 @@
 }
 
 /*
+ * Invoked when topology for CPU0 changes
+ * post pg_cpu0_init().
+ *
+ * Currently happens as a result of null_proc_lpa
+ * on Starcat.
+ */
+void
+pg_cpu0_reinit(void)
+{
+	mutex_enter(&cpu_lock);
+	pg_cpu_inactive(CPU);
+	pg_cpupart_out(CPU, &cp_default);
+	pg_cpu_fini(CPU);
+
+	pg_cpu_init(CPU);
+	pg_cpupart_in(CPU, &cp_default);
+	pg_cpu_active(CPU);
+	mutex_exit(&cpu_lock);
+}
+
+/*
  * Register a new PG class
  */
 pg_cid_t
--- a/usr/src/uts/i86pc/io/mc/mcamd.h	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/i86pc/io/mc/mcamd.h	Sun Feb 18 22:37:35 2007 -0800
@@ -32,7 +32,6 @@
 #include <sys/types.h>
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
-#include <sys/pghw.h>
 #include <sys/ksynch.h>
 #include <sys/mc_amd.h>
 #include <mcamd_api.h>
@@ -234,7 +233,6 @@
 	uint32_t mc_socket;			/* Package type */
 	uint_t mc_ref;				/* reference (attach) count */
 	mc_func_t mc_funcs[MC_FUNC_NUM];	/* Instance, devinfo, ... */
-	pghw_t *mc_chip;			/* MC's associated chip PG */
 	mc_cs_t *mc_cslist;			/* All active chip-selects */
 	mc_cs_t *mc_cslast;			/* End of chip-select list */
 	mc_dimm_t *mc_dimmlist;			/* List of all logical DIMMs, */
--- a/usr/src/uts/i86pc/io/mc/mcamd_drv.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/i86pc/io/mc/mcamd_drv.c	Sun Feb 18 22:37:35 2007 -0800
@@ -110,7 +110,7 @@
 	ASSERT(RW_LOCK_HELD(&mc_lock));
 
 	for (mc = mc_list; mc != NULL; mc = mc->mc_next) {
-		if (mc->mc_chip->pghw_instance == chipid)
+		if (mc->mc_props.mcp_num  == chipid)
 			return (mc);
 	}
 
@@ -595,7 +595,7 @@
 	for (mccs = mc->mc_cslist; mccs != NULL; mccs = mccs->mccs_next) {
 		if (mccs->mccs_props.csp_testfail) {
 			unum.unum_board = 0;
-			unum.unum_chip = mc->mc_chip->pghw_instance;
+			unum.unum_chip = mc->mc_props.mcp_num;
 			unum.unum_mc = 0;
 			unum.unum_cs = mccs->mccs_props.csp_num;
 			unum.unum_rank = mccs->mccs_props.csp_dimmrank;
@@ -671,8 +671,7 @@
 		 * is the HT id this loop and the preceding read of all
 		 * base/limit pairs is overkill.
 		 */
-		if (MCREG_FIELD_CMN(&lim[i], DstNode) !=
-		    mc->mc_chip->pghw_instance)
+		if (MCREG_FIELD_CMN(&lim[i], DstNode) != mc->mc_props.mcp_num)
 			continue;
 
 		/*
@@ -1272,31 +1271,46 @@
 static mc_t *
 mc_create(chipid_t chipid)
 {
-	pghw_t *chp = pghw_find_by_instance((id_t)chipid, PGHW_CHIP);
 	mc_t *mc;
 	cpu_t *cpu;
 
 	ASSERT(RW_WRITE_HELD(&mc_lock));
 
-	if (chp == NULL)
-		return (NULL);
+	mc = kmem_zalloc(sizeof (mc_t), KM_SLEEP);
 
-	mc = kmem_zalloc(sizeof (mc_t), KM_SLEEP);
+	/*
+	 * Find one of a chip's CPU.
+	 *
+	 * We can use one of the chip's CPUs since all cores
+	 * of a chip share the same revision and socket type.
+	 */
+	kpreempt_disable();
+	cpu = cpu_list;
+	do {
+		if (cpuid_get_chipid(cpu) == chipid)
+			break;
+	} while ((cpu = cpu->cpu_next) != cpu_list);
+
+	if (cpuid_get_chipid(cpu) != chipid) {
+		/*
+		 * Couldn't find a cpu with the specified chipid
+		 */
+		kpreempt_enable();
+		kmem_free(mc, sizeof (mc_t));
+		return (NULL);
+	}
+
 	mc->mc_hdr.mch_type = MC_NT_MC;
-	mc->mc_chip = chp;
-	mc->mc_props.mcp_num = mc->mc_chip->pghw_instance;
+	mc->mc_props.mcp_num = chipid;
 	mc->mc_props.mcp_sparecs = MC_INVALNUM;
 	mc->mc_props.mcp_badcs = MC_INVALNUM;
 
-	/*
-	 * We can use one of the chip's CPUs since all cores
-	 * of a chip share the same revision and socket type.
-	 */
-	cpu = PG_CPU_GET_FIRST(chp);
 	mc->mc_props.mcp_rev = cpuid_getchiprev(cpu);
 	mc->mc_revname = cpuid_getchiprevstr(cpu);
 	mc->mc_socket = cpuid_getsockettype(cpu);
 
+	kpreempt_enable();
+
 	if (mc_list == NULL)
 		mc_list = mc;
 	if (mc_last != NULL)
@@ -1364,7 +1378,7 @@
 	rw_enter(&mc_lock, RW_WRITER);
 
 	for (mc = mc_list; mc != NULL; mc = mc->mc_next) {
-		if (mc->mc_chip->pghw_instance == chipid)
+		if (mc->mc_props.mcp_num == chipid)
 			break;
 	}
 
@@ -1407,7 +1421,7 @@
 	    dip, "model", (char *)bm->bm_model);
 
 	(void) ddi_prop_update_int(DDI_DEV_T_NONE,
-	    dip, "chip-id", mc->mc_chip->pghw_instance);
+	    dip, "chip-id", mc->mc_props.mcp_num);
 
 	if (bm->bm_mkprops != NULL &&
 	    mc_pcicfg_setup(mc, bm->bm_func, &cfghdl) == DDI_SUCCESS) {
@@ -1424,14 +1438,15 @@
 		mc_props_t *mcp = &mc->mc_props;
 		int dram_present = 0;
 		pg_cpu_itr_t itr;
+		pghw_t *chp;
 		cpu_t *cpup;
 
 		if (ddi_create_minor_node(dip, "mc-amd", S_IFCHR,
-		    mc->mc_chip->pghw_instance, "ddi_mem_ctrl",
+		    mc->mc_props.mcp_num, "ddi_mem_ctrl",
 		    0) != DDI_SUCCESS) {
 			cmn_err(CE_WARN, "failed to create minor node for chip "
-			    "%u memory controller\n",
-			    mc->mc_chip->pghw_instance);
+			    "%d memory controller\n",
+			    (chipid_t)mc->mc_props.mcp_num);
 		}
 
 		/*
@@ -1446,11 +1461,31 @@
 		 */
 		kpreempt_disable();	/* prevent cpu list from changing */
 
-		PG_CPU_ITR_INIT(mc->mc_chip, itr);
-		cpup = cpu = pg_cpu_next(&itr);
-		do {
-			mcamd_mc_register(cpup);
-		} while ((cpup = pg_cpu_next(&itr)) != NULL);
+		chp = pghw_find_by_instance(mc->mc_props.mcp_num, PGHW_CHIP);
+		if (chp == NULL) {
+			/*
+			 * No chip grouping was found (single core processors).
+			 * Find the CPU to register by searching the CPU list.
+			 */
+			cpu = cpu_list;
+			do {
+				if (cpuid_get_chipid(cpu) ==
+				    mc->mc_props.mcp_num)
+					break;
+			} while ((cpu = cpu->cpu_next) != cpu_list);
+			ASSERT(cpuid_get_chipid(cpu) == mc->mc_props.mcp_num);
+
+			mcamd_mc_register(cpu);
+		} else {
+			/*
+			 * Iterate over / register the chip's CPUs
+			 */
+			PG_CPU_ITR_INIT(chp, itr);
+			cpup = cpu = pg_cpu_next(&itr);
+			do {
+				mcamd_mc_register(cpup);
+			} while ((cpup = pg_cpu_next(&itr)) != NULL);
+		}
 
 		if (mc->mc_props.mcp_lim != mc->mc_props.mcp_base) {
 			/*
--- a/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c	Sun Feb 18 22:37:35 2007 -0800
@@ -87,7 +87,7 @@
 mc_pcicfg_get32_nohdl(mc_t *mc, enum mc_funcnum func, off_t offset)
 {
 	return (pci_mech1_getl(0,
-		    MC_AMD_DEV_OFFSET + mc->mc_chip->pghw_instance,
+		    MC_AMD_DEV_OFFSET + mc->mc_props.mcp_num,
 		    func, offset));
 }
 
@@ -96,6 +96,6 @@
     uint32_t val)
 {
 	pci_mech1_putl(0,
-	    MC_AMD_DEV_OFFSET + mc->mc_chip->pghw_instance,
+	    MC_AMD_DEV_OFFSET + mc->mc_props.mcp_num,
 	    func, offset, val);
 }
--- a/usr/src/uts/i86pc/io/mc/mcamd_subr.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/i86pc/io/mc/mcamd_subr.c	Sun Feb 18 22:37:35 2007 -0800
@@ -617,7 +617,7 @@
 
 	fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
 	    "motherboard", 0,
-	    "chip", mc->mc_chip->pghw_instance,
+	    "chip", mc->mc_props.mcp_num,
 	    "memory-controller", 0);
 
 	return (nvl);
--- a/usr/src/uts/sun4u/os/cmp.c	Sun Feb 18 20:01:00 2007 -0800
+++ b/usr/src/uts/sun4u/os/cmp.c	Sun Feb 18 22:37:35 2007 -0800
@@ -155,11 +155,11 @@
 			return (1);
 		break;
 	case PGHW_CHIP:
-		if (IS_JAGUAR(impl) || IS_PANTHER(impl))
+		if (IS_JAGUAR(impl) || IS_PANTHER(impl) || IS_OLYMPUS_C(impl))
 			return (1);
 		break;
 	case PGHW_CACHE:
-		if (IS_PANTHER(impl))
+		if (IS_PANTHER(impl) || IS_OLYMPUS_C(impl))
 			return (1);
 		break;
 	}
@@ -169,10 +169,9 @@
 int
 pg_plat_cpus_share(cpu_t *cpu_a, cpu_t *cpu_b, pghw_type_t hw)
 {
-	int impla, implb;
+	int impl;
 
-	impla = cpunodes[cpu_a->cpu_id].implementation;
-	implb = cpunodes[cpu_b->cpu_id].implementation;
+	impl = cpunodes[cpu_a->cpu_id].implementation;
 
 	switch (hw) {
 	case PGHW_IPIPE:
@@ -180,8 +179,12 @@
 		return (pg_plat_hw_instance_id(cpu_a, hw) ==
 		    pg_plat_hw_instance_id(cpu_b, hw));
 	case PGHW_CACHE:
-		return (IS_PANTHER(impla) && IS_PANTHER(implb) &&
-		    pg_plat_cpus_share(cpu_a, cpu_b, PGHW_CHIP));
+		if ((IS_PANTHER(impl) || IS_OLYMPUS_C(impl)) &&
+		    pg_plat_cpus_share(cpu_a, cpu_b, PGHW_CHIP)) {
+			return (1);
+		} else {
+			return (0);
+		}
 	}
 	return (0);
 }
@@ -191,10 +194,10 @@
 {
 	int impl;
 
+	impl = cpunodes[cpu->cpu_id].implementation;
+
 	switch (hw) {
 	case PGHW_IPIPE:
-		impl = cpunodes[cpu->cpu_id].implementation;
-
 		if (IS_OLYMPUS_C(impl)) {
 			/*
 			 * Currently only Fujitsu Olympus-c processor supports
@@ -208,8 +211,10 @@
 	case PGHW_CHIP:
 		return (cmp_cpu_to_chip(cpu->cpu_id));
 	case PGHW_CACHE:
-		return (IS_PANTHER(impl) &&
-		    pg_plat_hw_instance_id(cpu, PGHW_CHIP));
+		if (IS_PANTHER(impl) || IS_OLYMPUS_C(impl))
+			return (pg_plat_hw_instance_id(cpu, PGHW_CHIP));
+		else
+			return (cpu->cpu_id);
 	default:
 		return (-1);
 	}