diff options
author | jeff <jeff@FreeBSD.org> | 2008-03-02 07:58:42 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2008-03-02 07:58:42 +0000 |
commit | ad2a31513f336da73b206794695829f59113b3a7 (patch) | |
tree | a49a50ce8694ae981e503de20b9650bb0f5a1776 /sys/amd64 | |
parent | 0a56287482dbdc42be0a66082c61cf783dd56d5f (diff) | |
download | FreeBSD-src-ad2a31513f336da73b206794695829f59113b3a7.zip FreeBSD-src-ad2a31513f336da73b206794695829f59113b3a7.tar.gz |
- Remove the old smp cpu topology specification with a new, more flexible
tree structure that encodes the level of cache sharing and other
properties.
- Provide several convenience functions for creating one and two level
cpu trees as well as a default flat topology. The system now always
has some topology.
- On i386 and amd64 create a seperate level in the hierarchy for HTT
and multi-core cpus. This will allow the scheduler to intelligently
load balance non-uniform cores. Presently we don't detect what level
of the cache hierarchy is shared at each level in the topology.
- Add a mechanism for testing common topologies that have more information
than the MD code is able to provide via the kern.smp.topology tunable.
This should be considered a debugging tool only and not a stable api.
Sponsored by: Nokia
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/identcpu.c | 8 | ||||
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 71 | ||||
-rw-r--r-- | sys/amd64/include/smp.h | 5 |
3 files changed, 41 insertions, 43 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index a51f02e..f0afb9f 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -97,6 +97,10 @@ static struct { { "Sledgehammer", CPUCLASS_K8 }, /* CPU_SLEDGEHAMMER */ }; +int cpu_cores; +int cpu_logical; + + extern int pq_l2size; extern int pq_l2nways; @@ -360,11 +364,13 @@ printcpuinfo(void) if ((regs[0] & 0x1f) != 0) cmp = ((regs[0] >> 26) & 0x3f) + 1; } + cpu_cores = cmp; + cpu_logical = htt / cmp; if (cmp > 1) printf("\n Cores per package: %d", cmp); if ((htt / cmp) > 1) printf("\n Logical CPUs per core: %d", - htt / cmp); + cpu_logical); } } /* Avoid ugly blank lines: only print newline when we have to. */ diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index a827137..83eab2e 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -83,12 +83,6 @@ extern int nkpt; extern struct pcpu __pcpu[]; -/* - * CPU topology map datastructures for HTT. - */ -static struct cpu_group mp_groups[MAXCPU]; -static struct cpu_top mp_top; - /* AP uses this during bootstrap. Do not staticize. */ char *bootSTK; static int bootAP; @@ -182,40 +176,38 @@ mem_range_AP_init(void) mem_range_softc.mr_op->initAP(&mem_range_softc); } -void -mp_topology(void) +struct cpu_group * +cpu_topo(void) { - struct cpu_group *group; - int apic_id; - int groups; - int cpu; - - /* Build the smp_topology map. */ - /* Nothing to do if there is no HTT support. */ - if (hyperthreading_cpus <= 1) - return; - group = &mp_groups[0]; - groups = 1; - for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) { - if (!cpu_info[apic_id].cpu_present) - continue; - /* - * If the current group has members and we're not a logical - * cpu, create a new group. - */ - if (group->cg_count != 0 && - (apic_id % hyperthreading_cpus) == 0) { - group++; - groups++; - } - group->cg_count++; - group->cg_mask |= 1 << cpu; - cpu++; + if (cpu_cores == 0) + cpu_cores = 1; + if (cpu_logical == 0) + cpu_logical = 1; + if (mp_ncpus % (cpu_cores * cpu_logical) != 0) { + printf("WARNING: Non-uniform processors.\n"); + printf("WARNING: Using suboptimal topology.\n"); + return (smp_topo_none()); } - - mp_top.ct_count = groups; - mp_top.ct_group = mp_groups; - smp_topology = &mp_top; + /* + * No multi-core or hyper-threaded. + */ + if (cpu_logical * cpu_cores == 1) + return (smp_topo_none()); + /* + * Only HTT no multi-core. + */ + if (cpu_logical > 1 && cpu_cores == 1) + return (smp_topo_1level(CG_SHARE_L1, cpu_logical, CG_FLAG_HTT)); + /* + * Only multi-core no HTT. + */ + if (cpu_cores > 1 && cpu_logical == 1) + return (smp_topo_1level(CG_SHARE_NONE, cpu_cores, 0)); + /* + * Both HTT and multi-core. + */ + return (smp_topo_2level(CG_SHARE_NONE, cpu_cores, + CG_SHARE_L1, cpu_logical, CG_FLAG_HTT)); } /* @@ -409,9 +401,6 @@ cpu_mp_start(void) } set_interrupt_apic_ids(); - - /* Last, setup the cpu topology now that we have probed CPUs */ - mp_topology(); } diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index d85c55e..f961d6b 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -36,6 +36,10 @@ extern int boot_cpu_id; extern struct pcb stoppcbs[]; extern int cpu_apic_ids[]; +/* global data in identcpu.c */ +extern int cpu_cores; +extern int cpu_logical; + /* IPI handlers */ inthand_t IDTVEC(invltlb), /* TLB shootdowns - global */ @@ -57,7 +61,6 @@ void ipi_self(u_int ipi); void ipi_bitmap_handler(struct trapframe frame); u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); -void mp_topology(void); void smp_cache_flush(void); void smp_invlpg(vm_offset_t addr); void smp_masked_invlpg(u_int mask, vm_offset_t addr); |