aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2008-04-09 19:47:20 +0000
committerPeter Wemm <peter@FreeBSD.org>2008-04-09 19:47:20 +0000
commitd2be7e5a27ef6282df68064679ca945d5d548ae7 (patch)
treed00118ced26acf4e520a9057cde69bd466ce3235 /sys
parentc68355219a376862d43a2b2cd541cff3d40d9b5a (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/linprocfs/linprocfs.c21
-rw-r--r--sys/kern/kern_clock.c73
-rw-r--r--sys/sys/pcpu.h2
-rw-r--r--sys/sys/resource.h2
4 files changed, 87 insertions, 11 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index f86a497ef95f..d605f34b0ba7 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -450,19 +450,28 @@ linprocfs_domtab(PFS_FILL_ARGS)
static int
linprocfs_dostat(PFS_FILL_ARGS)
{
+ struct pcpu *pcpu;
+ long cp_time[CPUSTATES];
+ long *cp;
int i;
+ read_cpu_time(cp_time);
sbuf_printf(sb, "cpu %ld %ld %ld %ld\n",
T2J(cp_time[CP_USER]),
T2J(cp_time[CP_NICE]),
T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/),
T2J(cp_time[CP_IDLE]));
- for (i = 0; i < mp_ncpus; ++i)
+ for (i = 0; i <= mp_maxid; ++i) {
+ if (CPU_ABSENT(i))
+ continue;
+ pcpu = pcpu_find(i);
+ cp = pcpu->pc_cp_time;
sbuf_printf(sb, "cpu%d %ld %ld %ld %ld\n", i,
- T2J(cp_time[CP_USER]) / mp_ncpus,
- T2J(cp_time[CP_NICE]) / mp_ncpus,
- T2J(cp_time[CP_SYS]) / mp_ncpus,
- T2J(cp_time[CP_IDLE]) / mp_ncpus);
+ T2J(cp[CP_USER]),
+ T2J(cp[CP_NICE]),
+ T2J(cp[CP_SYS] /*+ cp[CP_INTR]*/),
+ T2J(cp[CP_IDLE]));
+ }
sbuf_printf(sb,
"disk 0 0 0 0\n"
"page %u %u\n"
@@ -486,9 +495,11 @@ linprocfs_dostat(PFS_FILL_ARGS)
static int
linprocfs_douptime(PFS_FILL_ARGS)
{
+ long cp_time[CPUSTATES];
struct timeval tv;
getmicrouptime(&tv);
+ read_cpu_time(cp_time);
sbuf_printf(sb, "%lld.%02ld %ld.%02ld\n",
(long long)tv.tv_sec, tv.tv_usec / 10000,
T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100);
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index c31d86c65399..76ad4f6f7d7b 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -82,17 +82,18 @@ extern void hardclock_device_poll(void);
static void initclocks(void *dummy);
SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
-/* Some of these don't belong here, but it's easiest to concentrate them. */
-long cp_time[CPUSTATES];
-
static int
sysctl_kern_cp_time(SYSCTL_HANDLER_ARGS)
{
int error;
+ long cp_time[CPUSTATES];
#ifdef SCTL_MASK32
int i;
unsigned int cp_time32[CPUSTATES];
-
+#endif
+
+ read_cpu_time(cp_time);
+#ifdef SCTL_MASK32
if (req->flags & SCTL_MASK32) {
if (!req->oldptr)
return SYSCTL_OUT(req, 0, sizeof(cp_time32));
@@ -112,6 +113,66 @@ sysctl_kern_cp_time(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD,
0,0, sysctl_kern_cp_time, "LU", "CPU time statistics");
+static long empty[CPUSTATES];
+
+static int
+sysctl_kern_cp_times(SYSCTL_HANDLER_ARGS)
+{
+ struct pcpu *pcpu;
+ int error;
+ int i, c;
+ long *cp_time;
+#ifdef SCTL_MASK32
+ unsigned int cp_time32[CPUSTATES];
+#endif
+
+ if (!req->oldptr) {
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32)
+ return SYSCTL_OUT(req, 0, sizeof(cp_time32) * (mp_maxid + 1));
+ else
+#endif
+ return SYSCTL_OUT(req, 0, sizeof(long) * CPUSTATES * (mp_maxid + 1));
+ }
+ for (error = 0, c = 0; error == 0 && c <= mp_maxid; c++) {
+ if (!CPU_ABSENT(c)) {
+ pcpu = pcpu_find(c);
+ cp_time = pcpu->pc_cp_time;
+ } else {
+ cp_time = empty;
+ }
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
+ for (i = 0; i < CPUSTATES; i++)
+ cp_time32[i] = (unsigned int)cp_time[i];
+ error = SYSCTL_OUT(req, cp_time32, sizeof(cp_time32));
+ } else
+#endif
+ error = SYSCTL_OUT(req, cp_time, sizeof(long) * CPUSTATES);
+ }
+ return error;
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD,
+ 0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
+
+void
+read_cpu_time(long *cp_time)
+{
+ struct pcpu *pc;
+ int i, j;
+
+ /* Sum up global cp_time[]. */
+ bzero(cp_time, sizeof(long) * CPUSTATES);
+ for (i = 0; i <= mp_maxid; i++) {
+ if (CPU_ABSENT(i))
+ continue;
+ pc = pcpu_find(i);
+ for (j = 0; j < CPUSTATES; j++)
+ cp_time[j] += pc->pc_cp_time[j];
+ }
+}
+
#ifdef SW_WATCHDOG
#include <sys/watchdog.h>
@@ -410,11 +471,12 @@ statclock(frame)
struct thread *td;
struct proc *p;
long rss;
+ long *cp_time;
td = curthread;
p = td->td_proc;
- mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
+ cp_time = (long *)PCPU_PTR(cp_time);
if (CLKF_USERMODE(frame)) {
/*
* Charge the time as appropriate.
@@ -457,6 +519,7 @@ statclock(frame)
CTR4(KTR_SCHED, "statclock: %p(%s) prio %d stathz %d",
td, td->td_proc->p_comm, td->td_priority, (stathz)?stathz:hz);
+ mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
sched_clock(td);
/* Update resource usage integrals and maximums. */
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index c5c59447e7ba..fd76cad17283 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -43,6 +43,7 @@
#include <sys/queue.h>
#include <sys/vmmeter.h>
+#include <sys/resource.h>
#include <machine/pcpu.h>
struct pcb;
@@ -73,6 +74,7 @@ struct pcpu {
#endif
PCPU_MD_FIELDS;
struct vmmeter pc_cnt; /* VM stats counters */
+ long pc_cp_time[CPUSTATES]; /* statclock ticks */
struct device *pc_device;
};
diff --git a/sys/sys/resource.h b/sys/sys/resource.h
index ccb21648f5e8..9c9fb15236f6 100644
--- a/sys/sys/resource.h
+++ b/sys/sys/resource.h
@@ -156,7 +156,7 @@ struct loadavg {
#ifdef _KERNEL
extern struct loadavg averunnable;
-extern long cp_time[CPUSTATES];
+void read_cpu_time(long *cp_time); /* Writes array of CPUSTATES */
#else