aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-12-20 07:13:21 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:16 -0500
commitd647b36a69bf0a630ebf981bde3c0651e2779e5e (patch)
tree6c8c7ec7feefbc9c966863bc73d576017f833563
parent2caf62f6cae46e36b1c4a1b0f2d9ef82af89cad2 (diff)
[SNMP]: Fix SNMP counters with PREEMPT
The SNMP macros use raw_smp_processor_id() in process context which is illegal because the process may be preempted and then migrated to another CPU. This patch makes it use get_cpu/put_cpu to disable preemption. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/snmp.h21
1 files changed, 17 insertions, 4 deletions
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 9c5793db637..fbb66663a42 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -23,6 +23,7 @@
23 23
24#include <linux/cache.h> 24#include <linux/cache.h>
25#include <linux/snmp.h> 25#include <linux/snmp.h>
26#include <linux/smp.h>
26 27
27/* 28/*
28 * Mibs are stored in array of unsigned long. 29 * Mibs are stored in array of unsigned long.
@@ -135,14 +136,26 @@ struct linux_mib {
135#define SNMP_INC_STATS_BH(mib, field) \ 136#define SNMP_INC_STATS_BH(mib, field) \
136 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++) 137 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++)
137#define SNMP_INC_STATS_USER(mib, field) \ 138#define SNMP_INC_STATS_USER(mib, field) \
138 (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field]++) 139 do { \
140 per_cpu_ptr(mib[1], get_cpu())->mibs[field]++; \
141 put_cpu(); \
142 } while (0)
139#define SNMP_INC_STATS(mib, field) \ 143#define SNMP_INC_STATS(mib, field) \
140 (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++) 144 do { \
145 per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]++; \
146 put_cpu(); \
147 } while (0)
141#define SNMP_DEC_STATS(mib, field) \ 148#define SNMP_DEC_STATS(mib, field) \
142 (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--) 149 do { \
150 per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
151 put_cpu(); \
152 } while (0)
143#define SNMP_ADD_STATS_BH(mib, field, addend) \ 153#define SNMP_ADD_STATS_BH(mib, field, addend) \
144 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) 154 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
145#define SNMP_ADD_STATS_USER(mib, field, addend) \ 155#define SNMP_ADD_STATS_USER(mib, field, addend) \
146 (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field] += addend) 156 do { \
157 per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
158 put_cpu(); \
159 } while (0)
147 160
148#endif 161#endif