diff options
Diffstat (limited to 'features/rt/mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch')
-rw-r--r-- | features/rt/mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/features/rt/mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch b/features/rt/mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch new file mode 100644 index 00000000..cdffd95d --- /dev/null +++ b/features/rt/mm-vmstat-Protect-per-cpu-variables-with-preempt-dis.patch @@ -0,0 +1,144 @@ +From 3032c5b7a5a91389d663bd54367df7ed1a92a7a6 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar <mingo@elte.hu> +Date: Fri, 3 Jul 2009 08:30:13 -0500 +Subject: [PATCH 085/191] mm/vmstat: Protect per cpu variables with preempt + disable on RT + +Disable preemption on -RT for the vmstat code. On vanila the code runs in +IRQ-off regions while on -RT it is not. "preempt_disable" ensures that the +same ressources is not updated in parallel due to preemption. + +Signed-off-by: Ingo Molnar <mingo@elte.hu> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +--- + include/linux/vmstat.h | 4 ++++ + mm/vmstat.c | 12 ++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index 506d625163a1..09a7e4c714b8 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -63,7 +63,9 @@ DECLARE_PER_CPU(struct vm_event_state, vm_event_states); + */ + static inline void __count_vm_event(enum vm_event_item item) + { ++ preempt_disable_rt(); + raw_cpu_inc(vm_event_states.event[item]); ++ preempt_enable_rt(); + } + + static inline void count_vm_event(enum vm_event_item item) +@@ -73,7 +75,9 @@ static inline void count_vm_event(enum vm_event_item item) + + static inline void __count_vm_events(enum vm_event_item item, long delta) + { ++ preempt_disable_rt(); + raw_cpu_add(vm_event_states.event[item], delta); ++ preempt_enable_rt(); + } + + static inline void count_vm_events(enum vm_event_item item, long delta) +diff --git a/mm/vmstat.c b/mm/vmstat.c +index 74b2c374b86c..4ef7b8a8f5ce 100644 +--- a/mm/vmstat.c ++++ b/mm/vmstat.c +@@ -321,6 +321,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, + long x; + long t; + ++ preempt_disable_rt(); + x = delta + __this_cpu_read(*p); + + t = __this_cpu_read(pcp->stat_threshold); +@@ -330,6 +331,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, + x = 0; + } + __this_cpu_write(*p, x); ++ preempt_enable_rt(); + } + EXPORT_SYMBOL(__mod_zone_page_state); + +@@ -352,6 +354,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, + delta >>= PAGE_SHIFT; + } + ++ preempt_disable_rt(); + x = delta + __this_cpu_read(*p); + + t = __this_cpu_read(pcp->stat_threshold); +@@ -361,6 +364,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, + x = 0; + } + __this_cpu_write(*p, x); ++ preempt_enable_rt(); + } + EXPORT_SYMBOL(__mod_node_page_state); + +@@ -393,6 +397,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + s8 __percpu *p = pcp->vm_stat_diff + item; + s8 v, t; + ++ preempt_disable_rt(); + v = __this_cpu_inc_return(*p); + t = __this_cpu_read(pcp->stat_threshold); + if (unlikely(v > t)) { +@@ -401,6 +406,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + zone_page_state_add(v + overstep, zone, item); + __this_cpu_write(*p, -overstep); + } ++ preempt_enable_rt(); + } + + void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -411,6 +417,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) + + VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); + ++ preempt_disable_rt(); + v = __this_cpu_inc_return(*p); + t = __this_cpu_read(pcp->stat_threshold); + if (unlikely(v > t)) { +@@ -419,6 +426,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) + node_page_state_add(v + overstep, pgdat, item); + __this_cpu_write(*p, -overstep); + } ++ preempt_enable_rt(); + } + + void __inc_zone_page_state(struct page *page, enum zone_stat_item item) +@@ -439,6 +447,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + s8 __percpu *p = pcp->vm_stat_diff + item; + s8 v, t; + ++ preempt_disable_rt(); + v = __this_cpu_dec_return(*p); + t = __this_cpu_read(pcp->stat_threshold); + if (unlikely(v < - t)) { +@@ -447,6 +456,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + zone_page_state_add(v - overstep, zone, item); + __this_cpu_write(*p, overstep); + } ++ preempt_enable_rt(); + } + + void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -457,6 +467,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) + + VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); + ++ preempt_disable_rt(); + v = __this_cpu_dec_return(*p); + t = __this_cpu_read(pcp->stat_threshold); + if (unlikely(v < - t)) { +@@ -465,6 +476,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) + node_page_state_add(v - overstep, pgdat, item); + __this_cpu_write(*p, overstep); + } ++ preempt_enable_rt(); + } + + void __dec_zone_page_state(struct page *page, enum zone_stat_item item) +-- +2.19.1 + |