FreeBSD Bugzilla – Attachment 105067 Details for
Bug 145385
[cpu] Logical processor cannot be disabled for some SMT-enabled Intel procs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
kern.145385.patch
kern.145385.patch (text/x-patch; charset=US-ASCII), 13.20 KB, created by
Enji Cooper
on 2010-11-19 03:01:08 UTC
(
hide
)
Description:
kern.145385.patch
Filename:
MIME Type:
Creator:
Enji Cooper
Created:
2010-11-19 03:01:08 UTC
Size:
13.20 KB
patch
obsolete
>Index: sys/amd64/amd64/mp_machdep.c >=================================================================== >--- sys/amd64/amd64/mp_machdep.c (revision 215417) >+++ sys/amd64/amd64/mp_machdep.c (working copy) >@@ -39,6 +39,7 @@ > #ifdef GPROF > #include <sys/gmon.h> > #endif >+#include <sys/cpuset.h> > #include <sys/kernel.h> > #include <sys/ktr.h> > #include <sys/lock.h> >@@ -85,7 +86,7 @@ > int mp_naps; /* # of Applications processors */ > int boot_cpu_id = -1; /* designated BSP */ > >-extern struct pcpu __pcpu[]; >+extern struct pcpu __pcpu[]; > > /* AP uses this during bootstrap. Do not staticize. */ > char *bootSTK; >@@ -1145,7 +1146,7 @@ > old_pending = cpu_ipi_pending[cpu]; > new_pending = old_pending | bitmap; > } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], >- old_pending, new_pending)); >+ old_pending, new_pending)); > if (old_pending) > return; > } >@@ -1333,7 +1334,6 @@ > */ > if (ipi == IPI_STOP_HARD) > atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus)); >- > CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); > lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); > } >@@ -1357,7 +1357,7 @@ > cpustop_handler(); > return (0); > } >- >+ > /* > * Handle an IPI_STOP by saving our current context and spinning until we > * are resumed. >@@ -1447,6 +1447,7 @@ > static int > sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; > cpumask_t mask; > int error; > >@@ -1455,18 +1456,20 @@ > 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 (! hyperthreading_allowed) >+ if (hlt_logical_cpus) >+ mask |= logical_cpus_mask; >+ if (!hyperthreading_allowed) > mask |= hyperthreading_cpus_mask; > >+ /* Don't disable BSP0 */ > if ((mask & all_cpus) == all_cpus) > mask &= ~(1<<0); >- hlt_cpus_mask = mask; >+ >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hlt_cpus_mask = mask; > return (error); > } > SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW, >@@ -1476,6 +1479,8 @@ > static int > sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; >+ cpumask_t mask; > int disable, error; > > disable = hlt_logical_cpus; >@@ -1483,24 +1488,31 @@ > if (error || !req->newptr) > return (error); > >+ mask = hlt_cpus_mask; > if (disable) >- hlt_cpus_mask |= logical_cpus_mask; >- else >- hlt_cpus_mask &= ~logical_cpus_mask; >+ mask |= logical_cpus_mask; >+ if (!hyperthreading_allowed) >+ mask |= hyperthreading_cpus_mask; > >- if (! hyperthreading_allowed) >- hlt_cpus_mask |= hyperthreading_cpus_mask; >+ /* Don't disable BSP0 */ >+ if ((mask & all_cpus) == all_cpus) >+ mask &= ~(1<<0); > >- if ((hlt_cpus_mask & all_cpus) == all_cpus) >- hlt_cpus_mask &= ~(1<<0); >+ printf("%s: mask: %d\n", __func__, mask); > >- hlt_logical_cpus = disable; >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hlt_logical_cpus = disable; > return (error); > } > > static int > sysctl_hyperthreading_allowed(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; >+ cpumask_t mask; > int allowed, error; > > allowed = hyperthreading_allowed; >@@ -1508,42 +1520,45 @@ > if (error || !req->newptr) > return (error); > >-#ifdef SCHED_ULE >- /* >- * SCHED_ULE doesn't allow enabling/disabling HT cores at >- * run-time. >- */ >- if (allowed != hyperthreading_allowed) >- return (ENOTSUP); >- return (error); >-#endif >+ mask = hlt_cpus_mask; >+ if (hlt_logical_cpus) >+ mask |= logical_cpus_mask; >+ if (!allowed) >+ mask |= hyperthreading_cpus_mask; > >- if (allowed) >- hlt_cpus_mask &= ~hyperthreading_cpus_mask; >- else >- hlt_cpus_mask |= hyperthreading_cpus_mask; >+ /* Don't disable BSP0 */ >+ if ((mask & all_cpus) == all_cpus) >+ mask &= ~(1<<0); > >- if (logical_cpus_mask != 0 && >- (hlt_cpus_mask & logical_cpus_mask) == logical_cpus_mask) >- hlt_logical_cpus = 1; >- else >- hlt_logical_cpus = 0; >- >- if ((hlt_cpus_mask & all_cpus) == all_cpus) >- hlt_cpus_mask &= ~(1<<0); >- >- hyperthreading_allowed = allowed; >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hyperthreading_allowed = allowed; > return (error); > } > > static void > cpu_hlt_setup(void *dummy __unused) > { >+ cpuset_t mask_set; > > if (logical_cpus_mask != 0) { > TUNABLE_INT_FETCH("machdep.hlt_logical_cpus", > &hlt_logical_cpus); >+ if (hlt_logical_cpus != 0) { >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~logical_cpus_mask & all_cpus, &mask_set); >+ if (cpuset_zero_modify(&mask_set) == 0) >+ hlt_logical_cpus = 1; >+ else >+ hlt_logical_cpus = 0; >+ } > sysctl_ctx_init(&logical_cpu_clist); >+ SYSCTL_ADD_UINT(&logical_cpu_clist, >+ SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, >+ "all_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, >+ &all_cpus, 0, ""); > SYSCTL_ADD_PROC(&logical_cpu_clist, > SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, > "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0, >@@ -1553,9 +1568,6 @@ > "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, > &logical_cpus_mask, 0, ""); > >- if (hlt_logical_cpus) >- hlt_cpus_mask |= logical_cpus_mask; >- > /* > * If necessary for security purposes, force > * hyperthreading off, regardless of the value >@@ -1566,8 +1578,6 @@ > SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, > "hyperthreading_allowed", CTLTYPE_INT|CTLFLAG_RW, > 0, 0, sysctl_hyperthreading_allowed, "IU", ""); >- if (! hyperthreading_allowed) >- hlt_cpus_mask |= hyperthreading_cpus_mask; > } > } > } >@@ -1627,4 +1637,3 @@ > } > SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL); > #endif >- >Index: sys/i386/i386/mp_machdep.c >=================================================================== >--- sys/i386/i386/mp_machdep.c (revision 215417) >+++ sys/i386/i386/mp_machdep.c (working copy) >@@ -54,6 +54,7 @@ > #ifdef GPROF > #include <sys/gmon.h> > #endif >+#include <sys/cpuset.h> > #include <sys/kernel.h> > #include <sys/ktr.h> > #include <sys/lock.h> >@@ -1197,7 +1198,7 @@ > int ncpu, othercpus; > > othercpus = mp_ncpus - 1; >- if (mask == (u_int)-1) { >+ if (mask == (cpumask_t)-1) { > ncpu = othercpus; > if (ncpu < 1) > return; >@@ -1222,7 +1223,7 @@ > smp_tlb_addr1 = addr1; > smp_tlb_addr2 = addr2; > atomic_store_rel_int(&smp_tlb_wait, 0); >- if (mask == (u_int)-1) >+ if (mask == (cpumask_t)-1) > ipi_all_but_self(vector); > else > ipi_selected(mask, vector); >@@ -1248,7 +1249,7 @@ > old_pending = cpu_ipi_pending[cpu]; > new_pending = old_pending | bitmap; > } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu], >- old_pending, new_pending)); >+ old_pending, new_pending)); > if (old_pending) > return; > } >@@ -1510,6 +1511,7 @@ > static int > sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; > cpumask_t mask; > int error; > >@@ -1518,18 +1520,20 @@ > 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 (! hyperthreading_allowed) >+ if (hlt_logical_cpus) >+ mask |= logical_cpus_mask; >+ if (!hyperthreading_allowed) > mask |= hyperthreading_cpus_mask; > >+ /* Don't disable BSP0 */ > if ((mask & all_cpus) == all_cpus) > mask &= ~(1<<0); >- hlt_cpus_mask = mask; >+ >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hlt_cpus_mask = mask; > return (error); > } > SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW, >@@ -1539,6 +1543,8 @@ > static int > sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; >+ cpumask_t mask; > int disable, error; > > disable = hlt_logical_cpus; >@@ -1546,24 +1552,31 @@ > if (error || !req->newptr) > return (error); > >+ mask = hlt_cpus_mask; > if (disable) >- hlt_cpus_mask |= logical_cpus_mask; >- else >- hlt_cpus_mask &= ~logical_cpus_mask; >+ mask |= logical_cpus_mask; >+ if (!hyperthreading_allowed) >+ mask |= hyperthreading_cpus_mask; > >- if (! hyperthreading_allowed) >- hlt_cpus_mask |= hyperthreading_cpus_mask; >+ /* Don't disable BSP0 */ >+ if ((mask & all_cpus) == all_cpus) >+ mask &= ~(1<<0); > >- if ((hlt_cpus_mask & all_cpus) == all_cpus) >- hlt_cpus_mask &= ~(1<<0); >+ printf("%s: mask: %d\n", __func__, mask); > >- hlt_logical_cpus = disable; >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hlt_logical_cpus = disable; > return (error); > } > > static int > sysctl_hyperthreading_allowed(SYSCTL_HANDLER_ARGS) > { >+ cpuset_t mask_set; >+ cpumask_t mask; > int allowed, error; > > allowed = hyperthreading_allowed; >@@ -1571,42 +1584,45 @@ > if (error || !req->newptr) > return (error); > >-#ifdef SCHED_ULE >- /* >- * SCHED_ULE doesn't allow enabling/disabling HT cores at >- * run-time. >- */ >- if (allowed != hyperthreading_allowed) >- return (ENOTSUP); >- return (error); >-#endif >+ mask = hlt_cpus_mask; >+ if (hlt_logical_cpus) >+ mask |= logical_cpus_mask; >+ if (!allowed) >+ mask |= hyperthreading_cpus_mask; > >- if (allowed) >- hlt_cpus_mask &= ~hyperthreading_cpus_mask; >- else >- hlt_cpus_mask |= hyperthreading_cpus_mask; >+ /* Don't disable BSP0 */ >+ if ((mask & all_cpus) == all_cpus) >+ mask &= ~(1<<0); > >- if (logical_cpus_mask != 0 && >- (hlt_cpus_mask & logical_cpus_mask) == logical_cpus_mask) >- hlt_logical_cpus = 1; >- else >- hlt_logical_cpus = 0; >- >- if ((hlt_cpus_mask & all_cpus) == all_cpus) >- hlt_cpus_mask &= ~(1<<0); >- >- hyperthreading_allowed = allowed; >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~mask & all_cpus, &mask_set); >+ error = cpuset_zero_modify(&mask_set); >+ if (error == 0) >+ hyperthreading_allowed = allowed; > return (error); > } > > static void > cpu_hlt_setup(void *dummy __unused) > { >+ cpuset_t mask_set; > > if (logical_cpus_mask != 0) { > TUNABLE_INT_FETCH("machdep.hlt_logical_cpus", > &hlt_logical_cpus); >+ if (hlt_logical_cpus != 0) { >+ CPU_ZERO(&mask_set); >+ CPU_SETMASK(~logical_cpus_mask & all_cpus, &mask_set); >+ if (cpuset_zero_modify(&mask_set) == 0) >+ hlt_logical_cpus = 1; >+ else >+ hlt_logical_cpus = 0; >+ } > sysctl_ctx_init(&logical_cpu_clist); >+ SYSCTL_ADD_UINT(&logical_cpu_clist, >+ SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, >+ "all_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, >+ &all_cpus, 0, ""); > SYSCTL_ADD_PROC(&logical_cpu_clist, > SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, > "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0, >@@ -1616,9 +1632,6 @@ > "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, > &logical_cpus_mask, 0, ""); > >- if (hlt_logical_cpus) >- hlt_cpus_mask |= logical_cpus_mask; >- > /* > * If necessary for security purposes, force > * hyperthreading off, regardless of the value >@@ -1629,8 +1642,6 @@ > SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, > "hyperthreading_allowed", CTLTYPE_INT|CTLFLAG_RW, > 0, 0, sysctl_hyperthreading_allowed, "IU", ""); >- if (! hyperthreading_allowed) >- hlt_cpus_mask |= hyperthreading_cpus_mask; > } > } > } >@@ -1686,7 +1697,7 @@ > intrcnt_add(buf, &ipi_lazypmap_counts[i]); > snprintf(buf, sizeof(buf), "cpu%d:hardclock", i); > intrcnt_add(buf, &ipi_hardclock_counts[i]); >- } >+ } > } > SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL); > #endif >Index: sys/kern/kern_cpuset.c >=================================================================== >--- sys/kern/kern_cpuset.c (revision 215417) >+++ sys/kern/kern_cpuset.c (working copy) >@@ -332,6 +332,10 @@ > > mtx_assert(&cpuset_lock, MA_OWNED); > CPU_AND(&set->cs_mask, mask); >+#if 1 >+ printf("%s (after): set: %ld, mask: %ld\n", __func__, >+ set->cs_mask.__bits[0], mask->__bits[0]); >+#endif > LIST_FOREACH(nset, &set->cs_children, cs_siblings) > cpuset_update(nset, &set->cs_mask); > >@@ -764,8 +768,29 @@ > panic("Can't set initial cpuset mask.\n"); > cpuset_zero->cs_flags |= CPU_SET_RDONLY; > } >-SYSINIT(cpuset, SI_SUB_SMP, SI_ORDER_ANY, cpuset_init, NULL); >+SYSINIT(cpuset, SI_SUB_SMP, SI_ORDER_MIDDLE, cpuset_init, NULL); > >+int >+cpuset_zero_modify(cpuset_t *mask) >+{ >+ int err; >+ >+ mtx_lock_spin(&cpuset_lock); >+ cpuset_zero->cs_flags &= ~CPU_SET_RDONLY; >+#if 1 >+ printf("%s (before): cpuset_zero: %ld, mask: %ld\n", __func__, >+ cpuset_zero->cs_mask.__bits[0], mask->__bits[0]); >+#endif >+ err = cpuset_modify(cpuset_zero, mask); >+#if 1 >+ printf("%s (after): cpuset_zero: %ld, mask: %ld\n", __func__, >+ cpuset_zero->cs_mask.__bits[0], mask->__bits[0]); >+#endif >+ cpuset_zero->cs_flags |= CPU_SET_RDONLY; >+ mtx_unlock_spin(&cpuset_lock); >+ return (err); >+} >+ > #ifndef _SYS_SYSPROTO_H_ > struct cpuset_args { > cpusetid_t *setid; >Index: sys/sys/cpuset.h >=================================================================== >--- sys/sys/cpuset.h (revision 215417) >+++ sys/sys/cpuset.h (working copy) >@@ -54,6 +54,7 @@ > #define CPU_COPY(f, t) (void)(*(t) = *(f)) > #define CPU_ISSET(n, p) (((p)->__bits[(n)/_NCPUBITS] & __cpuset_mask(n)) != 0) > #define CPU_SET(n, p) ((p)->__bits[(n)/_NCPUBITS] |= __cpuset_mask(n)) >+#define CPU_SETMASK(mask, p) ((p)->__bits[0] = (mask)) > #define CPU_ZERO(p) do { \ > __size_t __i; \ > for (__i = 0; __i < _NCPUWORDS; __i++) \ >@@ -178,6 +179,7 @@ > struct prison; > struct proc; > >+int cpuset_zero_modify(cpuset_t *mask); > struct cpuset *cpuset_thread0(void); > struct cpuset *cpuset_ref(struct cpuset *); > void cpuset_rel(struct cpuset *);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 145385
:
105065
|
105066
| 105067