aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/vmstat.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 8f62f17ee1c7..3ad909d9600f 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -167,18 +167,20 @@ static void refresh_zone_stat_thresholds(void)
167void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, 167void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
168 int delta) 168 int delta)
169{ 169{
170 struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset); 170 struct per_cpu_pageset __percpu *pcp = zone->pageset;
171 171 s8 __percpu *p = pcp->vm_stat_diff + item;
172 s8 *p = pcp->vm_stat_diff + item;
173 long x; 172 long x;
173 long t;
174
175 x = delta + __this_cpu_read(*p);
174 176
175 x = delta + *p; 177 t = __this_cpu_read(pcp->stat_threshold);
176 178
177 if (unlikely(x > pcp->stat_threshold || x < -pcp->stat_threshold)) { 179 if (unlikely(x > t || x < -t)) {
178 zone_page_state_add(x, zone, item); 180 zone_page_state_add(x, zone, item);
179 x = 0; 181 x = 0;
180 } 182 }
181 *p = x; 183 __this_cpu_write(*p, x);
182} 184}
183EXPORT_SYMBOL(__mod_zone_page_state); 185EXPORT_SYMBOL(__mod_zone_page_state);
184 186
@@ -221,16 +223,19 @@ EXPORT_SYMBOL(mod_zone_page_state);
221 */ 223 */
222void __inc_zone_state(struct zone *zone, enum zone_stat_item item) 224void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
223{ 225{
224 struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset); 226 struct per_cpu_pageset __percpu *pcp = zone->pageset;
225 s8 *p = pcp->vm_stat_diff + item; 227 s8 __percpu *p = pcp->vm_stat_diff + item;
228 s8 v, t;
226 229
227 (*p)++; 230 __this_cpu_inc(*p);
228 231
229 if (unlikely(*p > pcp->stat_threshold)) { 232 v = __this_cpu_read(*p);
230 int overstep = pcp->stat_threshold / 2; 233 t = __this_cpu_read(pcp->stat_threshold);
234 if (unlikely(v > t)) {
235 s8 overstep = t >> 1;
231 236
232 zone_page_state_add(*p + overstep, zone, item); 237 zone_page_state_add(v + overstep, zone, item);
233 *p = -overstep; 238 __this_cpu_write(*p, -overstep);
234 } 239 }
235} 240}
236 241
@@ -242,16 +247,19 @@ EXPORT_SYMBOL(__inc_zone_page_state);
242 247
243void __dec_zone_state(struct zone *zone, enum zone_stat_item item) 248void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
244{ 249{
245 struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset); 250 struct per_cpu_pageset __percpu *pcp = zone->pageset;
246 s8 *p = pcp->vm_stat_diff + item; 251 s8 __percpu *p = pcp->vm_stat_diff + item;
252 s8 v, t;
247 253
248 (*p)--; 254 __this_cpu_dec(*p);
249 255
250 if (unlikely(*p < - pcp->stat_threshold)) { 256 v = __this_cpu_read(*p);
251 int overstep = pcp->stat_threshold / 2; 257 t = __this_cpu_read(pcp->stat_threshold);
258 if (unlikely(v < - t)) {
259 s8 overstep = t >> 1;
252 260
253 zone_page_state_add(*p - overstep, zone, item); 261 zone_page_state_add(v - overstep, zone, item);
254 *p = overstep; 262 __this_cpu_write(*p, overstep);
255 } 263 }
256} 264}
257 265