Commit a302eb4e authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] ZVC: Overstep counters

Increments and decrements are usually grouped rather than mixed.  We can
optimize the inc and dec functions for that case.

Increment and decrement the counters by 50% more than the threshold in
those cases and set the differential accordingly.  This decreases the need
to update the atomic counters.

The idea came originally from Andrew Morton.  The overstepping alone was
sufficient to address the contention issue found when updating the global
and the per zone counters from 160 processors.

Also remove some code in dec_zone_page_state.
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b63fe1ba
...@@ -190,8 +190,8 @@ static void __inc_zone_state(struct zone *zone, enum zone_stat_item item) ...@@ -190,8 +190,8 @@ static void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
(*p)++; (*p)++;
if (unlikely(*p > STAT_THRESHOLD)) { if (unlikely(*p > STAT_THRESHOLD)) {
zone_page_state_add(*p, zone, item); zone_page_state_add(*p + STAT_THRESHOLD / 2, zone, item);
*p = 0; *p = -STAT_THRESHOLD / 2;
} }
} }
...@@ -209,8 +209,8 @@ void __dec_zone_page_state(struct page *page, enum zone_stat_item item) ...@@ -209,8 +209,8 @@ void __dec_zone_page_state(struct page *page, enum zone_stat_item item)
(*p)--; (*p)--;
if (unlikely(*p < -STAT_THRESHOLD)) { if (unlikely(*p < -STAT_THRESHOLD)) {
zone_page_state_add(*p, zone, item); zone_page_state_add(*p - STAT_THRESHOLD / 2, zone, item);
*p = 0; *p = STAT_THRESHOLD /2;
} }
} }
EXPORT_SYMBOL(__dec_zone_page_state); EXPORT_SYMBOL(__dec_zone_page_state);
...@@ -239,19 +239,9 @@ EXPORT_SYMBOL(inc_zone_page_state); ...@@ -239,19 +239,9 @@ EXPORT_SYMBOL(inc_zone_page_state);
void dec_zone_page_state(struct page *page, enum zone_stat_item item) void dec_zone_page_state(struct page *page, enum zone_stat_item item)
{ {
unsigned long flags; unsigned long flags;
struct zone *zone;
s8 *p;
zone = page_zone(page);
local_irq_save(flags); local_irq_save(flags);
p = diff_pointer(zone, item); __dec_zone_page_state(page, item);
(*p)--;
if (unlikely(*p < -STAT_THRESHOLD)) {
zone_page_state_add(*p, zone, item);
*p = 0;
}
local_irq_restore(flags); local_irq_restore(flags);
} }
EXPORT_SYMBOL(dec_zone_page_state); EXPORT_SYMBOL(dec_zone_page_state);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment