diff options
Diffstat (limited to 'include/net/snmp.h')
-rw-r--r-- | include/net/snmp.h | 86 |
1 files changed, 33 insertions, 53 deletions
diff --git a/include/net/snmp.h b/include/net/snmp.h index 479083a78b0..8f0f9ac0307 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h | |||
@@ -116,57 +116,51 @@ struct linux_xfrm_mib { | |||
116 | unsigned long mibs[LINUX_MIB_XFRMMAX]; | 116 | unsigned long mibs[LINUX_MIB_XFRMMAX]; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /* | 119 | #define SNMP_ARRAY_SZ 1 |
120 | * FIXME: On x86 and some other CPUs the split into user and softirq parts | 120 | |
121 | * is not needed because addl $1,memory is atomic against interrupts (but | ||
122 | * atomic_inc would be overkill because of the lock cycles). Wants new | ||
123 | * nonlocked_atomic_inc() primitives -AK | ||
124 | */ | ||
125 | #define DEFINE_SNMP_STAT(type, name) \ | 121 | #define DEFINE_SNMP_STAT(type, name) \ |
126 | __typeof__(type) __percpu *name[2] | 122 | __typeof__(type) __percpu *name[SNMP_ARRAY_SZ] |
127 | #define DEFINE_SNMP_STAT_ATOMIC(type, name) \ | 123 | #define DEFINE_SNMP_STAT_ATOMIC(type, name) \ |
128 | __typeof__(type) *name | 124 | __typeof__(type) *name |
129 | #define DECLARE_SNMP_STAT(type, name) \ | 125 | #define DECLARE_SNMP_STAT(type, name) \ |
130 | extern __typeof__(type) __percpu *name[2] | 126 | extern __typeof__(type) __percpu *name[SNMP_ARRAY_SZ] |
131 | |||
132 | #define SNMP_STAT_BHPTR(name) (name[0]) | ||
133 | #define SNMP_STAT_USRPTR(name) (name[1]) | ||
134 | 127 | ||
135 | #define SNMP_INC_STATS_BH(mib, field) \ | 128 | #define SNMP_INC_STATS_BH(mib, field) \ |
136 | __this_cpu_inc(mib[0]->mibs[field]) | 129 | __this_cpu_inc(mib[0]->mibs[field]) |
130 | |||
137 | #define SNMP_INC_STATS_USER(mib, field) \ | 131 | #define SNMP_INC_STATS_USER(mib, field) \ |
138 | this_cpu_inc(mib[1]->mibs[field]) | 132 | irqsafe_cpu_inc(mib[0]->mibs[field]) |
133 | |||
139 | #define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \ | 134 | #define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \ |
140 | atomic_long_inc(&mib->mibs[field]) | 135 | atomic_long_inc(&mib->mibs[field]) |
136 | |||
141 | #define SNMP_INC_STATS(mib, field) \ | 137 | #define SNMP_INC_STATS(mib, field) \ |
142 | this_cpu_inc(mib[!in_softirq()]->mibs[field]) | 138 | irqsafe_cpu_inc(mib[0]->mibs[field]) |
139 | |||
143 | #define SNMP_DEC_STATS(mib, field) \ | 140 | #define SNMP_DEC_STATS(mib, field) \ |
144 | this_cpu_dec(mib[!in_softirq()]->mibs[field]) | 141 | irqsafe_cpu_dec(mib[0]->mibs[field]) |
142 | |||
145 | #define SNMP_ADD_STATS_BH(mib, field, addend) \ | 143 | #define SNMP_ADD_STATS_BH(mib, field, addend) \ |
146 | __this_cpu_add(mib[0]->mibs[field], addend) | 144 | __this_cpu_add(mib[0]->mibs[field], addend) |
145 | |||
147 | #define SNMP_ADD_STATS_USER(mib, field, addend) \ | 146 | #define SNMP_ADD_STATS_USER(mib, field, addend) \ |
148 | this_cpu_add(mib[1]->mibs[field], addend) | 147 | irqsafe_cpu_add(mib[0]->mibs[field], addend) |
148 | |||
149 | #define SNMP_ADD_STATS(mib, field, addend) \ | 149 | #define SNMP_ADD_STATS(mib, field, addend) \ |
150 | this_cpu_add(mib[!in_softirq()]->mibs[field], addend) | 150 | irqsafe_cpu_add(mib[0]->mibs[field], addend) |
151 | /* | 151 | /* |
152 | * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" | 152 | * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" |
153 | * to make @ptr a non-percpu pointer. | 153 | * to make @ptr a non-percpu pointer. |
154 | */ | 154 | */ |
155 | #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ | 155 | #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ |
156 | do { \ | 156 | do { \ |
157 | __typeof__(*mib[0]) *ptr; \ | 157 | irqsafe_cpu_inc(mib[0]->mibs[basefield##PKTS]); \ |
158 | preempt_disable(); \ | 158 | irqsafe_cpu_add(mib[0]->mibs[basefield##OCTETS], addend); \ |
159 | ptr = this_cpu_ptr((mib)[!in_softirq()]); \ | ||
160 | ptr->mibs[basefield##PKTS]++; \ | ||
161 | ptr->mibs[basefield##OCTETS] += addend;\ | ||
162 | preempt_enable(); \ | ||
163 | } while (0) | 159 | } while (0) |
164 | #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ | 160 | #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ |
165 | do { \ | 161 | do { \ |
166 | __typeof__(*mib[0]) *ptr = \ | 162 | __this_cpu_inc(mib[0]->mibs[basefield##PKTS]); \ |
167 | __this_cpu_ptr((mib)[0]); \ | 163 | __this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend); \ |
168 | ptr->mibs[basefield##PKTS]++; \ | ||
169 | ptr->mibs[basefield##OCTETS] += addend;\ | ||
170 | } while (0) | 164 | } while (0) |
171 | 165 | ||
172 | 166 | ||
@@ -179,40 +173,20 @@ struct linux_xfrm_mib { | |||
179 | ptr->mibs[field] += addend; \ | 173 | ptr->mibs[field] += addend; \ |
180 | u64_stats_update_end(&ptr->syncp); \ | 174 | u64_stats_update_end(&ptr->syncp); \ |
181 | } while (0) | 175 | } while (0) |
176 | |||
182 | #define SNMP_ADD_STATS64_USER(mib, field, addend) \ | 177 | #define SNMP_ADD_STATS64_USER(mib, field, addend) \ |
183 | do { \ | 178 | do { \ |
184 | __typeof__(*mib[0]) *ptr; \ | 179 | local_bh_disable(); \ |
185 | preempt_disable(); \ | 180 | SNMP_ADD_STATS64_BH(mib, field, addend); \ |
186 | ptr = __this_cpu_ptr((mib)[1]); \ | 181 | local_bh_enable(); \ |
187 | u64_stats_update_begin(&ptr->syncp); \ | ||
188 | ptr->mibs[field] += addend; \ | ||
189 | u64_stats_update_end(&ptr->syncp); \ | ||
190 | preempt_enable(); \ | ||
191 | } while (0) | 182 | } while (0) |
183 | |||
192 | #define SNMP_ADD_STATS64(mib, field, addend) \ | 184 | #define SNMP_ADD_STATS64(mib, field, addend) \ |
193 | do { \ | 185 | SNMP_ADD_STATS64_USER(mib, field, addend) |
194 | __typeof__(*mib[0]) *ptr; \ | 186 | |
195 | preempt_disable(); \ | ||
196 | ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ | ||
197 | u64_stats_update_begin(&ptr->syncp); \ | ||
198 | ptr->mibs[field] += addend; \ | ||
199 | u64_stats_update_end(&ptr->syncp); \ | ||
200 | preempt_enable(); \ | ||
201 | } while (0) | ||
202 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1) | 187 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1) |
203 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1) | 188 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1) |
204 | #define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) | 189 | #define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) |
205 | #define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ | ||
206 | do { \ | ||
207 | __typeof__(*mib[0]) *ptr; \ | ||
208 | preempt_disable(); \ | ||
209 | ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ | ||
210 | u64_stats_update_begin(&ptr->syncp); \ | ||
211 | ptr->mibs[basefield##PKTS]++; \ | ||
212 | ptr->mibs[basefield##OCTETS] += addend; \ | ||
213 | u64_stats_update_end(&ptr->syncp); \ | ||
214 | preempt_enable(); \ | ||
215 | } while (0) | ||
216 | #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \ | 190 | #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \ |
217 | do { \ | 191 | do { \ |
218 | __typeof__(*mib[0]) *ptr; \ | 192 | __typeof__(*mib[0]) *ptr; \ |
@@ -222,6 +196,12 @@ struct linux_xfrm_mib { | |||
222 | ptr->mibs[basefield##OCTETS] += addend; \ | 196 | ptr->mibs[basefield##OCTETS] += addend; \ |
223 | u64_stats_update_end(&ptr->syncp); \ | 197 | u64_stats_update_end(&ptr->syncp); \ |
224 | } while (0) | 198 | } while (0) |
199 | #define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ | ||
200 | do { \ | ||
201 | local_bh_disable(); \ | ||
202 | SNMP_UPD_PO_STATS64_BH(mib, basefield, addend); \ | ||
203 | local_bh_enable(); \ | ||
204 | } while (0) | ||
225 | #else | 205 | #else |
226 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_INC_STATS_BH(mib, field) | 206 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_INC_STATS_BH(mib, field) |
227 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_INC_STATS_USER(mib, field) | 207 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_INC_STATS_USER(mib, field) |