summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/disp/cmt.c53
-rw-r--r--usr/src/uts/common/os/lgrp.c8
-rw-r--r--usr/src/uts/common/os/pg.c21
-rw-r--r--usr/src/uts/i86pc/io/mc/mcamd.h2
-rw-r--r--usr/src/uts/i86pc/io/mc/mcamd_drv.c83
-rw-r--r--usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c4
-rw-r--r--usr/src/uts/i86pc/io/mc/mcamd_subr.c2
-rw-r--r--usr/src/uts/sun4u/os/cmp.c27
8 files changed, 150 insertions, 50 deletions
diff --git a/usr/src/uts/common/disp/cmt.c b/usr/src/uts/common/disp/cmt.c
index 1bf0704346..31683ea096 100644
--- a/usr/src/uts/common/disp/cmt.c
+++ b/usr/src/uts/common/disp/cmt.c
@@ -89,9 +89,16 @@ typedef struct cmt_lgrp {
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 void pg_cmt_hier_pack(pg_cmt_t **, int);
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 @@ pg_cmt_cpu_init(cpu_t *cp)
*/
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 @@ pg_cmt_cpu_init(cpu_t *cp)
if (is_cpu0) {
pg_cmt_cpu_startup(cp);
is_cpu0 = 0;
+ cpu0_lgrp = lgrp;
}
}
@@ -453,7 +464,20 @@ pg_cmt_cpu_fini(cpu_t *cp)
* 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 @@ pg_cmt_cpupart_move(cpu_t *cp, cpupart_t *oldpp, cpupart_t *newpp)
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 @@ pg_cmt_cpu_inactive(cpu_t *cp)
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 @@ pg_cmt_hier_pack(pg_cmt_t *hier[], int sz)
/*
* 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 @@ pg_cmt_find_lgrp(lgrp_handle_t hand)
lgrp = cmt_lgrps;
while (lgrp != NULL) {
if (lgrp->cl_hand == hand)
- return (lgrp);
+ break;
lgrp = lgrp->cl_next;
}
+ return (lgrp);
+}
+
+/*
+ * 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));
- /*
- * Haven't seen this lgrp yet
- */
lgrp = kmem_zalloc(sizeof (cmt_lgrp_t), KM_SLEEP);
lgrp->cl_hand = hand;
diff --git a/usr/src/uts/common/os/lgrp.c b/usr/src/uts/common/os/lgrp.c
index 2007f7b158..346a57c82f 100644
--- a/usr/src/uts/common/os/lgrp.c
+++ b/usr/src/uts/common/os/lgrp.c
@@ -404,6 +404,8 @@ lgrp_main_init(void)
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 @@ lgrp_main_init(void)
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++) {
diff --git a/usr/src/uts/common/os/pg.c b/usr/src/uts/common/os/pg.c
index cb8295b38e..9bd15af43b 100644
--- a/usr/src/uts/common/os/pg.c
+++ b/usr/src/uts/common/os/pg.c
@@ -241,6 +241,27 @@ pg_cpu0_init(void)
}
/*
+ * 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
diff --git a/usr/src/uts/i86pc/io/mc/mcamd.h b/usr/src/uts/i86pc/io/mc/mcamd.h
index 28dd664b82..8ad790f1f8 100644
--- a/usr/src/uts/i86pc/io/mc/mcamd.h
+++ b/usr/src/uts/i86pc/io/mc/mcamd.h
@@ -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 @@ struct mc {
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, */
diff --git a/usr/src/uts/i86pc/io/mc/mcamd_drv.c b/usr/src/uts/i86pc/io/mc/mcamd_drv.c
index fe8ad94fd9..3490c08e2a 100644
--- a/usr/src/uts/i86pc/io/mc/mcamd_drv.c
+++ b/usr/src/uts/i86pc/io/mc/mcamd_drv.c
@@ -110,7 +110,7 @@ mc_lookup_by_chipid(int chipid)
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 @@ mc_report_testfails(mc_t *mc)
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 @@ mc_mkprops_addrmap(mc_pcicfg_hdl_t cfghdl, mc_t *mc)
* 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 @@ mc_fm_fini(dev_info_t *dip)
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->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_sparecs = MC_INVALNUM;
- mc->mc_props.mcp_badcs = MC_INVALNUM;
/*
+ * 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.
*/
- cpu = PG_CPU_GET_FIRST(chp);
+ 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_props.mcp_num = chipid;
+ mc->mc_props.mcp_sparecs = MC_INVALNUM;
+ mc->mc_props.mcp_badcs = MC_INVALNUM;
+
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 @@ mc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
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 @@ mc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
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_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
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 @@ mc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
*/
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) {
/*
diff --git a/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c b/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c
index 8c772a8f01..4445a23ae2 100644
--- a/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c
+++ b/usr/src/uts/i86pc/io/mc/mcamd_pcicfg.c
@@ -87,7 +87,7 @@ uint32_t
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 @@ mc_pcicfg_put32_nohdl(mc_t *mc, enum mc_funcnum func, off_t offset,
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);
}
diff --git a/usr/src/uts/i86pc/io/mc/mcamd_subr.c b/usr/src/uts/i86pc/io/mc/mcamd_subr.c
index 9f9786b10b..f072e37b1a 100644
--- a/usr/src/uts/i86pc/io/mc/mcamd_subr.c
+++ b/usr/src/uts/i86pc/io/mc/mcamd_subr.c
@@ -617,7 +617,7 @@ mc_fmri_create(mc_t *mc)
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);
diff --git a/usr/src/uts/sun4u/os/cmp.c b/usr/src/uts/sun4u/os/cmp.c
index 3c2fa2503f..c35fa8dbd4 100644
--- a/usr/src/uts/sun4u/os/cmp.c
+++ b/usr/src/uts/sun4u/os/cmp.c
@@ -155,11 +155,11 @@ pg_plat_hw_shared(cpu_t *cp, pghw_type_t hw)
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 @@ pg_plat_hw_shared(cpu_t *cp, pghw_type_t hw)
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 @@ pg_plat_cpus_share(cpu_t *cpu_a, cpu_t *cpu_b, pghw_type_t hw)
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 @@ pg_plat_hw_instance_id(cpu_t *cpu, pghw_type_t hw)
{
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 @@ pg_plat_hw_instance_id(cpu_t *cpu, pghw_type_t hw)
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);
}