summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2008-03-02 07:58:42 +0000
committerjeff <jeff@FreeBSD.org>2008-03-02 07:58:42 +0000
commitad2a31513f336da73b206794695829f59113b3a7 (patch)
treea49a50ce8694ae981e503de20b9650bb0f5a1776 /sys/amd64
parent0a56287482dbdc42be0a66082c61cf783dd56d5f (diff)
downloadFreeBSD-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.c8
-rw-r--r--sys/amd64/amd64/mp_machdep.c71
-rw-r--r--sys/amd64/include/smp.h5
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);
OpenPOWER on IntegriCloud