From owner-p4-projects@FreeBSD.ORG Mon Sep 17 16:43:52 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 29CFD16A469; Mon, 17 Sep 2007 16:43:52 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E5F1E16A420 for ; Mon, 17 Sep 2007 16:43:51 +0000 (UTC) (envelope-from zec@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E06FE13C459 for ; Mon, 17 Sep 2007 16:43:51 +0000 (UTC) (envelope-from zec@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l8HGhp8b029899 for ; Mon, 17 Sep 2007 16:43:51 GMT (envelope-from zec@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l8HGhptr029896 for perforce@freebsd.org; Mon, 17 Sep 2007 16:43:51 GMT (envelope-from zec@FreeBSD.org) Date: Mon, 17 Sep 2007 16:43:51 GMT Message-Id: <200709171643.l8HGhptr029896@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to zec@FreeBSD.org using -f From: Marko Zec To: Perforce Change Reviews Cc: Subject: PERFORCE change 126517 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Sep 2007 16:43:52 -0000 http://perforce.freebsd.org/chv.cgi?CH=126517 Change 126517 by zec@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 #include #include +#include +#include #include #include #include @@ -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 #include @@ -52,6 +53,7 @@ #include #include #include +#include #include #include @@ -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 __FBSDID("$FreeBSD: src/sys/vm/vm_meter.c,v 1.96 2007/07/27 20:01:21 alc Exp $"); +#include "opt_vimage.h" + #include #include #include @@ -51,6 +53,7 @@ #include #include #include +#include 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]);