From 44c36320a5f99d34932824cdbea1bdd5d48d8493 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 20 Jun 2009 20:49:49 +0800 Subject: [PATCH] MP table: Remove global variables for HT fixup --- sys/platform/pc32/i386/mp_machdep.c | 77 +++++++++++++++-------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/sys/platform/pc32/i386/mp_machdep.c b/sys/platform/pc32/i386/mp_machdep.c index e7e51e8eef..c49a019081 100644 --- a/sys/platform/pc32/i386/mp_machdep.c +++ b/sys/platform/pc32/i386/mp_machdep.c @@ -218,10 +218,6 @@ typedef int (*mptable_iter_func)(void *, const void *, int); #define MP_ANNOUNCE_POST 0x19 -static int need_hyperthreading_fixup; -static u_int logical_cpus; -u_int logical_cpus_mask; - static int madt_probe_test; TUNABLE_INT("hw.madt_probe_test", &madt_probe_test); @@ -308,7 +304,7 @@ static int mptable_iterate_entries(const mpcth_t, static int mptable_probe(void); static int mptable_check(vm_paddr_t); static int mptable_search_sig(u_int32_t target, int count); -static void mptable_hyperthread_fixup(u_int id_mask); +static int mptable_hyperthread_fixup(u_int, int); static void mptable_pass1(struct mptable_pos *); static int mptable_pass2(struct mptable_pos *); static void mptable_default(int type); @@ -1081,17 +1077,17 @@ mptable_pass2(struct mptable_pos *mpt) * the APIC ID's for a physical processor are aligned * with the number of logical CPU's in the processor. */ -static void -mptable_hyperthread_fixup(u_int id_mask) +static int +mptable_hyperthread_fixup(u_int id_mask, int cpu_count) { - int i, id, lcpus_max; + int i, id, lcpus_max, logical_cpus; if ((cpu_feature & CPUID_HTT) == 0) - return; + return 0; lcpus_max = (cpu_procinfo & CPUID_HTT_CORES) >> 16; if (lcpus_max <= 1) - return; + return 0; if (strcmp(cpu_vendor, "GenuineIntel") == 0) { /* @@ -1110,10 +1106,11 @@ mptable_hyperthread_fixup(u_int id_mask) } } - if (mp_naps == lcpus_max) { + KKASSERT(cpu_count != 0); + if (cpu_count == lcpus_max) { /* We have nothing to fix */ - return; - } else if (mp_naps == 1) { + return 0; + } else if (cpu_count == 1) { /* XXX this may be incorrect */ logical_cpus = lcpus_max; } else { @@ -1143,16 +1140,16 @@ mptable_hyperthread_fixup(u_int id_mask) * are same. */ if (dist != new_dist) - return; + return 0; } prev = cur; } if (dist == 1) - return; + return 0; /* Must be power of 2 */ if (dist & (dist - 1)) - return; + return 0; /* Can't exceed CPU package capacity */ if (dist > lcpus_max) @@ -1172,18 +1169,12 @@ mptable_hyperthread_fixup(u_int id_mask) continue; /* First, make sure we are on a logical_cpus boundary. */ if (id % logical_cpus != 0) - return; + return 0; for (i = id + 1; i < id + logical_cpus; i++) if ((id_mask & 1 << i) != 0) - return; + return 0; } - - /* - * Ok, the ID's checked out, so enable the fixup. We have to fixup - * mp_naps right now. - */ - need_hyperthreading_fixup = 1; - mp_naps *= logical_cpus; + return logical_cpus; } static int @@ -2804,7 +2795,8 @@ cpu_send_ipiq_passive(int dcpu) struct mptable_lapic_cbarg1 { int cpu_count; - u_int id_mask; + int ht_fixup; + u_int ht_apicid_mask; }; static int @@ -2821,12 +2813,18 @@ mptable_lapic_pass1_callback(void *xarg, const void *pos, int type) return 0; arg->cpu_count++; - arg->id_mask |= 1 << ent->apic_id; + if (ent->apic_id < 32) { + arg->ht_apicid_mask |= 1 << ent->apic_id; + } else if (arg->ht_fixup) { + kprintf("MPTABLE: lapic id > 32, disable HTT fixup\n"); + arg->ht_fixup = 0; + } return 0; } struct mptable_lapic_cbarg2 { int cpu; + int logical_cpus; int found_bsp; }; @@ -2848,7 +2846,7 @@ mptable_lapic_pass2_callback(void *xarg, const void *pos, int type) if (processor_entry(ent, arg->cpu)) arg->cpu++; - if (need_hyperthreading_fixup) { + if (arg->logical_cpus) { struct PROCENTRY proc; int i; @@ -2862,10 +2860,9 @@ mptable_lapic_pass2_callback(void *xarg, const void *pos, int type) proc.cpu_flags = PROCENTRY_FLAG_EN; proc.apic_id = ent->apic_id; - for (i = 1; i < logical_cpus; i++) { + for (i = 1; i < arg->logical_cpus; i++) { proc.apic_id++; processor_entry(&proc, arg->cpu); - logical_cpus_mask |= (1 << arg->cpu); arg->cpu++; } } @@ -2895,9 +2892,6 @@ mptable_lapic_default(void) * Configure: * cpu_apic_address (common to all CPUs) * mp_naps - * need_hyperthreading_fixup - * logical_cpus - * logical_cpus_mask * ID_TO_CPU(N), APIC ID to logical CPU table * CPU_TO_ID(N), logical CPU to APIC ID table */ @@ -2907,7 +2901,7 @@ mptable_lapic_enumerate(struct mptable_pos *mpt) struct mptable_lapic_cbarg1 arg1; struct mptable_lapic_cbarg2 arg2; mpcth_t cth; - int error; + int error, logical_cpus = 0; vm_offset_t lapic_addr; KKASSERT(mpt->mp_fps != NULL); @@ -2931,18 +2925,24 @@ mptable_lapic_enumerate(struct mptable_pos *mpt) * Find out how many CPUs do we have */ bzero(&arg1, sizeof(arg1)); + arg1.ht_fixup = 1; /* Apply ht fixup by default */ + error = mptable_iterate_entries(cth, mptable_lapic_pass1_callback, &arg1); if (error) panic("mptable_iterate_entries(lapic_pass1) failed\n"); - KKASSERT(arg1.cpu_count != 0); - mp_naps = arg1.cpu_count; /* See if we need to fixup HT logical CPUs. */ - mptable_hyperthread_fixup(arg1.id_mask); + if (arg1.ht_fixup) { + logical_cpus = mptable_hyperthread_fixup(arg1.ht_apicid_mask, + arg1.cpu_count); + if (logical_cpus != 0) + arg1.cpu_count *= logical_cpus; + } + mp_naps = arg1.cpu_count; - /* Qualify the numbers again, after hyperthreading fixup */ + /* Qualify the numbers again, after possible HT fixup */ if (mp_naps > MAXCPU) { kprintf("Warning: only using %d of %d available CPUs!\n", MAXCPU, mp_naps); @@ -2956,6 +2956,7 @@ mptable_lapic_enumerate(struct mptable_pos *mpt) */ bzero(&arg2, sizeof(arg2)); arg2.cpu = 1; + arg2.logical_cpus = logical_cpus; error = mptable_iterate_entries(cth, mptable_lapic_pass2_callback, &arg2); -- 2.41.0