Skip to contentSkip to conversation

sched: Fix "divide error: 0000" in find_busiest_group

PATCH In review Terry Loftin 2 participants 5 messages Jul 19, 2011 x86

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 sched: Fix "divide error: 0000" in find_busiest_group

Add a check to sched_avg_update() to detect and reset age_stamp if the clock value has wrapped. Because __cycles_2_ns() includes an offset to account for start up time, the clock may not wrap to zero, so use the current clock value instead.

---

kernel/sched.c +2 -0
index 18d38e4..b39cae1 100644
@@ -1256,6 +1256,8 @@ static void sched_avg_update(struct rq *rq)
 {
 	s64 period = sched_avg_period();
 
+	if (unlikely(rq->age_stamp > rq->clock))
+		rq->age_stamp = rq->clock;
 	while ((s64)(rq->clock - rq->age_stamp) > period) {
 		/*
 		 * Inline assembly required to prevent the compiler
#1 lore raw
Quoted 4 lines · Terry Loftin

Add a check to sched_avg_update() to detect and reset age_stamp if the clock value has wrapped. Because __cycles_2_ns() includes an offset to account for start up time, the clock may not wrap to zero, so use the current clock value instead.

So you're running on a platform (unspecified) where we use a raw sched_clock() that is buggy. Again, you're fixing symptoms not causes.

Quoted 16 lines

---

kernel/sched.c +2 -0
index 18d38e4..b39cae1 100644
@@ -1256,6 +1256,8 @@ static void sched_avg_update(struct rq *rq)
 {
 	s64 period = sched_avg_period();
 
+	if (unlikely(rq->age_stamp > rq->clock))
+		rq->age_stamp = rq->clock;
 	while ((s64)(rq->clock - rq->age_stamp) > period) {
 		/*
 		 * Inline assembly required to prevent the compiler
#2 lore raw
Quoted 9 lines · Peter Zijlstra
Quoted 4 lines · Terry Loftin

Add a check to sched_avg_update() to detect and reset age_stamp if the clock value has wrapped. Because __cycles_2_ns() includes an offset to account for start up time, the clock may not wrap to zero, so use the current clock value instead.

So you're running on a platform (unspecified) where we use a raw sched_clock() that is buggy. Again, you're fixing symptoms not causes.

This x86_64. This is the actual cause, unless the rq->clock value should never roll, in which case, the clock roll is the actual cause and you can disregard these patches.

-T

Quoted 19 lines
Quoted 16 lines

---

kernel/sched.c +2 -0
index 18d38e4..b39cae1 100644
@@ -1256,6 +1256,8 @@ static void sched_avg_update(struct rq *rq)
 {
 	s64 period = sched_avg_period();
 
+	if (unlikely(rq->age_stamp > rq->clock))
+		rq->age_stamp = rq->clock;
 	while ((s64)(rq->clock - rq->age_stamp) > period) {
 		/*
 		 * Inline assembly required to prevent the compiler
#3 lore raw
Quoted 6 lines · Terry Loftin
Quoted 3 lines

So you're running on a platform (unspecified) where we use a raw sched_clock() that is buggy. Again, you're fixing symptoms not causes.

This x86_64. This is the actual cause, unless the rq->clock value should never roll, in which case, the clock roll is the actual cause and you can disregard these patches.

Its supposed to roll over on the full 64bit, and I think x86_64 only suffers this if you have sched_clock_stable set to 1.

So I think the correct fix is disabling that logic for now. John Stultz was working on some patches to fix __cycles_2_ns().

Something like the below perhaps.

---
 arch/x86/kernel/cpu/intel.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/intel.c +0 -2
index 1edf5ba..dba0482 100644
@@ -91,8 +91,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 	if (c->x86_power & (1 << 8)) {
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-		if (!check_tsc_unstable())
-			sched_clock_stable = 1;
 	}
 
 	/*
#4 lore raw
Quoted 8 lines · Peter Zijlstra
Quoted 6 lines · Terry Loftin
Quoted 3 lines

So you're running on a platform (unspecified) where we use a raw sched_clock() that is buggy. Again, you're fixing symptoms not causes.

This x86_64. This is the actual cause, unless the rq->clock value should never roll, in which case, the clock roll is the actual cause and you can disregard these patches.

Quoted 7 lines

Its supposed to roll over on the full 64bit, and I think x86_64 only suffers this if you have sched_clock_stable set to 1.

So I think the correct fix is disabling that logic for now. John Stultz was working on some patches to fix __cycles_2_ns().

Something like the below perhaps.

OK - this would also avoid the problem I came across. Thank you for your time.

-T

Quoted 20 lines
---
 arch/x86/kernel/cpu/intel.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/intel.c +0 -2
index 1edf5ba..dba0482 100644
@@ -91,8 +91,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 	if (c->x86_power & (1 << 8)) {
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-		if (!check_tsc_unstable())
-			sched_clock_stable = 1;
 	}
 
 	/*