rpms/kernel/devel linux-2.6-posix-timers-sched_time-accumulation.patch, NONE, 1.1.2.1 kernel-2.6.spec, 1.1826.2.3, 1.1826.2.4

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Sat Jan 7 04:16:56 UTC 2006


Author: davej

Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv13001

Modified Files:
      Tag: private-fc5-test2-branch
	kernel-2.6.spec 
Added Files:
      Tag: private-fc5-test2-branch
	linux-2.6-posix-timers-sched_time-accumulation.patch 
Log Message:
Fix posix-cpu-timers sched_time accumulation.



linux-2.6-posix-timers-sched_time-accumulation.patch:
 posix-cpu-timers.c |   13 +------------
 1 files changed, 1 insertion(+), 12 deletions(-)

--- NEW FILE linux-2.6-posix-timers-sched_time-accumulation.patch ---

Message-Id: <20060106.153648.27161028.davem at davemloft.net>
To: linux-kernel at vger.kernel.org
CC: roland at redhat.com, torvalds at osdl.org
Subject: [PATCH]: Fix posix-cpu-timers sched_time accumulation
From: "David S. Miller" <davem at davemloft.net>

I've spent the past 3 days digging into a glibc testsuite failure in
current CVS, specifically libc/rt/tst-cputimer1.c The thr1 and thr2
timers fire too early in the second pass of this test.  The second
pass is noteworthy because it makes use of intervals, whereas the
first pass does not.

All throughout the posix-cpu-timers.c code, the calculation of the
process sched_time sum is implemented roughly as:

	unsigned long long sum;

	sum = tsk->signal->sched_time;
	t = tsk;
	do {
		sum += t->sched_time;
		t = next_thread(t);
	} while (t != tsk);

In fact this is the exact scheme used by check_process_timers().

In the case of check_process_timers(), current->sched_time has just
been updated (via scheduler_tick(), which is invoked by
update_process_times(), which subsequently invokes
run_posix_cpu_timers()) So there is no special processing necessary
wrt. that.

In other contexts, we have to allot for the fact that tsk->sched_time
might be a bit out of date if we are current.  And the
posix-cpu-timers.c code uses current_sched_time() to deal with that.

Unfortunately it does so in an erroneous and inconsistent manner in
one spot which is what results in the early timer firing.

In cpu_clock_sample_group_locked(), it does this:

		cpu->sched = p->signal->sched_time;
		/* Add in each other live thread.  */
		while ((t = next_thread(t)) != p) {
			cpu->sched += t->sched_time;
		}
		if (p->tgid == current->tgid) {
			/*
			 * We're sampling ourselves, so include the
			 * cycles not yet banked.  We still omit
			 * other threads running on other CPUs,
			 * so the total can always be behind as
			 * much as max(nthreads-1,ncpus) * (NSEC_PER_SEC/HZ).
			 */
			cpu->sched += current_sched_time(current);
		} else {
			cpu->sched += p->sched_time;
		}

The problem is the "p->tgid == current->tgid" test.  If "p" is
not current, and the tgids are the same, we will add the process
t->sched_time twice into cpu->sched and omit "p"'s sched_time
which is very very very wrong.

posix-cpu-timers.c has a helper function, sched_ns(p) which takes care
of this, so my fix is to use that here instead of this special tgid
test.

The fact that current can be one of the sub-threads of "p" points out
that we could make things a little bit more accurate, perhaps by using
sched_ns() on every thread we process in these loops.  It also points
out that we don't use the most accurate value for threads in the group
actively running other cpus (and this is mentioned in the comment).

But that is a future enhancement, and this fix here definitely makes
sense.

Signed-off-by: David S. Miller <davem at davemloft.net>

diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index cae4f57..4c68edf 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -238,18 +238,7 @@ static int cpu_clock_sample_group_locked
 		while ((t = next_thread(t)) != p) {
 			cpu->sched += t->sched_time;
 		}
-		if (p->tgid == current->tgid) {
-			/*
-			 * We're sampling ourselves, so include the
-			 * cycles not yet banked.  We still omit
-			 * other threads running on other CPUs,
-			 * so the total can always be behind as
-			 * much as max(nthreads-1,ncpus) * (NSEC_PER_SEC/HZ).
-			 */
-			cpu->sched += current_sched_time(current);
-		} else {
-			cpu->sched += p->sched_time;
-		}
+		cpu->sched += sched_ns(p);
 		break;
 	}
 	return 0;



Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.1826.2.3
retrieving revision 1.1826.2.4
diff -u -r1.1826.2.3 -r1.1826.2.4
--- kernel-2.6.spec	6 Jan 2006 23:32:18 -0000	1.1826.2.3
+++ kernel-2.6.spec	7 Jan 2006 04:16:53 -0000	1.1826.2.4
@@ -367,6 +367,7 @@
 Patch1820: linux-2.6-usbhid-wireless-security-lock.patch
 Patch1830: linux-2.6-w1-hush-debug.patch
 Patch1840: linux-2.6-x86-hp-reboot.patch
+Patch1860: linux-2.6-posix-timers-sched_time-accumulation.patch
 
 # Warn about usage of various obsolete functionality that may go away.
 Patch1900: linux-2.6-obsolete-idescsi-warning.patch
@@ -881,6 +882,8 @@
 %patch1830 -p1
 # Reboot through BIOS on HP laptops.
 %patch1840 -p1
+# Fix posix-cpu-timers sched_time accumulation
+%patch1860 -p1
 
 # Warn about obsolete functionality usage.
 %patch1900 -p1
@@ -1431,6 +1434,7 @@
 - Flip IO scheduler to 'AS' by default again.
   (CFQ has slab corruption bugs right now).
 - Enable nvram driver for x86-64
+- Fix posix-cpu-timers sched_time accumulation.
 
 * Thu Jan  5 2006 Dave Jones <davej at redhat.com>
 - Try to debug some negative pagecount errors.




More information about the fedora-cvs-commits mailing list