PERFORCE change 126517 for review
Marko Zec
zec at FreeBSD.org
Mon Sep 17 09:43:52 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126517
Change 126517 by zec at zec_tpx32 on 2007/09/17 16:43:24
As an experiment, maintain load average accounting on
per-vprocg basis, where a vprocg can be thought of as
something like a jail-style process group in the current
vimage incarnation. Seems to work OK on both VIMAGE and
nooptions VIMAGE kernel configs with SCHED_4BSD. Perhaps
this could be made to work with ULE as well...
Affected files ...
.. //depot/projects/vimage/src/sys/compat/linprocfs/linprocfs.c#11 edit
.. //depot/projects/vimage/src/sys/compat/linux/linux_misc.c#10 edit
.. //depot/projects/vimage/src/sys/kern/kern_synch.c#11 edit
.. //depot/projects/vimage/src/sys/kern/kern_vimage.c#38 edit
.. //depot/projects/vimage/src/sys/kern/sched_4bsd.c#8 edit
.. //depot/projects/vimage/src/sys/kern/tty.c#10 edit
.. //depot/projects/vimage/src/sys/sys/resource.h#4 edit
.. //depot/projects/vimage/src/sys/sys/sched.h#5 edit
.. //depot/projects/vimage/src/sys/sys/vimage.h#38 edit
.. //depot/projects/vimage/src/sys/vm/vm_meter.c#6 edit
.. //depot/projects/vimage/src/usr.sbin/vimage/vimage.c#4 edit
Differences ...
==== //depot/projects/vimage/src/sys/compat/linprocfs/linprocfs.c#11 (text+ko) ====
@@ -502,15 +502,16 @@
static int
linprocfs_doloadavg(PFS_FILL_ARGS)
{
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg);
sbuf_printf(sb,
"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
- (int)(averunnable.ldavg[0] / averunnable.fscale),
- (int)(averunnable.ldavg[0] * 100 / averunnable.fscale % 100),
- (int)(averunnable.ldavg[1] / averunnable.fscale),
- (int)(averunnable.ldavg[1] * 100 / averunnable.fscale % 100),
- (int)(averunnable.ldavg[2] / averunnable.fscale),
- (int)(averunnable.ldavg[2] * 100 / averunnable.fscale % 100),
+ (int)(V_averunnable.ldavg[0] / V_averunnable.fscale),
+ (int)(V_averunnable.ldavg[0] * 100 / V_averunnable.fscale % 100),
+ (int)(V_averunnable.ldavg[1] / V_averunnable.fscale),
+ (int)(V_averunnable.ldavg[1] * 100 / V_averunnable.fscale % 100),
+ (int)(V_averunnable.ldavg[2] / V_averunnable.fscale),
+ (int)(V_averunnable.ldavg[2] * 100 / V_averunnable.fscale % 100),
1, /* number of running tasks */
nprocs, /* number of tasks */
lastpid /* the last pid */
==== //depot/projects/vimage/src/sys/compat/linux/linux_misc.c#10 (text+ko) ====
@@ -125,6 +125,7 @@
int
linux_sysinfo(struct thread *td, struct linux_sysinfo_args *args)
{
+ INIT_VPROCG(td->td_ucred->cr_vimage->v_procg);
struct l_sysinfo sysinfo;
vm_object_t object;
int i, j;
@@ -137,8 +138,8 @@
/* Use the information from the mib to get our load averages */
for (i = 0; i < 3; i++)
- sysinfo.loads[i] = averunnable.ldavg[i] *
- LINUX_SYSINFO_LOADS_SCALE / averunnable.fscale;
+ sysinfo.loads[i] = V_averunnable.ldavg[i] *
+ LINUX_SYSINFO_LOADS_SCALE / V_averunnable.fscale;
sysinfo.totalram = physmem * PAGE_SIZE;
sysinfo.freeram = sysinfo.totalram - cnt.v_wire_count * PAGE_SIZE;
==== //depot/projects/vimage/src/sys/kern/kern_synch.c#11 (text+ko) ====
@@ -78,8 +78,11 @@
static struct callout loadav_callout;
static struct callout lbolt_callout;
+#ifndef VIMAGE
struct loadavg averunnable =
{ {0, 0, 0}, FSCALE }; /* load average, of runnable procs */
+#endif
+
/*
* Constants for averages over 1, 5, and 15 minutes
* when sampling at 5 second intervals.
@@ -521,12 +524,19 @@
int i, nrun;
struct loadavg *avg;
+ VPROCG_ITERLOOP_BEGIN();
+ INIT_VPROCG(vprocg_iter);
+#ifdef VIMAGE
+ nrun = sched_load(vprocg_iter);
+#else
nrun = sched_load();
- avg = &averunnable;
+#endif
+ avg = &V_averunnable;
for (i = 0; i < 3; i++)
avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
+ VPROCG_ITERLOOP_END();
/*
* Schedule the next update to occur after 5 seconds, but add a
==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#38 (text+ko) ====
@@ -39,6 +39,8 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
#include <sys/sockio.h>
#include <sys/sx.h>
#include <sys/vimage.h>
@@ -123,10 +125,8 @@
static u_int last_vi_id = 0;
static u_int last_vnet_id = 0;
-#if 0
static u_int last_vprocg_id = 0;
static u_int last_vcpu_id = 0;
-#endif
static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
@@ -488,6 +488,8 @@
vi_req->vi_id = vip_r->vi_id;
bcopy(&vip_r->vi_name, &vi_req->vi_name,
sizeof (vi_req->vi_name));
+ bcopy(&vip_r->v_procg->_averunnable, &vi_req->averunnable,
+ sizeof (vi_req->averunnable));
vi_req->vi_proc_count = vip_r->v_procg->nprocs;
vi_req->vi_if_count = vip_r->v_vnet->ifccnt;
vi_req->vi_sock_count = vip_r->v_vnet->sockcnt;
@@ -520,6 +522,8 @@
sx_xlock(&allproc_lock);
oldcred->cr_vimage->v_procg->nprocs--;
p->p_ucred->cr_vimage->v_procg->nprocs++;
+ sched_load_reassign(oldcred->cr_vimage->v_procg,
+ newcred->cr_vimage->v_procg);
sx_xunlock(&allproc_lock);
crfree(oldcred);
break;
@@ -606,21 +610,24 @@
if (vprocg == NULL)
panic("vi_alloc: malloc failed for vprocg \"%s\"\n", name);
vip->v_procg = vprocg;
+ vprocg->vprocg_id = last_vprocg_id++;
vcpu = vi_malloc(sizeof(struct vcpu), M_VCPU, M_NOWAIT | M_ZERO);
if (vcpu == NULL)
panic ("vi_alloc: malloc failed for vcpu \"%s\"\n", name);
vip->v_cpu = vcpu;
+ vcpu->vcpu_id = last_vcpu_id++;
- /* Some initialization stuff... */
+ /* Struct vimage initialization */
sprintf(vip->vi_name, "%s", name);
+ /* Struct vprocg initialization - perhaps move to anther place? */
+ V_averunnable.fscale = FSCALE;
+
+ /* Initialize / attach vnet module instances. */
CURVNET_SET_QUIET(vnet);
-
- /* Initialize / attach module instances. */
TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le)
vnet_mod_constructor(vml);
-
CURVNET_RESTORE();
VNET_LIST_LOCK(); /* XXX should lock other lists separately */
==== //depot/projects/vimage/src/sys/kern/sched_4bsd.c#8 (text+ko) ====
@@ -36,6 +36,7 @@
__FBSDID("$FreeBSD: src/sys/kern/sched_4bsd.c,v 1.103 2007/07/18 20:46:05 jeff Exp $");
#include "opt_hwpmc_hooks.h"
+#include "opt_vimage.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -52,6 +53,7 @@
#include <sys/sx.h>
#include <sys/turnstile.h>
#include <sys/umtx.h>
+#include <sys/vimage.h>
#include <machine/pcb.h>
#include <machine/smp.h>
@@ -103,7 +105,9 @@
static struct td_sched td_sched0;
struct mtx sched_lock;
+#ifndef VIMAGE
static int sched_tdcnt; /* Total runnable threads in the system. */
+#endif
static int sched_quantum; /* Roundrobin scheduling quantum in ticks. */
#define SCHED_QUANTUM (hz / 10) /* Default sched quantum */
@@ -229,18 +233,33 @@
#endif
static __inline void
-sched_load_add(void)
+sched_load_add(struct thread *td)
{
- sched_tdcnt++;
+ INIT_VPROCG(td->td_ucred->cr_vimage->v_procg);
+
+ V_sched_tdcnt++;
CTR1(KTR_SCHED, "global load: %d", sched_tdcnt);
}
static __inline void
-sched_load_rem(void)
+sched_load_rem(struct thread *td)
{
- sched_tdcnt--;
+ INIT_VPROCG(td->td_ucred->cr_vimage->v_procg);
+
+ V_sched_tdcnt--;
CTR1(KTR_SCHED, "global load: %d", sched_tdcnt);
}
+
+#ifdef VIMAGE
+void
+sched_load_reassign(struct vprocg *old, struct vprocg *new)
+{
+ /* XXX locking? */
+ old->_sched_tdcnt--;
+ new->_sched_tdcnt++;
+}
+#endif
+
/*
* Arrange to reschedule if necessary, taking the priorities and
* schedulers into account.
@@ -369,7 +388,11 @@
static void
schedcpu(void)
{
+#ifndef VIMAGE
register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]);
+#else
+ #define loadfac loadfactor(p->p_ucred->cr_vimage->v_procg->_averunnable.ldavg[0])
+#endif
struct thread *td;
struct proc *p;
struct td_sched *ts;
@@ -467,6 +490,9 @@
PROC_SUNLOCK(p);
} /* end of process loop */
sx_sunlock(&allproc_lock);
+#ifdef VIMAGE
+#undef loadfac
+#endif
}
/*
@@ -490,10 +516,11 @@
static void
updatepri(struct thread *td)
{
+ INIT_VPROCG(td->td_ucred->cr_vimage->v_procg);
register fixpt_t loadfac;
register unsigned int newcpu;
- loadfac = loadfactor(averunnable.ldavg[0]);
+ loadfac = loadfactor(V_averunnable.ldavg[0]);
if (td->td_slptime > 5 * loadfac)
td->td_estcpu = 0;
else {
@@ -559,7 +586,7 @@
roundrobin(NULL);
/* Account for thread0. */
- sched_load_add();
+ sched_load_add(&thread0);
}
/* External interfaces start here */
@@ -654,7 +681,7 @@
thread_unlock(td);
mtx_lock_spin(&sched_lock);
if ((child->td_proc->p_flag & P_NOLOAD) == 0)
- sched_load_rem();
+ sched_load_rem(td);
mtx_unlock_spin(&sched_lock);
}
@@ -850,7 +877,7 @@
}
if ((p->p_flag & P_NOLOAD) == 0)
- sched_load_rem();
+ sched_load_rem(td);
if (newtd)
newtd->td_flags |= (td->td_flags & TDF_NEEDRESCHED);
@@ -892,7 +919,7 @@
newtd->td_sched->ts_flags |= TSF_DIDRUN;
TD_SET_RUNNING(newtd);
if ((newtd->td_proc->p_flag & P_NOLOAD) == 0)
- sched_load_add();
+ sched_load_add(newtd);
} else {
newtd = choosethread();
}
@@ -1143,7 +1170,7 @@
}
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
- sched_load_add();
+ sched_load_add(td);
runq_add(ts->ts_runq, ts, flags);
}
#else /* SMP */
@@ -1188,7 +1215,7 @@
return;
}
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
- sched_load_add();
+ sched_load_add(td);
runq_add(ts->ts_runq, ts, flags);
maybe_resched(td);
}
@@ -1210,7 +1237,7 @@
curthread->td_proc->p_comm);
if ((td->td_proc->p_flag & P_NOLOAD) == 0)
- sched_load_rem();
+ sched_load_rem(td);
runq_remove(ts->ts_runq, ts);
TD_SET_CAN_RUN(td);
}
@@ -1328,11 +1355,19 @@
thread_unlock(td);
}
+#ifdef VIMAGE
int
+sched_load(struct vprocg *vprocg)
+{
+ return (V_sched_tdcnt);
+}
+#else
+int
sched_load(void)
{
return (sched_tdcnt);
}
+#endif
int
sched_sizeof_proc(void)
==== //depot/projects/vimage/src/sys/kern/tty.c#10 (text+ko) ====
@@ -2534,6 +2534,7 @@
void
ttyinfo(struct tty *tp)
{
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg);
struct timeval utime, stime;
struct proc *p, *pick;
struct thread *td, *picktd;
@@ -2548,7 +2549,7 @@
return;
/* Print load average. */
- load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
+ load = (V_averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
/*
==== //depot/projects/vimage/src/sys/sys/resource.h#4 (text+ko) ====
@@ -153,8 +153,8 @@
#ifdef _KERNEL
+#ifndef VIMAGE
extern struct loadavg averunnable;
-#ifndef VIMAGE
extern long cp_time[CPUSTATES];
#endif
==== //depot/projects/vimage/src/sys/sys/sched.h#5 (text+ko) ====
@@ -63,6 +63,9 @@
#define _SCHED_H_
#ifdef _KERNEL
+
+struct vprocg;
+
/*
* General scheduling info.
*
@@ -72,7 +75,12 @@
* sched_runnable:
* Runnable threads for this processor.
*/
+#ifdef VIMAGE
+int sched_load(struct vprocg *);
+void sched_load_reassign(struct vprocg *, struct vprocg *);
+#else
int sched_load(void);
+#endif
int sched_rr_interval(void);
int sched_runnable(void);
==== //depot/projects/vimage/src/sys/sys/vimage.h#38 (text+ko) ====
@@ -231,6 +231,13 @@
} \
VNET_LIST_UNREF();
+#define VPROCG_ITERLOOP_BEGIN() \
+ struct vprocg *vprocg_iter; \
+ LIST_FOREACH(vprocg_iter, &vprocg_head, vprocg_le) { \
+
+#define VPROCG_ITERLOOP_END() \
+ } \
+
#else /* !VNET_DEBUG */
#define VNET_ASSERT(condition)
@@ -281,6 +288,8 @@
#define VNET_ITERLOOP_BEGIN()
#define VNET_ITERLOOP_END()
#define INIT_VPROCG(arg)
+#define VPROCG_ITERLOOP_BEGIN()
+#define VPROCG_ITERLOOP_END()
#endif /* !VIMAGE */
@@ -290,6 +299,8 @@
#define V_hostname VPROCG(hostname)
#define V_domainname VPROCG(domainname)
#define V_morphing_symlinks VPROCG(morphing_symlinks)
+#define V_averunnable VPROCG(averunnable)
+#define V_sched_tdcnt VPROCG(sched_tdcnt)
#ifdef VIMAGE
void vnet_mod_register(const struct vnet_modinfo *);
@@ -364,10 +375,10 @@
int _morphing_symlinks;
+ struct loadavg _averunnable; /* from kern/kern_synch.c */
+ int _sched_tdcnt; /* from kern/sched_4bsd.c */
+
#if 0
- struct loadavg averunnable; /* from kern/kern_synch.c */
- int nrun;
-
u_int proc_limit; /* max. number of processes */
struct msgbuf *msgbufp;
==== //depot/projects/vimage/src/sys/vm/vm_meter.c#6 (text+ko) ====
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/vm/vm_meter.c,v 1.96 2007/07/27 20:01:21 alc Exp $");
+#include "opt_vimage.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -51,6 +53,7 @@
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <sys/sysctl.h>
+#include <sys/vimage.h>
struct vmmeter cnt;
@@ -76,18 +79,20 @@
static int
sysctl_vm_loadavg(SYSCTL_HANDLER_ARGS)
{
+ INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg);
+
#ifdef SCTL_MASK32
u_int32_t la[4];
if (req->flags & SCTL_MASK32) {
- la[0] = averunnable.ldavg[0];
- la[1] = averunnable.ldavg[1];
- la[2] = averunnable.ldavg[2];
- la[3] = averunnable.fscale;
+ la[0] = V_averunnable.ldavg[0];
+ la[1] = V_averunnable.ldavg[1];
+ la[2] = V_averunnable.ldavg[2];
+ la[3] = V_averunnable.fscale;
return SYSCTL_OUT(req, la, sizeof(la));
} else
#endif
- return SYSCTL_OUT(req, &averunnable, sizeof(averunnable));
+ return SYSCTL_OUT(req, &V_averunnable, sizeof(V_averunnable));
}
SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD,
NULL, 0, sysctl_vm_loadavg, "S,loadavg", "Machine loadaverage history");
==== //depot/projects/vimage/src/usr.sbin/vimage/vimage.c#4 (text+ko) ====
@@ -62,19 +62,17 @@
void vi_print(struct vi_req *vi_req)
{
-#if 0
double lf = 1.0/vi_req->averunnable.fscale;
-#endif
printf ("\"%s\":\n", vi_req->vi_name);
printf (" Processes (current/max): %d/%d\n",
vi_req->vi_proc_count, vi_req->vi_proc_limit);
-#if 0
printf (" load averages: %3.2f, %3.2f, %3.2f\n",
lf * vi_req->averunnable.ldavg[0],
lf * vi_req->averunnable.ldavg[1],
lf * vi_req->averunnable.ldavg[2]);
+#if 0
printf (" CPU usage: %3.2f%% (",
0.0001 * vi_req->cp_time_avg[CP_ALL]);
printf ("%3.2f%% user, ", 0.0001 * vi_req->cp_time_avg[CP_USER]);
More information about the p4-projects
mailing list