From owner-p4-projects@FreeBSD.ORG Fri Nov 12 17:07:40 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DBA5D106567A; Fri, 12 Nov 2010 17:07:39 +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 9E3E41065670 for ; Fri, 12 Nov 2010 17:07:39 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 895808FC22 for ; Fri, 12 Nov 2010 17:07:39 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id oACH7dvD092957 for ; Fri, 12 Nov 2010 17:07:39 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id oACH7dE1092954 for perforce@freebsd.org; Fri, 12 Nov 2010 17:07:39 GMT (envelope-from trasz@freebsd.org) Date: Fri, 12 Nov 2010 17:07:39 GMT Message-Id: <201011121707.oACH7dE1092954@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 185697 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Nov 2010 17:07:40 -0000 http://p4web.freebsd.org/@@185697?ac=10 Change 185697 by trasz@trasz_victim on 2010/11/12 17:07:14 Move maintenance of cpu usage into a new kproc. This way it's easy to measure how much time is wasted for running it. Affected files ... .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#32 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#52 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#32 (text+ko) ==== @@ -37,15 +37,20 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #include +#include #include #include #include +#include #ifdef HRL #include @@ -590,3 +595,84 @@ #endif container_destroy(&p->p_container); } + +/* + * Stuff below runs from a "containerd" kernel process. + */ +static void +rusage_throttle(struct thread *td, int throttle) +{ + u_char oldpri; + u_char newpri; + int type; + + if (throttle) { + td->td_flags |= TDF_THROTTLED; + newpri = PRI_MIN_IDLE; + type = RTP_PRIO_IDLE; + } else if (td->td_flags & TDF_THROTTLED) { + td->td_flags &= ~TDF_THROTTLED; + newpri = PRI_MIN_TIMESHARE; + type = RTP_PRIO_NORMAL; + } else + return; + + /* Mostly copied from rtp_to_pri(). */ + sched_class(td, type); /* XXX fix */ + oldpri = td->td_user_pri; + sched_user_prio(td, newpri); + if (TD_IS_RUNNING(td) || TD_CAN_RUN(td)) + sched_prio(td, td->td_user_pri); /* XXX dubious */ + if (TD_ON_UPILOCK(td) && oldpri != newpri) + umtx_pi_adjust(td, oldpri); +} + +static void +containerd(void) +{ + int pctcpu; + struct thread *td; + struct proc *p; + struct timeval wallclock; + uint64_t pctcpu_limit; + + for (;;) { + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + pctcpu_limit = rusage_get_limit(p, RUSAGE_PCTCPU); + PROC_SLOCK(p); + pctcpu = 0; + FOREACH_THREAD_IN_PROC(p, td) { + ruxagg(p, td); + thread_lock(td); + pctcpu += sched_pctcpu(td); + /* + * We are making this decision based on data from + * the previous run. The assumption is that this runs + * so often it doesn't matter. + */ + if (pctcpu > pctcpu_limit) + rusage_throttle(td, 1); + else + rusage_throttle(td, 0); + thread_unlock(td); + } + PROC_SUNLOCK(p); + rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime)); + microuptime(&wallclock); + timevalsub(&wallclock, &p->p_stats->p_start); + rusage_set(p, RUSAGE_WALLCLOCK, wallclock.tv_sec * 1000000 + wallclock.tv_usec); + pctcpu = ((pctcpu * 10000 + FSCALE / 2) >> FSHIFT) / 100; + rusage_set(p, RUSAGE_PCTCPU, pctcpu); + } + sx_sunlock(&allproc_lock); + pause("-", hz); + } +} + +static struct kproc_desc containerd_kp = { + "containerd", + containerd, + NULL +}; +SYSINIT(containerd, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST, kproc_start, &containerd_kp); ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#52 (text+ko) ==== @@ -81,11 +81,6 @@ static struct uidinfo *uilookup(uid_t uid); static void ruxagg_locked(struct rusage_ext *rux, struct thread *td); -#ifdef CONTAINERS -static struct callout rusage_cpu_callout; -static struct task rusage_cpu_task; -#endif - /* * Resource controls and accounting. */ @@ -611,89 +606,6 @@ return (error); } -#ifdef CONTAINERS -static void -rusage_cpu_update(void *arg) -{ - - /* - * The rusage_cpu_task_fn() routine may sleep, so we have to put it - * into taskqueue instead of running directly from callout. - */ - taskqueue_enqueue(taskqueue_thread, &rusage_cpu_task); -} - -static void -rusage_throttle(struct thread *td, int throttle) -{ - u_char oldpri; - u_char newpri; - int type; - - if (throttle) { - td->td_flags |= TDF_THROTTLED; - newpri = PRI_MIN_IDLE; - type = RTP_PRIO_IDLE; - } else if (td->td_flags & TDF_THROTTLED) { - td->td_flags &= ~TDF_THROTTLED; - newpri = PRI_MIN_TIMESHARE; - type = RTP_PRIO_NORMAL; - } else - return; - - /* Mostly copied from rtp_to_pri(). */ - sched_class(td, type); /* XXX fix */ - oldpri = td->td_user_pri; - sched_user_prio(td, newpri); - if (TD_IS_RUNNING(td) || TD_CAN_RUN(td)) - sched_prio(td, td->td_user_pri); /* XXX dubious */ - if (TD_ON_UPILOCK(td) && oldpri != newpri) - umtx_pi_adjust(td, oldpri); -} - -static void -rusage_cpu_task_fn(void *arg, int pending) -{ - int pctcpu; - struct thread *td; - struct proc *p; - struct timeval wallclock; - uint64_t pctcpu_limit; - - sx_slock(&allproc_lock); - FOREACH_PROC_IN_SYSTEM(p) { - pctcpu_limit = rusage_get_limit(p, RUSAGE_PCTCPU); - PROC_SLOCK(p); - pctcpu = 0; - FOREACH_THREAD_IN_PROC(p, td) { - ruxagg(p, td); - thread_lock(td); - pctcpu += sched_pctcpu(td); - /* - * We are making this decision based on data from - * the previous run. The assumption is that this runs - * so often it doesn't matter. - */ - if (pctcpu > pctcpu_limit) - rusage_throttle(td, 1); - else - rusage_throttle(td, 0); - thread_unlock(td); - } - PROC_SUNLOCK(p); - rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime)); - microuptime(&wallclock); - timevalsub(&wallclock, &p->p_stats->p_start); - rusage_set(p, RUSAGE_WALLCLOCK, wallclock.tv_sec * 1000000 + wallclock.tv_usec); - pctcpu = ((pctcpu * 10000 + FSCALE / 2) >> FSHIFT) / 100; - rusage_set(p, RUSAGE_PCTCPU, pctcpu); - } - sx_sunlock(&allproc_lock); - - callout_reset(&rusage_cpu_callout, hz, rusage_cpu_update, NULL); -} -#endif - #ifndef HRL static void lim_cb(void *arg) @@ -1378,16 +1290,6 @@ uihashtbl = hashinit(maxproc / 16, M_UIDINFO, &uihash); rw_init(&uihashtbl_lock, "uidinfo hash"); - -#ifdef CONTAINERS - /* - * XXX: Piggybacked for now; in the future it should have - * it's own function. - */ - TASK_INIT(&rusage_cpu_task, 0, rusage_cpu_task_fn, NULL); - callout_init(&rusage_cpu_callout, 1); - callout_reset(&rusage_cpu_callout, hz, rusage_cpu_update, NULL); -#endif } /*