diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 1 | ||||
-rw-r--r-- | sys/include/arch/amd64/cdefs.h | 4 | ||||
-rw-r--r-- | sys/include/arch/amd64/cpu.h | 16 | ||||
-rw-r--r-- | sys/include/sys/queue.h | 5 | ||||
-rw-r--r-- | sys/include/sys/sched.h | 2 | ||||
-rw-r--r-- | sys/kern/kern_accnt.c | 20 |
6 files changed, 46 insertions, 2 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index efd1af8..19dcf44 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -418,6 +418,7 @@ cpu_startup(struct cpu_info *ci) setup_vectors(ci); try_mitigate_spectre(); + ci->online = 1; cpu_get_info(ci); cpu_enable_smep(); diff --git a/sys/include/arch/amd64/cdefs.h b/sys/include/arch/amd64/cdefs.h index 0a20324..d038a15 100644 --- a/sys/include/arch/amd64/cdefs.h +++ b/sys/include/arch/amd64/cdefs.h @@ -31,7 +31,7 @@ #define _AMD64_CDEFS_H_ #include <sys/cdefs.h> -#include <machine/sync.h> +#include <machine/cpu.h> /* * Please use CLI wisely, it is a good idea to use @@ -41,7 +41,7 @@ #define md_pause() __ASMV("rep; nop") /* (F3 90) PAUSE */ #define md_intoff() __ASMV("cli") /* Clear interrupts */ #define md_inton() __ASMV("sti") /* Enable interrupts */ -#define md_hlt() __ASMV("hlt") /* Halt the processor */ +#define md_hlt() cpu_halt() /* Halt the processor */ /* * AMD64 specific defines diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h index 046b621..116661b 100644 --- a/sys/include/arch/amd64/cpu.h +++ b/sys/include/arch/amd64/cpu.h @@ -36,6 +36,7 @@ #include <sys/sched.h> #include <sys/spinlock.h> #include <machine/tss.h> +#include <machine/cdefs.h> #define CPU_IRQ(IRQ_N) (BIT((IRQ_N)) & 0xFF) @@ -51,6 +52,7 @@ struct cpu_info { uint8_t family : 4; /* CPU family ID */ uint8_t has_x2apic : 1; uint8_t tlb_shootdown : 1; + uint8_t online : 1; /* CPU online */ uint8_t ipl; size_t lapic_tmr_freq; uint8_t irq_mask; @@ -80,4 +82,18 @@ void mp_bootstrap_aps(struct cpu_info *ci); extern struct cpu_info g_bsp_ci; +__always_inline static inline void +cpu_halt(void) +{ + struct cpu_info *ci = this_cpu(); + + if (ci != NULL) + ci->online = 0; + + __ASMV("hlt"); + + if (ci != NULL) + ci->online = 1; +} + #endif /* !_MACHINE_CPU_H_ */ diff --git a/sys/include/sys/queue.h b/sys/include/sys/queue.h index e5d607d..92c1ff2 100644 --- a/sys/include/sys/queue.h +++ b/sys/include/sys/queue.h @@ -27,7 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if !defined(_KERNEL) +#include <stdint.h> +#include <stddef.h> +#else #include <sys/types.h> +#endif /* !_KERNEL */ #ifndef _QUEUE_H_ #define _QUEUE_H_ diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h index abc2718..7a859b2 100644 --- a/sys/include/sys/sched.h +++ b/sys/include/sys/sched.h @@ -49,11 +49,13 @@ struct sched_cpu { * * @nproc: Number processes running * @ncpu: Number of CPU cores + * @nhlt: Number of halted CPU cores * @quantum_usec: Scheduler quantum (microseconds) */ struct sched_stat { size_t nproc; uint16_t ncpu; + uint16_t nhlt; uint32_t quantum_usec; struct sched_cpu cpus[CPU_MAX]; }; diff --git a/sys/kern/kern_accnt.c b/sys/kern/kern_accnt.c index cd15863..51905e7 100644 --- a/sys/kern/kern_accnt.c +++ b/sys/kern/kern_accnt.c @@ -58,6 +58,25 @@ ctl_stat_read(struct ctlfs_dev *cdp, struct sio_txn *sio) return sio->len; } +static uint16_t +cpu_nhlt(void) +{ + uint16_t nhlt = 0; + struct cpu_info *ci; + + for (size_t i = 0; i < CPU_MAX; ++i) { + ci = cpu_get(i); + if (ci == NULL) { + continue; + } + if (!ci->online) { + ++nhlt; + } + } + + return nhlt; +} + /* * Get scheduler accounting information * @@ -71,6 +90,7 @@ sched_stat(struct sched_stat *statp) statp->nproc = atomic_load_64(&g_nthreads); statp->ncpu = cpu_count(); statp->quantum_usec = DEFAULT_TIMESLICE_USEC; + statp->nhlt = cpu_nhlt(); /* * Setup the per-cpu info/statistics |