32 bit overflow in mm/page_alloc.c

Bug #44782 reported by ake sandgren
8
Affects Status Importance Assigned to Milestone
linux-restricted-modules-2.6.15 (Ubuntu)
Fix Released
Undecided
Unassigned
linux-source-2.6.15 (Ubuntu)
Fix Released
Medium
Unassigned

Bug Description

Binary package hint: linux-source-2.6.15

This patch has already been entered into latest -mm kernel and since it is trivial we would like to see it in dappers 2.6.15 if possible.

============

The patch titled

     setup_per_zone_pages_min() overflow fix

has been added to the -mm tree. Its filename is

     setup_per_zone_pages_min-overflow-fix.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

From: Andrew Morton <email address hidden>

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 <email address hidden>
Cc: Martin Bligh <email address hidden>
Signed-off-by: Andrew Morton <email address hidden>
---

 mm/page_alloc.c | 10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff -puN mm/page_alloc.c~setup_per_zone_pages_min-overflow-fix mm/page_alloc.c
--- 25/mm/page_alloc.c~setup_per_zone_pages_min-overflow-fix Tue May 9 13:56:14 2006
+++ 25-akpm/mm/page_alloc.c Tue May 9 13:57:46 2006
@@ -2635,9 +2635,11 @@ void setup_per_zone_pages_min(void)
        }

        for_each_zone(zone) {
- unsigned long tmp;
+ u64 tmp;
+
                spin_lock_irqsave(&zone->lru_lock, flags);
- tmp = (pages_min * zone->present_pages) / lowmem_pages;
+ tmp = (u64)pages_min * zone->present_pages;
+ do_div(tmp, lowmem_pages);
                if (is_highmem(zone)) {
                        /*
                         * __GFP_HIGH and PF_MEMALLOC allocations usually don't
@@ -2664,8 +2666,8 @@ void setup_per_zone_pages_min(void)
                        zone->pages_min = tmp;
                }

- zone->pages_low = zone->pages_min + tmp / 4;
- zone->pages_high = zone->pages_min + tmp / 2;
+ zone->pages_low = zone->pages_min + tmp >> 2;
+ zone->pages_high = zone->pages_min + tmp >> 1;
                spin_unlock_irqrestore(&zone->lru_lock, flags);
        }

Changed in linux-source-2.6.15:
status: Unconfirmed → Fix Committed
Changed in linux-source-2.6.15:
status: Fix Committed → Fix Released
Changed in linux-restricted-modules-2.6.15:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.