rpms/kernel/F-11 linux-2.6-posix-timers-fix-clock-monotonicity.patch, NONE, 1.1 linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch, NONE, 1.1 linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch, NONE, 1.1 kernel.spec, 1.1537, 1.1538

Chuck Ebbert cebbert at fedoraproject.org
Tue Apr 14 13:05:30 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12322

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-posix-timers-fix-clock-monotonicity.patch 
	linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch 
	linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch 
Log Message:
Timer fixes headed for -stable

linux-2.6-posix-timers-fix-clock-monotonicity.patch:

--- NEW FILE linux-2.6-posix-timers-fix-clock-monotonicity.patch ---
From: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Date: Tue, 31 Mar 2009 07:56:03 +0000 (+0900)
Subject: posixtimers, sched: Fix posix clock monotonicity
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=c5f8d99585d7b5b7e857fabf8aefd0174903a98c

posixtimers, sched: Fix posix clock monotonicity

Impact: Regression fix (against clock_gettime() backwarding bug)

This patch re-introduces a couple of functions, task_sched_runtime
and thread_group_sched_runtime, which was once removed at the
time of 2.6.28-rc1.

These functions protect the sampling of thread/process clock with
rq lock.  This rq lock is required not to update rq->clock during
the sampling.

i.e.
  The clock_gettime() may return
   ((accounted runtime before update) + (delta after update))
  that is less than what it should be.

v2 -> v3:
	- Rename static helper function __task_delta_exec()
	  to do_task_delta_exec() since -tip tree already has
	  a __task_delta_exec() of different version.

v1 -> v2:
	- Revises comments of function and patch description.
	- Add note about accuracy of thread group's runtime.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Acked-by: Peter Zijlstra <a.p.zijlstra at chello.nl>
Cc: stable at kernel.org	[2.6.28.x][2.6.29.x]
LKML-Reference: <49D1CC93.4080401 at jp.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
---

diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index fa07da9..4318c30 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -224,7 +224,7 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
 		cpu->cpu = virt_ticks(p);
 		break;
 	case CPUCLOCK_SCHED:
-		cpu->sched = p->se.sum_exec_runtime + task_delta_exec(p);
+		cpu->sched = task_sched_runtime(p);
 		break;
 	}
 	return 0;
