Skip to content

Commit

Permalink
x86, amd: Get multi-node CPU info from NodeId MSR instead of PCI conf…
Browse files Browse the repository at this point in the history
…ig space

Use NodeId MSR to get NodeId and number of nodes per processor.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
LKML-Reference: <20091216144355.GB28798@alberich.amd.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
  • Loading branch information
Andreas Herrmann authored and H. Peter Anvin committed Dec 16, 2009
1 parent 5df9740 commit 9d260eb
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 38 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */
#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */

/*
* Auxiliary flags: Linux defined - For features scattered in various
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/msr-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff
#define FAM10H_MMIO_CONF_BASE_SHIFT 20
#define MSR_FAM10H_NODE_ID 0xc001100c

/* K8 MSRs */
#define MSR_K8_TOP_MEM1 0xc001001a
Expand Down
53 changes: 15 additions & 38 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid)

/*
* Fixup core topology information for AMD multi-node processors.
* Assumption 1: Number of cores in each internal node is the same.
* Assumption 2: Mixed systems with both single-node and dual-node
* processors are not supported.
* Assumption: Number of cores in each internal node is the same.
*/
#ifdef CONFIG_X86_HT
static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_PCI
u32 t, cpn;
u8 n, n_id;
unsigned long long value;
u32 nodes, cores_per_node;
int cpu = smp_processor_id();

if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
return;

/* fixup topology information only once for a core */
if (cpu_has(c, X86_FEATURE_AMD_DCM))
return;

/* check for multi-node processor on boot cpu */
t = read_pci_config(0, 24, 3, 0xe8);
if (!(t & (1 << 29)))
rdmsrl(MSR_FAM10H_NODE_ID, value);

nodes = ((value >> 3) & 7) + 1;
if (nodes == 1)
return;

set_cpu_cap(c, X86_FEATURE_AMD_DCM);
cores_per_node = c->x86_max_cores / nodes;

/* cores per node: each internal node has half the number of cores */
cpn = c->x86_max_cores >> 1;
/* store NodeID, use llc_shared_map to store sibling info */
per_cpu(cpu_llc_id, cpu) = value & 7;

/* even-numbered NB_id of this dual-node processor */
n = c->phys_proc_id << 1;

/*
* determine internal node id and assign cores fifty-fifty to
* each node of the dual-node processor
*/
t = read_pci_config(0, 24 + n, 3, 0xe8);
n = (t>>30) & 0x3;
if (n == 0) {
if (c->cpu_core_id < cpn)
n_id = 0;
else
n_id = 1;
} else {
if (c->cpu_core_id < cpn)
n_id = 1;
else
n_id = 0;
}

/* compute entire NodeID, use llc_shared_map to store sibling info */
per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;

/* fixup core id to be in range from 0 to cpn */
c->cpu_core_id = c->cpu_core_id % cpn;
#endif
/* fixup core id to be in range from 0 to (cores_per_node - 1) */
c->cpu_core_id = c->cpu_core_id % cores_per_node;
}
#endif

Expand Down

0 comments on commit 9d260eb

Please sign in to comment.