Bug 644903
Summary: | Kernel divide by zero in find_busiest_group | |||
---|---|---|---|---|
Product: | Red Hat Enterprise Linux 6 | Reporter: | William Cohen <wcohen> | |
Component: | kernel | Assignee: | Larry Woodman <lwoodman> | |
Status: | CLOSED ERRATA | QA Contact: | Red Hat Kernel QE team <kernel-qe> | |
Severity: | high | Docs Contact: | ||
Priority: | low | |||
Version: | 6.0 | CC: | arozansk, gbeshers, lwoodman | |
Target Milestone: | rc | |||
Target Release: | --- | |||
Hardware: | All | |||
OS: | Linux | |||
Whiteboard: | ||||
Fixed In Version: | kernel-2.6.32-85.el6 | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | ||
Clone Of: | ||||
: | 771416 (view as bug list) | Environment: | ||
Last Closed: | 2011-05-19 12:40:10 UTC | Type: | --- | |
Regression: | --- | Mount Type: | --- | |
Documentation: | --- | CRM: | ||
Verified Versions: | Category: | --- | ||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
Cloudforms Team: | --- | Target Upstream Version: | ||
Embargoed: | ||||
Bug Depends On: | ||||
Bug Blocks: | 771416 |
Description
William Cohen
2010-10-20 15:14:09 UTC
Not sure exacly how this happened but we should never blindly divide in the kernel without making sure the denominator is not zero! diff --git a/kernel/sched.c b/kernel/sched.c index f8e5a25..df7753d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4162,7 +4162,8 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, if (sds.this_load >= sds.max_load) goto out_balanced; - sds.avg_load = (SCHED_LOAD_SCALE * sds.total_load) / sds.total_pwr; + sds.avg_load = (SCHED_LOAD_SCALE * sds.total_load) / + (sds.total_pwr?sds.total_pwr:1); if (sds.this_load >= sds.avg_load) goto out_balanced; After talking with Peterz & Ingo about this, the problem seems to be scale_rt_power() can return a negative value to update_cpu_power() which sets the sdg->cpu_power. This potentially allows the arithmetic sum of all sdg->cpu_power within a schedule domain(total_pwr) to be zero. Finally find_busiest_group() uses total_pwr as the denominator when calculating the load average: sds.avg_load = (SCHED_LOAD_SCALE * sds.total_load) / sds.total_pwr; This fix is part of commit aa483808516ca5cacfa0e5849691f64fec25828e but we cant include all of it because it relies on other commits that really break the kABI. So we are only including the hunk that prevents scale_rt_power() from returning a negative value. -------------------------------------------------------------------------------------------------- commit aa483808516ca5cacfa0e5849691f64fec25828e Author: Venkatesh Pallipadi <venki> Date: Mon Oct 4 17:03:22 2010 -0700 sched: Remove irq time from available CPU power The idea was suggested by Peter Zijlstra here: http://marc.info/?l=linux-kernel&m=127476934517534&w=2 irq time is technically not available to the tasks running on the CPU. This patch removes irq time from CPU power piggybacking on sched_rt_avg_update(). Tested this by keeping CPU X busy with a network intensive task having 75% oa a single CPU irq processing (hard+soft) on a 4-way system. And start seven cycle soakers on the system. Without this change, there will be two tasks on each CPU. With this change, there is a single task on irq busy CPU X and remaining 7 tasks are spread around among other 3 CPUs. Signed-off-by: Venkatesh Pallipadi <venki> Signed-off-by: Peter Zijlstra <a.p.zijlstra> LKML-Reference: <1286237003-12406-8-git-send-email-venki> Signed-off-by: Ingo Molnar <mingo> -------------------------------------------------------------------------------------------------------------- diff --git a/kernel/sched.c b/kernel/sched.c index f8e5a25..60ef538 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3611,7 +3611,13 @@ unsigned long scale_rt_power(int cpu) sched_avg_update(rq); total = sched_avg_period() + (rq->clock - rq->age_stamp); - available = total - rq->rt_avg; + + if (unlikely(total < rq->rt_avg)) { + /* Ensures that power won't end up being negative */ + available = 0; + } else { + available = total - rq->rt_avg; + } if (unlikely((s64)total < SCHED_LOAD_SCALE)) total = SCHED_LOAD_SCALE; This request was evaluated by Red Hat Product Management for inclusion in a Red Hat Enterprise Linux maintenance release. Product Management has requested further review of this request by Red Hat Engineering, for potential inclusion in a Red Hat Enterprise Linux Update release for currently deployed products. This request is not yet committed for inclusion in an Update release. Patch(es) available on kernel-2.6.32-89.el6 *** Bug 669795 has been marked as a duplicate of this bug. *** An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHSA-2011-0542.html |