diff options
author | Andrew Morton <akpm@osdl.org> | 2006-05-15 12:43:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-15 14:20:55 -0400 |
commit | ac924c6034d9095f95ee889f7e31bbb9145da0c2 (patch) | |
tree | 2db4fc64a008ff2b81a0faf381d8c21ccc5006b2 /mm | |
parent | 5afdbd6e84c7fbdaa7cfde4cbee0d3a5f4f56da2 (diff) |
[PATCH] setup_per_zone_pages_min() overflow fix
As pointed out in http://bugzilla.kernel.org/show_bug.cgi?id=6490, this
function can experience overflows on 32-bit machines, causing our response to
changed values of min_free_kbytes to go whacky.
Fixing it efficiently is all too hard, so fix it with 64-bit math instead.
Cc: Ake Sandgren <ake.sandgren@hpc2n.umu.se>
Cc: Martin Bligh <mbligh@google.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ea77c999047e..813b4ec1298a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/mempolicy.h> | 39 | #include <linux/mempolicy.h> |
40 | 40 | ||
41 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
42 | #include <asm/div64.h> | ||
42 | #include "internal.h" | 43 | #include "internal.h" |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -2566,9 +2567,11 @@ void setup_per_zone_pages_min(void) | |||
2566 | } | 2567 | } |
2567 | 2568 | ||
2568 | for_each_zone(zone) { | 2569 | for_each_zone(zone) { |
2569 | unsigned long tmp; | 2570 | u64 tmp; |
2571 | |||
2570 | spin_lock_irqsave(&zone->lru_lock, flags); | 2572 | spin_lock_irqsave(&zone->lru_lock, flags); |
2571 | tmp = (pages_min * zone->present_pages) / lowmem_pages; | 2573 | tmp = (u64)pages_min * zone->present_pages; |
2574 | do_div(tmp, lowmem_pages); | ||
2572 | if (is_highmem(zone)) { | 2575 | if (is_highmem(zone)) { |
2573 | /* | 2576 | /* |
2574 | * __GFP_HIGH and PF_MEMALLOC allocations usually don't | 2577 | * __GFP_HIGH and PF_MEMALLOC allocations usually don't |
@@ -2595,8 +2598,8 @@ void setup_per_zone_pages_min(void) | |||
2595 | zone->pages_min = tmp; | 2598 | zone->pages_min = tmp; |
2596 | } | 2599 | } |
2597 | 2600 | ||
2598 | zone->pages_low = zone->pages_min + tmp / 4; | 2601 | zone->pages_low = zone->pages_min + (tmp >> 2); |
2599 | zone->pages_high = zone->pages_min + tmp / 2; | 2602 | zone->pages_high = zone->pages_min + (tmp >> 1); |
2600 | spin_unlock_irqrestore(&zone->lru_lock, flags); | 2603 | spin_unlock_irqrestore(&zone->lru_lock, flags); |
2601 | } | 2604 | } |
2602 | 2605 | ||