setup_per_zone_pages_min(): zone->lock vs. zone->lru_lock
Subsystems (2)
Hi,
is zone->lru_lock really the right lock to take in setup_per_zone_pages_min()? All other functions in mm/page_alloc.c take zone->lock instead, for working with page->lru free-list or PageBuddy().
setup_per_zone_pages_min() eventually calls move_freepages(), which is also manipulating the page->lru free-list and checking for PageBuddy(). Both should be protected by zone->lock instead of zone->lru_lock, if I understood that right, or else there could be a race with the other functions in mm/page_alloc.c.
We ran into a list corruption bug in free_pages_bulk() once, during memory hotplug stress test, but cannot reproduce it easily. So I cannot verify if using zone->lock instead of zone->lru_lock would fix it, but to me it looks like this may be the problem.
Any thoughts?
BTW, I also wonder if a spin_lock_irq() would be enough, instead of spin_lock_irqsave(), because this function should never be called from interrupt context, right?
Thanks,
Gerald
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 17 lines · Gerald Schaefer
Hi,
is
zone->lru_lockreally the right lock to take insetup_per_zone_pages_min()? All other functions inmm/page_alloc.ctakezone->lockinstead, for working withpage->lrufree-list orPageBuddy().
setup_per_zone_pages_min()eventually callsmove_freepages(), which is also manipulating thepage->lrufree-list and checking forPageBuddy(). Both should be protected byzone->lockinstead ofzone->lru_lock, if I understood that right, or else there could be a race with the other functions inmm/page_alloc.c.We ran into a list corruption bug in
free_pages_bulk()once, during memory hotplug stress test, but cannot reproduce it easily. So I cannot verify if usingzone->lockinstead ofzone->lru_lockwould fix it, but to me it looks like this may be the problem.
Quoted 5 lines
Any thoughts?
BTW, I also wonder if a
spin_lock_irq()would be enough, instead ofspin_lock_irqsave(), because this function should never be called from interrupt context, right?
The allocator protects it freelists using zone->lock (as we can see in rmqueue_bulk), so anything which manipulates those should also be using that lock. move_freepages() is scanning the cmap and picking up free pages directly off the free lists, it is expecting those lists to be stable; it would appear to need zone->lock. It does look like setup_per_zone_pages_min() is holding the wrong thing at first look.
-apw
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 6 lines · Andy Whitcroft
The allocator protects it freelists using
zone->lock(as we can see inrmqueue_bulk), so anything which manipulates those should also be using that lock.move_freepages()is scanning the cmap and picking up free pages directly off the free lists, it is expecting those lists to be stable; it would appear to needzone->lock. It does look likesetup_per_zone_pages_min()is holding the wrong thing at first look.
I just noticed that the spin_lock in that function is much older than the call to setup_zone_migrate_reserve(), which then calls move_freepages(). So it seems that the zone->lru_lock there does (did?) have another purpose, maybe protecting zone->present_pages/pages_min/etc.
Looks like the need for a zone->lock (if any) was added later, but I'm not sure if makes sense to take both locks together, or if the lru_lock is still needed at all.
Thanks,
Gerald
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 8 lines · On Mon, 29 Sep 2008 23:20:05 +0200 Gerald Schaefer…
Quoted 6 lines · Andy Whitcroft
The allocator protects it freelists using
zone->lock(as we can see inrmqueue_bulk), so anything which manipulates those should also be using that lock.move_freepages()is scanning the cmap and picking up free pages directly off the free lists, it is expecting those lists to be stable; it would appear to needzone->lock. It does look likesetup_per_zone_pages_min()is holding the wrong thing at first look.
Quoted 5 lines
I just noticed that the
spin_lockin that function is much older than the call tosetup_zone_migrate_reserve(), which then callsmove_freepages(). So it seems that thezone->lru_lockthere does (did?) have another purpose, maybe protecting zone->present_pages/pages_min/etc.
Maybe.
Quoted 4 lines
Looks like the need for a
zone->lock(if any) was added later, but I'm not sure if makes sense to take both locks together, or if thelru_lockis still needed at all.
At first look, replacing zone->lru_lock with zone->lock is enough... This function is an only one function which use zone->lru_lock in page_alloc.c And zone_watermark_ok() which access zone->pages_min/low/high is not under any locks. So, taking zone->lru_lock here doesn't seem to be necessary...
Thanks,
-Kame
Quoted 11 lines
Quoted 8 lines · On Mon, 29 Sep 2008 23:20:05 +0200 Gerald Schaefer…
Quoted 6 lines · Andy Whitcroft
The allocator protects it freelists using
zone->lock(as we can see inrmqueue_bulk), so anything which manipulates those should also be using that lock.move_freepages()is scanning the cmap and picking up free pages directly off the free lists, it is expecting those lists to be stable; it would appear to needzone->lock. It does look likesetup_per_zone_pages_min()is holding the wrong thing at first look.
Quoted 6 lines
Quoted 5 lines
I just noticed that the
spin_lockin that function is much older than the call tosetup_zone_migrate_reserve(), which then callsmove_freepages(). So it seems that thezone->lru_lockthere does (did?) have another purpose, maybe protecting zone->present_pages/pages_min/etc.Maybe.
The zone->lru_lock() have been used before memory hotplug code was implemented. But I can't find any reason why it have been used.
Quoted 9 lines
Quoted 5 lines
Looks like the need for a
zone->lock(if any) was added later, but I'm not sure if makes sense to take both locks together, or if thelru_lockis still needed at all.At first look, replacing
zone->lru_lockwithzone->lockis enough... This function is an only one function which usezone->lru_lockinpage_alloc.cAndzone_watermark_ok()which access zone->pages_min/low/high is not under any locks. So, takingzone->lru_lockhere doesn't seem to be necessary...
I agree.
Bye.
Signature · 8 lines
Yasunori Goto -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 setup_per_zone_pages_min(): take zone->lock instead of zone->lru_lock
This replaces zone->lru_lock in setup_per_zone_pages_min() with zone->lock. There seems to be no need for the lru_lock anymore, but there is a need for zone->lock instead, because that function may call move_freepages() via setup_zone_migrate_reserve().
--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
@@ -4207,7 +4207,7 @@ void setup_per_zone_pages_min(void)for_each_zone (zone) {u64 tmp; -spin_lock_irqsave (&zone->lru_lock, flags); +spin_lock_irqsave (&zone->lock, flags); tmp = (u64 )pages_min * zone->present_pages;do_div (tmp, lowmem_pages);if (is_highmem (zone)) {
@@ -4239,7 +4239,7 @@ void setup_per_zone_pages_min(void) zone->pages_low = zone->pages_min + (tmp >>2 ); zone->pages_high = zone->pages_min + (tmp >>1 );setup_zone_migrate_reserve (zone); -spin_unlock_irqrestore (&zone->lru_lock, flags); +spin_unlock_irqrestore (&zone->lock, flags); }/* update totalreserve_pages */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH] setup_per_zone_pages_min(): take zone->lock instead of zone->lru_lock
Quoted 9 lines · On Wed, 01 Oct 2008 19:39:32 +0200 Gerald Schaefer…
From: Gerald Schaefer <[email protected]>
This replaces
zone->lru_lockinsetup_per_zone_pages_min()withzone->lock. There seems to be no need for thelru_lockanymore, but there is a need forzone->lockinstead, because that function may callmove_freepages()viasetup_zone_migrate_reserve().Signed-off-by Gerald Schaefer <[email protected]>
Thank you!.
Quoted 34 lines
--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)Index:
linux-2.6/mm/page_alloc.c
===================================================================mm/page_alloc.c +2
-3@@ -4207,7 +4207,7 @@ void setup_per_zone_pages_min(void)for_each_zone (zone) {u64 tmp; -spin_lock_irqsave (&zone->lru_lock, flags); +spin_lock_irqsave (&zone->lock, flags); tmp = (u64 )pages_min * zone->present_pages;do_div (tmp, lowmem_pages);if (is_highmem (zone)) {@@ -4239,7 +4239,7 @@ void setup_per_zone_pages_min(void) zone->pages_low = zone->pages_min + (tmp >>2 ); zone->pages_high = zone->pages_min + (tmp >>1 );setup_zone_migrate_reserve (zone); -spin_unlock_irqrestore (&zone->lru_lock, flags); +spin_unlock_irqrestore (&zone->lock, flags); }/* update totalreserve_pages */ --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] setup_per_zone_pages_min(): take zone->lock instead of zone->lru_lock
In reply to Gerald SchaeferThanks!
Quoted 37 lines
From: Gerald Schaefer <[email protected]>
This replaces
zone->lru_lockinsetup_per_zone_pages_min()withzone->lock. There seems to be no need for thelru_lockanymore, but there is a need forzone->lockinstead, because that function may callmove_freepages()viasetup_zone_migrate_reserve().Signed-off-by Gerald Schaefer <[email protected]>--- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)Index:
linux-2.6/mm/page_alloc.c
===================================================================mm/page_alloc.c +2
-2@@ -4207,7 +4207,7 @@ void setup_per_zone_pages_min(void)for_each_zone (zone) {u64 tmp; -spin_lock_irqsave (&zone->lru_lock, flags); +spin_lock_irqsave (&zone->lock, flags); tmp = (u64 )pages_min * zone->present_pages;do_div (tmp, lowmem_pages);if (is_highmem (zone)) {@@ -4239,7 +4239,7 @@ void setup_per_zone_pages_min(void) zone->pages_low = zone->pages_min + (tmp >>2 ); zone->pages_high = zone->pages_min + (tmp >>1 );setup_zone_migrate_reserve (zone); -spin_unlock_irqrestore (&zone->lru_lock, flags); +spin_unlock_irqrestore (&zone->lock, flags); }/* update totalreserve_pages */
Signature · 8 lines
Yasunori Goto -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>