Index: linux-2.6.17-rc6-cl/mm/vmstat.c =================================================================== --- linux-2.6.17-rc6-cl.orig/mm/vmstat.c 2006-06-15 12:27:37.528446605 -0700 +++ linux-2.6.17-rc6-cl/mm/vmstat.c 2006-06-15 12:29:29.511756046 -0700 @@ -145,11 +145,11 @@ void __mod_zone_page_state(struct zone * x = delta + *p; if (unlikely(x > STAT_THRESHOLD || x < -STAT_THRESHOLD)) { + x = xchg(*p, 0); zone_page_state_add(x, zone, item); - x = 0; } - - *p = x; + atomic_byte_sub(x , p); + /* If we gang schedule on this then we will bust the s8 ! */ } EXPORT_SYMBOL(__mod_zone_page_state); @@ -191,12 +191,14 @@ EXPORT_SYMBOL(mod_zone_page_state); void __inc_zone_state(struct zone *zone, enum zone_stat_item item) { s8 *p = diff_pointer(zone, item); + int x; - (*p)++; + x = atomic_inc_return(p); + /* If we gang scheduler here then we bust the s8! */ - if (unlikely(*p > STAT_THRESHOLD)) { - zone_page_state_add(*p, zone, item); - *p = 0; + if (unlikely(x > STAT_THRESHOLD)) { + x = xchg(p, 0); + zone_page_state_add(x , zone, item); } } @@ -208,14 +210,15 @@ EXPORT_SYMBOL(__inc_zone_page_state); void __dec_zone_page_state(struct page *page, enum zone_stat_item item) { + int x; struct zone *zone = page_zone(page); s8 *p = diff_pointer(zone, item); - (*p)--; + x = atomic_dec_return(p); - if (unlikely(*p < -STAT_THRESHOLD)) { - zone_page_state_add(*p, zone, item); - *p = 0; + if (unlikely(x < -STAT_THRESHOLD)) { + x = xchg(p, 0); + zone_page_state_add(x, zone, item); } } EXPORT_SYMBOL(__dec_zone_page_state); @@ -235,29 +238,17 @@ void inc_zone_page_state(struct page *pa struct zone *zone; zone = page_zone(page); - local_irq_save(flags); + preempt_disable(); __inc_zone_state(zone, item); - local_irq_restore(flags); + preempt_enable(); } EXPORT_SYMBOL(inc_zone_page_state); void dec_zone_page_state(struct page *page, enum zone_stat_item item) { - unsigned long flags; - struct zone *zone; - s8 *p; - - zone = page_zone(page); - local_irq_save(flags); - p = diff_pointer(zone, item); - - (*p)--; - - if (unlikely(*p < -STAT_THRESHOLD)) { - zone_page_state_add(*p, zone, item); - *p = 0; - } - local_irq_restore(flags); + preempt_disable(); + __dec_zone_page_state(page, item); + preempt_enable(); } EXPORT_SYMBOL(dec_zone_page_state);