@@ -240,18 +240,19 @@ static int cpu_clock_sample_group(const clockid_t which_clock,
 {
 	struct task_cputime cputime;
 
-	thread_group_cputime(p, &cputime);
 	switch (CPUCLOCK_WHICH(which_clock)) {
 	default:
 		return -EINVAL;
 	case CPUCLOCK_PROF:
+		thread_group_cputime(p, &cputime);
 		cpu->cpu = cputime_add(cputime.utime, cputime.stime);
 		break;
 	case CPUCLOCK_VIRT:
+		thread_group_cputime(p, &cputime);
 		cpu->cpu = cputime.utime;
 		break;
 	case CPUCLOCK_SCHED:
-		cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
+		cpu->sched = thread_group_sched_runtime(p);
 		break;
 	}
 	return 0;
diff --git a/kernel/sched.c b/kernel/sched.c
index cc397aa..c8d7f17 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4139,9 +4139,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
 EXPORT_PER_CPU_SYMBOL(kstat);
 
 /*
- * Return any ns on the sched_clock that have not yet been banked in
+ * Return any ns on the sched_clock that have not yet been accounted in
  * @p in case that task is currently running.
+ *
+ * Called with task_rq_lock() held on @rq.
  */
+static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
+{
+	u64 ns = 0;
+
+	if (task_current(rq, p)) {
+		update_rq_clock(rq);
+		ns = rq->clock - p->se.exec_start;
+		if ((s64)ns < 0)
+			ns = 0;
+	}
+
+	return ns;
+}
+
 unsigned long long task_delta_exec(struct task_struct *p)
 {
 	unsigned long flags;
@@ -4149,16 +4165,49 @@ unsigned long long task_delta_exec(struct task_struct *p)
 	u64 ns = 0;
 
 	rq = task_rq_lock(p, &flags);
+	ns = do_task_delta_exec(p, rq);
+	task_rq_unlock(rq, &flags);
 
-	if (task_current(rq, p)) {
-		u64 delta_exec;
+	return ns;
+}
 
-		update_rq_clock(rq);
-		delta_exec = rq->clock - p->se.exec_start;
-		if ((s64)delta_exec > 0)
-			ns = delta_exec;
-	}
+/*
+ * Return accounted runtime for the task.
+ * In case the task is currently running, return the runtime plus current's
+ * pending runtime that have not been accounted yet.
+ */
+unsigned long long task_sched_runtime(struct task_struct *p)
+{
+	unsigned long flags;
+	struct rq *rq;
+	u64 ns = 0;
+
+	rq = task_rq_lock(p, &flags);
+	ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
+	task_rq_unlock(rq, &flags);
+
+	return ns;
+}
 
+/*
+ * Return sum_exec_runtime for the thread group.
+ * In case the task is currently running, return the sum plus current's
+ * pending runtime that have not been accounted yet.
+ *
+ * Note that the thread group might have other running tasks as well,
+ * so the return value not includes other pending runtime that other
+ * running tasks might have.
+ */
+unsigned long long thread_group_sched_runtime(struct task_struct *p)
+{
+	struct task_cputime totals;
+	unsigned long flags;
+	struct rq *rq;
+	u64 ns;
+
+	rq = task_rq_lock(p, &flags);
+	thread_group_cputime(p, &totals);
+	ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq);
 	task_rq_unlock(rq, &flags);
 
 	return ns;

linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch:

--- NEW FILE linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch ---
From: Oleg Nesterov <oleg at redhat.com>
Date: Mon, 23 Mar 2009 19:34:11 +0000 (+0100)
Subject: posix timers: fix RLIMIT_CPU && fork()
X-Git-Tag: v2.6.30-rc1~657^2^4
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=37bebc70d7ad4144c571d74500db3bb26ec0c0eb

posix timers: fix RLIMIT_CPU && fork()

See http://bugzilla.kernel.org/show_bug.cgi?id=12911

copy_signal() copies signal->rlim, but RLIMIT_CPU is "lost". Because
posix_cpu_timers_init_group() sets cputime_expires.prof_exp = 0 and thus
fastpath_timer_check() returns false unless we have other cpu timers.

This is the minimal fix for 2.6.29 (tested) and 2.6.28. The patch is not
optimal, we need further cleanups here. With this patch update_rlimit_cpu()
is not really needed, but I don't think it should be removed.

The proper fix (I think) is:

	- set_process_cpu_timer() should just start the cputimer->running
	  logic (it does), no need to change cputime_expires.xxx_exp

	- posix_cpu_timers_init_group() should set ->running when needed

	- fastpath_timer_check() can check ->running instead of
	  task_cputime_zero(signal->cputime_expires)

Reported-by: Peter Lojkin <ia6432 at inbox.ru>
Signed-off-by: Oleg Nesterov <oleg at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Roland McGrath <roland at redhat.com>
Cc: <stable at kernel.org> [for 2.6.29.x]
LKML-Reference: <20090323193411.GA17514 at redhat.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
---

diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index e976e50..8e5d9a6 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -1370,7 +1370,8 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
 		if (task_cputime_expired(&group_sample, &sig->cputime_expires))
 			return 1;
 	}
-	return 0;
+
+	return sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY;
 }
 
 /*

linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch:

--- NEW FILE linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch ---
From: Oleg Nesterov <oleg at redhat.com>
Date: Fri, 27 Mar 2009 00:06:10 +0000 (+0100)
Subject: posix-timers: fix RLIMIT_CPU && setitimer(CPUCLOCK_PROF)
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8f2e586567b1bad72dac7c3810fe9a2ef7117506

posix-timers: fix RLIMIT_CPU && setitimer(CPUCLOCK_PROF)

update_rlimit_cpu() tries to optimize out set_process_cpu_timer() in case
when we already have CPUCLOCK_PROF timer which should expire first. But it
uses cputime_lt() instead of cputime_gt().

Test case:

	int main(void)
	{
		struct itimerval it = {
			.it_value = { .tv_sec = 1000 },
		};

		assert(!setitimer(ITIMER_PROF, &it, NULL));

		struct rlimit rl = {
			.rlim_cur = 1,
			.rlim_max = 1,
		};

		assert(!setrlimit(RLIMIT_CPU, &rl));

		for (;;)
			;

		return 0;
	}

Without this patch, the task is not killed as RLIMIT_CPU demands.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
Acked-by: Peter Zijlstra <peterz at infradead.org>
Cc: Peter Lojkin <ia6432 at inbox.ru>
Cc: Roland McGrath <roland at redhat.com>
Cc: stable at kernel.org
LKML-Reference: <20090327000610.GA10108 at redhat.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
---

diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 8e5d9a6..bb53185 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -18,7 +18,7 @@ void update_rlimit_cpu(unsigned long rlim_new)
 
 	cputime = secs_to_cputime(rlim_new);
 	if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
-	    cputime_lt(current->signal->it_prof_expires, cputime)) {
+	    cputime_gt(current->signal->it_prof_expires, cputime)) {
 		spin_lock_irq(&current->sighand->siglock);
 		set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
 		spin_unlock_irq(&current->sighand->siglock);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1537
retrieving revision 1.1538
diff -u -r1.1537 -r1.1538
--- kernel.spec	14 Apr 2009 12:07:20 -0000	1.1537
+++ kernel.spec	14 Apr 2009 13:04:59 -0000	1.1538
@@ -716,11 +716,16 @@
 
 Patch5000: linux-2.6-add-qcserial.patch
 
+# patches headed for -stable
 # fix oops in md raid1 (#495550)
 Patch6000: linux-2.6-md-raid1-dont-assume-new-bvecs-are-init.patch
-
-# patches headed for -stable
+# fix duplicated flags value
 Patch7000: linux-2.6-mm-define-unique-value-for-as_unevictable.patch
+# fix posix clock monotonicity
+Patch7001: linux-2.6-posix-timers-fix-clock-monotonicity.patch
+# make RLIMIT_CPU work again
+Patch7002: linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch
+Patch7003: linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch
 
 Patch9001: revert-fix-modules_install-via-nfs.patch
 
@@ -1342,6 +1347,9 @@
 # patches headed for -stable
 ApplyPatch linux-2.6-md-raid1-dont-assume-new-bvecs-are-init.patch
 ApplyPatch linux-2.6-mm-define-unique-value-for-as_unevictable.patch
+ApplyPatch linux-2.6-posix-timers-fix-clock-monotonicity.patch
+ApplyPatch linux-2.6-posix-timers-fix-rlimit_cpu-fork.patch
+ApplyPatch linux-2.6-posix-timers-fix-rlimit_cpu-setitimer.patch
 
 # revert 8b249b6856f16f09b0e5b79ce5f4d435e439b9d6
 ApplyPatch revert-fix-modules_install-via-nfs.patch
@@ -1938,6 +1946,9 @@
 
 %changelog
 * Tue Apr 14 2009 Chuck Ebbert <cebbert at redhat.com>
+- Timer fixes headed for -stable
+
+* Tue Apr 14 2009 Chuck Ebbert <cebbert at redhat.com>
 - Fix duplicated flag value in pagemap.h (-stable patch)
 
 * Tue Apr 14 2009 Chuck Ebbert <cebbert at redhat.com>




More information about the fedora-extras-commits mailing list