summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/amd64/mp.c18
-rw-r--r--sys/arch/amd64/amd64/proc_machdep.c5
-rw-r--r--sys/include/arch/amd64/cpu.h4
-rw-r--r--sys/include/sys/limits.h2
-rw-r--r--sys/include/sys/sched.h12
-rw-r--r--sys/kern/kern_accnt.c14
6 files changed, 53 insertions, 2 deletions
diff --git a/sys/arch/amd64/amd64/mp.c b/sys/arch/amd64/amd64/mp.c
index dbee32c..21881b2 100644
--- a/sys/arch/amd64/amd64/mp.c
+++ b/sys/arch/amd64/amd64/mp.c
@@ -81,6 +81,24 @@ cpu_get(uint32_t index)
return ci_list[index];
}
+/*
+ * Grab the CPU stat structured of a specified
+ * processor
+ *
+ * @cpu_index: CPU index number
+ */
+struct sched_cpu *
+cpu_get_stat(uint32_t cpu_index)
+{
+ struct cpu_info *ci;
+
+ if ((ci = cpu_get(cpu_index)) == NULL) {
+ return NULL;
+ }
+
+ return &ci->stat;
+}
+
uint32_t
cpu_count(void)
{
diff --git a/sys/arch/amd64/amd64/proc_machdep.c b/sys/arch/amd64/amd64/proc_machdep.c
index 72c2b56..ad807fe 100644
--- a/sys/arch/amd64/amd64/proc_machdep.c
+++ b/sys/arch/amd64/amd64/proc_machdep.c
@@ -245,6 +245,7 @@ static void
sched_switch_to(struct trapframe *tf, struct proc *td)
{
struct cpu_info *ci;
+ struct sched_cpu *cpustat;
struct pcb *pcbp;
ci = this_cpu();
@@ -253,6 +254,10 @@ sched_switch_to(struct trapframe *tf, struct proc *td)
memcpy(tf, &td->tf, sizeof(*tf));
}
+ /* Update stats */
+ cpustat = &ci->stat;
+ cpustat->nswitch++;
+
ci->curtd = td;
pcbp = &td->pcb;
pmap_switch_vas(pcbp->addrsp);
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index a5f09fb..a047cef 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/proc.h>
+#include <sys/sched.h>
#include <sys/spinlock.h>
#include <machine/tss.h>
@@ -53,6 +54,7 @@ struct cpu_info {
size_t lapic_tmr_freq;
uint8_t irq_mask;
vaddr_t shootdown_va;
+ struct sched_cpu stat;
struct tss_entry *tss;
struct proc *curtd;
struct spinlock lock;
@@ -67,6 +69,8 @@ void cpu_enable_smep(void);
void cpu_disable_smep(void);
struct cpu_info *cpu_get(uint32_t index);
+struct sched_cpu *cpu_get_stat(uint32_t cpu_index);
+
uint32_t cpu_count(void);
void cpu_shootdown_tlb(vaddr_t va);
diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h
index 5b97b68..f6aed9d 100644
--- a/sys/include/sys/limits.h
+++ b/sys/include/sys/limits.h
@@ -35,7 +35,5 @@
#define SSIZE_MAX 32767
#define ARG_MAX 4096
#define CHAR_BIT 8
-#if defined(_KERNEL)
#define CPU_MAX 256
-#endif /* _KERNEL */
#endif /* !_SYS_LIMITS_H_ */
diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h
index d80483a..abc2718 100644
--- a/sys/include/sys/sched.h
+++ b/sys/include/sys/sched.h
@@ -32,6 +32,17 @@
#include <sys/proc.h>
#include <sys/cdefs.h>
+#include <sys/limits.h>
+
+/*
+ * Scheduler CPU information
+ *
+ * @nswitch: Number of context switches
+ * @idle: Number of milliseconds idle
+ */
+struct sched_cpu {
+ uint32_t nswitch;
+};
/*
* Scheduler statistics
@@ -44,6 +55,7 @@ struct sched_stat {
size_t nproc;
uint16_t ncpu;
uint32_t quantum_usec;
+ struct sched_cpu cpus[CPU_MAX];
};
#if defined(_KERNEL)
diff --git a/sys/kern/kern_accnt.c b/sys/kern/kern_accnt.c
index 3b90d9f..cd15863 100644
--- a/sys/kern/kern_accnt.c
+++ b/sys/kern/kern_accnt.c
@@ -66,9 +66,23 @@ ctl_stat_read(struct ctlfs_dev *cdp, struct sio_txn *sio)
void
sched_stat(struct sched_stat *statp)
{
+ struct sched_cpu *cpustat;
+
statp->nproc = atomic_load_64(&g_nthreads);
statp->ncpu = cpu_count();
statp->quantum_usec = DEFAULT_TIMESLICE_USEC;
+
+ /*
+ * Setup the per-cpu info/statistics
+ */
+ for (int i = 0; i < CPU_MAX; ++i) {
+ cpustat = cpu_get_stat(i);
+ if (cpustat == NULL) {
+ break;
+ }
+
+ statp->cpus[i] = *cpustat;
+ }
}
void