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