diff options
author | John Levon <john.levon@joyent.com> | 2018-08-23 17:29:42 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2018-08-23 17:30:22 +0000 |
commit | e79c50557fdcaf68635086f55afd817419c78661 (patch) | |
tree | 79315a8558da7eaae004ffab5c0f4f21de58c18c | |
parent | 14623ce3614a9ee961adb4294066fe377022d419 (diff) | |
download | illumos-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.mf | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/apix/apix_utils.c | 7 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/pcplusmp/apic.c | 6 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/ht.c | 62 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/ht.h | 1 | ||||
-rw-r--r-- | usr/src/uts/sun4/sys/ht.h | 5 |
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 } |