From 26fe456f216d9c83dd7f5af085925867ef902c50 Mon Sep 17 00:00:00 2001 From: ps Date: Wed, 26 Mar 2003 19:49:34 +0000 Subject: Nuke options HTT infavor of machdep.hlt_logical_cpus tunable/sysctl. This keeps the logical cpu's halted in the idle loop. By default the logical cpu's are halted at startup. It is also possible to halt any cpu in the idle loop now using machdep.hlt_cpus. Examples of how to use this: machdep.hlt_cpus=1 halt cpu0 machdep.hlt_cpus=2 halt cpu1 machdep.hlt_cpus=4 halt cpu2 machdep.hlt_cpus=3 halt cpu0,cpu1 Reviewed by: jhb, peter --- sys/i386/include/mptable.h | 109 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 21 deletions(-) (limited to 'sys/i386/include/mptable.h') diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index 12d7578..954a7fd 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -26,7 +26,6 @@ */ #include "opt_cpu.h" -#include "opt_htt.h" #include "opt_kstack_pages.h" #ifdef SMP @@ -238,10 +237,9 @@ typedef struct BASETABLE_ENTRY { #define MP_ANNOUNCE_POST 0x19 -#ifdef HTT static int need_hyperthreading_fixup; static u_int logical_cpus; -#endif +static u_int logical_cpus_mask; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -318,9 +316,7 @@ static mpfps_t mpfps; static int search_for_sig(u_int32_t target, int count); static void mp_enable(u_int boot_addr); -#ifdef HTT static void mptable_hyperthread_fixup(u_int id_mask); -#endif static void mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); @@ -791,9 +787,7 @@ mptable_pass1(void) void* position; int count; int type; -#ifdef HTT u_int id_mask; -#endif POSTCODE(MPTABLE_PASS1_POST); @@ -807,9 +801,7 @@ mptable_pass1(void) mp_nbusses = 0; mp_napics = 0; nintrs = 0; -#ifdef HTT id_mask = 0; -#endif /* check for use of 'default' configuration */ if (MPFPS_MPFB1 != 0) { @@ -844,10 +836,8 @@ mptable_pass1(void) & PROCENTRY_FLAG_EN) { ++mp_naps; mp_maxid++; -#ifdef HTT id_mask |= 1 << ((proc_entry_ptr)position)->apic_id; -#endif } break; case 1: /* bus_entry */ @@ -882,10 +872,8 @@ mptable_pass1(void) mp_naps = MAXCPU; } -#ifdef HTT /* See if we need to fixup HT logical CPUs. */ mptable_hyperthread_fixup(id_mask); -#endif /* * Count the BSP. @@ -911,9 +899,7 @@ mptable_pass1(void) static int mptable_pass2(void) { -#ifdef HTT struct PROCENTRY proc; -#endif int x; mpcth_t cth; int totalSize; @@ -926,12 +912,10 @@ mptable_pass2(void) POSTCODE(MPTABLE_PASS2_POST); -#ifdef HTT /* Initialize fake proc entry for use with HT fixup. */ bzero(&proc, sizeof(proc)); proc.type = 0; proc.cpu_flags = PROCENTRY_FLAG_EN; -#endif pgeflag = 0; /* XXX - Not used under SMP yet. */ @@ -1011,7 +995,6 @@ mptable_pass2(void) if (processor_entry(position, cpu)) ++cpu; -#ifdef HTT if (need_hyperthreading_fixup) { /* * Create fake mptable processor entries @@ -1022,10 +1005,10 @@ mptable_pass2(void) for (i = 1; i < logical_cpus; i++) { proc.apic_id++; (void)processor_entry(&proc, cpu); + logical_cpus_mask |= (1 << cpu); cpu++; } } -#endif break; case 1: if (bus_entry(position, bus)) @@ -1058,7 +1041,6 @@ mptable_pass2(void) return 0; } -#ifdef HTT /* * Check if we should perform a hyperthreading "fix-up" to * enumerate any logical CPU's that aren't already listed @@ -1108,7 +1090,6 @@ mptable_hyperthread_fixup(u_int id_mask) mp_maxid *= logical_cpus; mp_naps *= logical_cpus; } -#endif void assign_apic_irq(int apic, int intpin, int irq) @@ -2760,3 +2741,89 @@ release_aps(void *dummy __unused) } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); + +static int hlt_cpus_mask; +static int hlt_logical_cpus = 1; +static struct sysctl_ctx_list logical_cpu_clist; + +static int +sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) +{ + u_int mask; + int error; + + mask = hlt_cpus_mask; + error = sysctl_handle_int(oidp, &mask, 0, req); + if (error || !req->newptr) + return (error); + + if (logical_cpus_mask != 0 && + (mask & logical_cpus_mask) == logical_cpus_mask) + hlt_logical_cpus = 1; + else + hlt_logical_cpus = 0; + + if ((mask & all_cpus) == all_cpus) + mask &= ~(1<<0); + hlt_cpus_mask = mask; + return (error); +} +SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW, + 0, 0, sysctl_hlt_cpus, "IU", ""); + +static int +sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS) +{ + int disable, error; + + disable = hlt_logical_cpus; + error = sysctl_handle_int(oidp, &disable, 0, req); + if (error || !req->newptr) + return (error); + + if (disable) + hlt_cpus_mask |= logical_cpus_mask; + else + hlt_cpus_mask &= ~logical_cpus_mask; + + if ((hlt_cpus_mask & all_cpus) == all_cpus) + hlt_cpus_mask &= ~(1<<0); + + hlt_logical_cpus = disable; + return (error); +} + +static void +cpu_hlt_setup(void *dummy __unused) +{ + + if (logical_cpus_mask != 0) { + TUNABLE_INT_FETCH("machdep.hlt_logical_cpus", + &hlt_logical_cpus); + sysctl_ctx_init(&logical_cpu_clist); + SYSCTL_ADD_PROC(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0, + sysctl_hlt_logical_cpus, "IU", ""); + SYSCTL_ADD_UINT(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, + &logical_cpus_mask, 0, ""); + + if (hlt_logical_cpus) + hlt_cpus_mask |= logical_cpus_mask; + } +} +SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL); + +int +mp_grab_cpu_hlt(void) +{ + u_int mask = PCPU_GET(cpumask); + int retval; + + retval = mask & hlt_cpus_mask; + while (mask & hlt_cpus_mask) + __asm __volatile("sti; hlt" : : : "memory"); + return (retval); +} -- cgit v1.1