summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2018-08-23 17:29:42 +0000
committerJohn Levon <john.levon@joyent.com>2018-08-23 17:30:22 +0000
commite79c50557fdcaf68635086f55afd817419c78661 (patch)
tree79315a8558da7eaae004ffab5c0f4f21de58c18c
parent14623ce3614a9ee961adb4294066fe377022d419 (diff)
downloadillumos-joyent-e79c50557fdcaf68635086f55afd817419c78661.tar.gz
OS-7149 HT exclusion needs cleanup
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r--usr/src/pkg/manifests/system-header.mf3
-rw-r--r--usr/src/uts/i86pc/io/apix/apix_utils.c7
-rw-r--r--usr/src/uts/i86pc/io/pcplusmp/apic.c6
-rw-r--r--usr/src/uts/i86pc/os/ht.c62
-rw-r--r--usr/src/uts/i86pc/sys/ht.h1
-rw-r--r--usr/src/uts/sun4/sys/ht.h5
6 files changed, 57 insertions, 27 deletions
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index f3721b3ce8..3f62bda986 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -1675,6 +1675,7 @@ $(i386_ONLY)file path=usr/platform/i86pc/include/sys/cram.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/ddi_subrdefs.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/debug_info.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/fastboot.h
+$(i386_ONLY)file path=usr/platform/i86pc/include/sys/ht.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/mach_mmu.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/machclock.h
$(i386_ONLY)file path=usr/platform/i86pc/include/sys/machcpuvar.h
@@ -1730,6 +1731,7 @@ $(sparc_ONLY)file path=usr/platform/sun4u/include/sys/errclassify.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/fhc.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/gpio_87317.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/hpc3130_events.h
+$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/ht.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/i2c/clients/hpc3130.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/i2c/clients/i2c_client.h
$(sparc_ONLY)file path=usr/platform/sun4u/include/sys/i2c/clients/lm75.h
@@ -1793,6 +1795,7 @@ $(sparc_ONLY)file path=usr/platform/sun4v/include/sys/dvma.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/eeprom.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/fcode.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/hsvc.h
+$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/ht.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/hypervisor_api.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/idprom.h
$(sparc_ONLY)file path=usr/platform/sun4v/include/sys/intr.h
diff --git a/usr/src/uts/i86pc/io/apix/apix_utils.c b/usr/src/uts/i86pc/io/apix/apix_utils.c
index 0bdc7c6cc9..268aa5a391 100644
--- a/usr/src/uts/i86pc/io/apix/apix_utils.c
+++ b/usr/src/uts/i86pc/io/apix/apix_utils.c
@@ -29,6 +29,7 @@
/*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Pluribus Networks, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
#include <sys/processor.h>
@@ -66,6 +67,7 @@
#include <sys/x_call.h>
#include <sys/reboot.h>
#include <sys/apix.h>
+#include <sys/ht.h>
static int apix_get_avail_vector_oncpu(uint32_t, int, int);
static apix_vector_t *apix_init_vector(processorid_t, uchar_t);
@@ -803,6 +805,9 @@ apix_insert_av(apix_vector_t *vecp, void *intr_id, avfunc f, caddr_t arg1,
vecp->v_share++;
vecp->v_pri = (ipl > vecp->v_pri) ? ipl : vecp->v_pri;
+
+ ht_intr_alloc_pil(vecp->v_pri);
+
if (vecp->v_autovect == NULL) { /* Nothing on list - put it at head */
vecp->v_autovect = mem;
return;
@@ -1468,7 +1473,7 @@ apix_rebind(apix_vector_t *vecp, processorid_t newcpu, int count)
if (!apix_is_cpu_enabled(newcpu))
return (NULL);
- if (vecp->v_cpuid == newcpu) /* rebind to the same cpu */
+ if (vecp->v_cpuid == newcpu) /* rebind to the same cpu */
return (vecp);
APIX_ENTER_CPU_LOCK(oldcpu);
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic.c b/usr/src/uts/i86pc/io/pcplusmp/apic.c
index 0649afa3f3..9d1f0962fc 100644
--- a/usr/src/uts/i86pc/io/pcplusmp/apic.c
+++ b/usr/src/uts/i86pc/io/pcplusmp/apic.c
@@ -82,6 +82,7 @@
#include <sys/hpet.h>
#include <sys/apic_common.h>
#include <sys/apic_timer.h>
+#include <sys/ht.h>
/*
* Local Function Prototypes
@@ -300,6 +301,11 @@ apic_init(void)
apic_ipltopri[j] = (i << APIC_IPL_SHIFT) + APIC_BASE_VECT;
apic_init_common();
+ /*
+ * For pcplusmp, we'll keep things simple and always disable this.
+ */
+ ht_intr_alloc_pil(XC_CPUPOKE_PIL);
+
apic_pir_vect = apic_get_ipivect(XC_CPUPOKE_PIL, -1);
#if !defined(__amd64)
diff --git a/usr/src/uts/i86pc/os/ht.c b/usr/src/uts/i86pc/os/ht.c
index f82c51ac08..6e13eaedae 100644
--- a/usr/src/uts/i86pc/os/ht.c
+++ b/usr/src/uts/i86pc/os/ht.c
@@ -138,6 +138,8 @@ CTASSERT(CM_POISONED < (1 << CS_SHIFT));
CTASSERT(CM_POISONED > CM_VCPU);
CTASSERT(CM_VCPU > CM_UNSAFE);
+static uint_t empty_pil = XC_CPUPOKE_PIL;
+
/*
* If disabled, no HT exclusion is performed, and system is potentially
* vulnerable to L1TF if hyper-threading is enabled, and we don't have the "not
@@ -212,6 +214,23 @@ ht_init(void)
}
/*
+ * We're adding an interrupt handler of some kind at the given PIL. If this
+ * happens to be the same PIL as XC_CPUPOKE_PIL, then we need to disable our
+ * pil_needs_kick() optimization, as there is now potentially an unsafe
+ * interrupt handler at that PIL. This typically won't occur, so we're not that
+ * careful about what's actually getting added, which CPU it's on, or if it gets
+ * removed. This also presumes that softints can't cover our empty_pil.
+ */
+void
+ht_intr_alloc_pil(uint_t pil)
+{
+ ASSERT(pil <= PIL_MAX);
+
+ if (empty_pil == pil)
+ empty_pil = PIL_MAX + 1;
+}
+
+/*
* If our sibling is also a VCPU thread from a different zone, we need one of
* them to give up, otherwise they will just battle each other for exclusion
* until they exhaust their quantum.
@@ -370,41 +389,36 @@ ht_kick(cpu_ht_t *ht, zoneid_t zoneid)
poke_cpu(ht->ch_sib->cpu_id);
+ membar_consumer();
+ sibstate = ht->ch_sibstate;
+
+ if (CS_MARK(sibstate) != CM_POISONED || CS_ZONE(sibstate) == zoneid)
+ return;
+
+ lock_clear(&ht->ch_lock);
+
+ /*
+ * Spin until we can see the sibling has been kicked out or is otherwise
+ * OK.
+ */
for (;;) {
membar_consumer();
sibstate = ht->ch_sibstate;
if (CS_MARK(sibstate) != CM_POISONED ||
CS_ZONE(sibstate) == zoneid)
- return;
-
- lock_clear(&ht->ch_lock);
-
- for (;;) {
- membar_consumer();
- sibstate = ht->ch_sibstate;
-
- if (CS_MARK(sibstate) != CM_POISONED ||
- CS_ZONE(sibstate) == zoneid) {
- lock_set(&ht->ch_lock);
- return;
- }
-
- SMT_PAUSE();
- }
+ break;
- lock_set(&ht->ch_lock);
+ SMT_PAUSE();
}
+
+ lock_set(&ht->ch_lock);
}
-/*
- * FIXME: do we need a callback in case somebody installs a handler at this PIL
- * ever?
- */
static boolean_t
pil_needs_kick(uint_t pil)
{
- return (pil != XC_CPUPOKE_PIL);
+ return (pil != empty_pil);
}
void
@@ -413,6 +427,8 @@ ht_begin_intr(uint_t pil)
ulong_t flags;
cpu_ht_t *ht;
+ ASSERT(pil <= PIL_MAX);
+
flags = intr_clear();
ht = &CPU->cpu_m.mcpu_ht;
@@ -581,8 +597,6 @@ ht_should_run(kthread_t *t, cpu_t *cp)
pri_t
ht_adjust_cpu_score(kthread_t *t, struct cpu *cp, pri_t score)
{
- cpu_t *sib;
-
if (ht_should_run(t, cp))
return (score);
diff --git a/usr/src/uts/i86pc/sys/ht.h b/usr/src/uts/i86pc/sys/ht.h
index 6b1bfcdd2b..8bb5a0d6d2 100644
--- a/usr/src/uts/i86pc/sys/ht.h
+++ b/usr/src/uts/i86pc/sys/ht.h
@@ -26,6 +26,7 @@ extern "C" {
struct cpu;
extern void ht_init(void);
+extern void ht_intr_alloc_pil(uint_t);
extern int ht_acquire(void);
extern void ht_release(void);
diff --git a/usr/src/uts/sun4/sys/ht.h b/usr/src/uts/sun4/sys/ht.h
index 831891979f..6d7b3e37cc 100644
--- a/usr/src/uts/sun4/sys/ht.h
+++ b/usr/src/uts/sun4/sys/ht.h
@@ -27,8 +27,9 @@ extern "C" {
#define ht_should_run(t, c) (B_TRUE)
#define ht_adjust_cpu_score(t, c, p) (p)
-#define ht_mark_safe(void) {}
-#define ht_mark_unsafe(void) {}
+#define ht_begin_unsafe(void) {}
+#define ht_end_unsafe(void) {}
+#define ht_end_intr(void) {}
#ifdef __cplusplus
}