summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/machdep.c1
-rw-r--r--sys/include/arch/amd64/cdefs.h4
-rw-r--r--sys/include/arch/amd64/cpu.h16
-rw-r--r--sys/include/sys/queue.h5
-rw-r--r--sys/include/sys/sched.h2
-rw-r--r--sys/kern/kern_accnt.c20
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