Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Nov 2010 16:08:26 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 185695 for review
Message-ID:  <201011121608.oACG8Q9j080477@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@185695?ac=10

Change 185695 by trasz@trasz_victim on 2010/11/12 16:07:20

	Implement simple CPU throttling (%cpu limit).

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#51 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#26 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_resource.c#51 (text+ko) ====

@@ -624,21 +624,60 @@
 }
 
 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);

==== //depot/projects/soc2009/trasz_limits/sys/sys/proc.h#26 (text+ko) ====

@@ -354,7 +354,7 @@
 #define	TDF_NEEDRESCHED	0x00010000 /* Thread needs to yield. */
 #define	TDF_NEEDSIGCHK	0x00020000 /* Thread may need signal delivery. */
 #define	TDF_NOLOAD	0x00040000 /* Ignore during load avg calculations. */
-#define	TDF_UNUSED19	0x00080000 /* --available-- */
+#define	TDF_THROTTLED	0x00080000 /* Throttled due to %cpu usage */
 #define	TDF_THRWAKEUP	0x00100000 /* Libthr thread must not suspend itself. */
 #define	TDF_UNUSED21	0x00200000 /* --available-- */
 #define	TDF_SWAPINREQ	0x00400000 /* Swapin request due to wakeup. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011121608.oACG8Q9j080477>