diff options
Diffstat (limited to 'include/net/snmp.h')
| -rw-r--r-- | include/net/snmp.h | 120 |
1 files changed, 89 insertions, 31 deletions
diff --git a/include/net/snmp.h b/include/net/snmp.h index f0d756f2ac99..a0e61806d480 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * - name of entries. | 32 | * - name of entries. |
| 33 | */ | 33 | */ |
| 34 | struct snmp_mib { | 34 | struct snmp_mib { |
| 35 | char *name; | 35 | const char *name; |
| 36 | int entry; | 36 | int entry; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| @@ -47,31 +47,17 @@ struct snmp_mib { | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /* | 49 | /* |
| 50 | * We use all unsigned longs. Linux will soon be so reliable that even | 50 | * We use unsigned longs for most mibs but u64 for ipstats. |
| 51 | * these will rapidly get too small 8-). Seriously consider the IpInReceives | ||
| 52 | * count on the 20Gb/s + networks people expect in a few years time! | ||
| 53 | */ | 51 | */ |
| 54 | 52 | #include <linux/u64_stats_sync.h> | |
| 55 | /* | ||
| 56 | * The rule for padding: | ||
| 57 | * Best is power of two because then the right structure can be found by a | ||
| 58 | * simple shift. The structure should be always cache line aligned. | ||
| 59 | * gcc needs n=alignto(cachelinesize, popcnt(sizeof(bla_mib))) shift/add | ||
| 60 | * instructions to emulate multiply in case it is not power-of-two. | ||
| 61 | * Currently n is always <=3 for all sizes so simple cache line alignment | ||
| 62 | * is enough. | ||
| 63 | * | ||
| 64 | * The best solution would be a global CPU local area , especially on 64 | ||
| 65 | * and 128byte cacheline machine it makes a *lot* of sense -AK | ||
| 66 | */ | ||
| 67 | |||
| 68 | #define __SNMP_MIB_ALIGN__ ____cacheline_aligned | ||
| 69 | 53 | ||
| 70 | /* IPstats */ | 54 | /* IPstats */ |
| 71 | #define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX | 55 | #define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX |
| 72 | struct ipstats_mib { | 56 | struct ipstats_mib { |
| 73 | unsigned long mibs[IPSTATS_MIB_MAX]; | 57 | /* mibs[] must be first field of struct ipstats_mib */ |
| 74 | } __SNMP_MIB_ALIGN__; | 58 | u64 mibs[IPSTATS_MIB_MAX]; |
| 59 | struct u64_stats_sync syncp; | ||
| 60 | }; | ||
| 75 | 61 | ||
| 76 | /* ICMP */ | 62 | /* ICMP */ |
| 77 | #define ICMP_MIB_DUMMY __ICMP_MIB_MAX | 63 | #define ICMP_MIB_DUMMY __ICMP_MIB_MAX |
| @@ -79,36 +65,36 @@ struct ipstats_mib { | |||
| 79 | 65 | ||
| 80 | struct icmp_mib { | 66 | struct icmp_mib { |
| 81 | unsigned long mibs[ICMP_MIB_MAX]; | 67 | unsigned long mibs[ICMP_MIB_MAX]; |
| 82 | } __SNMP_MIB_ALIGN__; | 68 | }; |
| 83 | 69 | ||
| 84 | #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX | 70 | #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX |
| 85 | struct icmpmsg_mib { | 71 | struct icmpmsg_mib { |
| 86 | unsigned long mibs[ICMPMSG_MIB_MAX]; | 72 | unsigned long mibs[ICMPMSG_MIB_MAX]; |
| 87 | } __SNMP_MIB_ALIGN__; | 73 | }; |
| 88 | 74 | ||
| 89 | /* ICMP6 (IPv6-ICMP) */ | 75 | /* ICMP6 (IPv6-ICMP) */ |
| 90 | #define ICMP6_MIB_MAX __ICMP6_MIB_MAX | 76 | #define ICMP6_MIB_MAX __ICMP6_MIB_MAX |
| 91 | struct icmpv6_mib { | 77 | struct icmpv6_mib { |
| 92 | unsigned long mibs[ICMP6_MIB_MAX]; | 78 | unsigned long mibs[ICMP6_MIB_MAX]; |
| 93 | } __SNMP_MIB_ALIGN__; | 79 | }; |
| 94 | 80 | ||
| 95 | #define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX | 81 | #define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX |
| 96 | struct icmpv6msg_mib { | 82 | struct icmpv6msg_mib { |
| 97 | unsigned long mibs[ICMP6MSG_MIB_MAX]; | 83 | unsigned long mibs[ICMP6MSG_MIB_MAX]; |
| 98 | } __SNMP_MIB_ALIGN__; | 84 | }; |
| 99 | 85 | ||
| 100 | 86 | ||
| 101 | /* TCP */ | 87 | /* TCP */ |
| 102 | #define TCP_MIB_MAX __TCP_MIB_MAX | 88 | #define TCP_MIB_MAX __TCP_MIB_MAX |
| 103 | struct tcp_mib { | 89 | struct tcp_mib { |
| 104 | unsigned long mibs[TCP_MIB_MAX]; | 90 | unsigned long mibs[TCP_MIB_MAX]; |
| 105 | } __SNMP_MIB_ALIGN__; | 91 | }; |
| 106 | 92 | ||
| 107 | /* UDP */ | 93 | /* UDP */ |
| 108 | #define UDP_MIB_MAX __UDP_MIB_MAX | 94 | #define UDP_MIB_MAX __UDP_MIB_MAX |
| 109 | struct udp_mib { | 95 | struct udp_mib { |
| 110 | unsigned long mibs[UDP_MIB_MAX]; | 96 | unsigned long mibs[UDP_MIB_MAX]; |
| 111 | } __SNMP_MIB_ALIGN__; | 97 | }; |
| 112 | 98 | ||
| 113 | /* Linux */ | 99 | /* Linux */ |
| 114 | #define LINUX_MIB_MAX __LINUX_MIB_MAX | 100 | #define LINUX_MIB_MAX __LINUX_MIB_MAX |
| @@ -129,9 +115,9 @@ struct linux_xfrm_mib { | |||
| 129 | * nonlocked_atomic_inc() primitives -AK | 115 | * nonlocked_atomic_inc() primitives -AK |
| 130 | */ | 116 | */ |
| 131 | #define DEFINE_SNMP_STAT(type, name) \ | 117 | #define DEFINE_SNMP_STAT(type, name) \ |
| 132 | __typeof__(type) *name[2] | 118 | __typeof__(type) __percpu *name[2] |
| 133 | #define DECLARE_SNMP_STAT(type, name) \ | 119 | #define DECLARE_SNMP_STAT(type, name) \ |
| 134 | extern __typeof__(type) *name[2] | 120 | extern __typeof__(type) __percpu *name[2] |
| 135 | 121 | ||
| 136 | #define SNMP_STAT_BHPTR(name) (name[0]) | 122 | #define SNMP_STAT_BHPTR(name) (name[0]) |
| 137 | #define SNMP_STAT_USRPTR(name) (name[1]) | 123 | #define SNMP_STAT_USRPTR(name) (name[1]) |
| @@ -148,9 +134,15 @@ struct linux_xfrm_mib { | |||
| 148 | __this_cpu_add(mib[0]->mibs[field], addend) | 134 | __this_cpu_add(mib[0]->mibs[field], addend) |
| 149 | #define SNMP_ADD_STATS_USER(mib, field, addend) \ | 135 | #define SNMP_ADD_STATS_USER(mib, field, addend) \ |
| 150 | this_cpu_add(mib[1]->mibs[field], addend) | 136 | this_cpu_add(mib[1]->mibs[field], addend) |
| 137 | #define SNMP_ADD_STATS(mib, field, addend) \ | ||
| 138 | this_cpu_add(mib[!in_softirq()]->mibs[field], addend) | ||
| 139 | /* | ||
| 140 | * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" | ||
| 141 | * to make @ptr a non-percpu pointer. | ||
| 142 | */ | ||
| 151 | #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ | 143 | #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ |
| 152 | do { \ | 144 | do { \ |
| 153 | __typeof__(mib[0]) ptr; \ | 145 | __typeof__(*mib[0]) *ptr; \ |
| 154 | preempt_disable(); \ | 146 | preempt_disable(); \ |
| 155 | ptr = this_cpu_ptr((mib)[!in_softirq()]); \ | 147 | ptr = this_cpu_ptr((mib)[!in_softirq()]); \ |
| 156 | ptr->mibs[basefield##PKTS]++; \ | 148 | ptr->mibs[basefield##PKTS]++; \ |
| @@ -159,9 +151,75 @@ struct linux_xfrm_mib { | |||
| 159 | } while (0) | 151 | } while (0) |
| 160 | #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ | 152 | #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ |
| 161 | do { \ | 153 | do { \ |
| 162 | __typeof__(mib[0]) ptr = \ | 154 | __typeof__(*mib[0]) *ptr = \ |
| 163 | __this_cpu_ptr((mib)[!in_softirq()]); \ | 155 | __this_cpu_ptr((mib)[!in_softirq()]); \ |
| 164 | ptr->mibs[basefield##PKTS]++; \ | 156 | ptr->mibs[basefield##PKTS]++; \ |
| 165 | ptr->mibs[basefield##OCTETS] += addend;\ | 157 | ptr->mibs[basefield##OCTETS] += addend;\ |
| 166 | } while (0) | 158 | } while (0) |
| 159 | |||
| 160 | |||
| 161 | #if BITS_PER_LONG==32 | ||
| 162 | |||
| 163 | #define SNMP_ADD_STATS64_BH(mib, field, addend) \ | ||
| 164 | do { \ | ||
| 165 | __typeof__(*mib[0]) *ptr = __this_cpu_ptr((mib)[0]); \ | ||
| 166 | u64_stats_update_begin(&ptr->syncp); \ | ||
| 167 | ptr->mibs[field] += addend; \ | ||
| 168 | u64_stats_update_end(&ptr->syncp); \ | ||
| 169 | } while (0) | ||
| 170 | #define SNMP_ADD_STATS64_USER(mib, field, addend) \ | ||
| 171 | do { \ | ||
| 172 | __typeof__(*mib[0]) *ptr; \ | ||
| 173 | preempt_disable(); \ | ||
| 174 | ptr = __this_cpu_ptr((mib)[1]); \ | ||
| 175 | u64_stats_update_begin(&ptr->syncp); \ | ||
| 176 | ptr->mibs[field] += addend; \ | ||
| 177 | u64_stats_update_end(&ptr->syncp); \ | ||
| 178 | preempt_enable(); \ | ||
| 179 | } while (0) | ||
| 180 | #define SNMP_ADD_STATS64(mib, field, addend) \ | ||
| 181 | do { \ | ||
| 182 | __typeof__(*mib[0]) *ptr; \ | ||
| 183 | preempt_disable(); \ | ||
| 184 | ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ | ||
| 185 | u64_stats_update_begin(&ptr->syncp); \ | ||
| 186 | ptr->mibs[field] += addend; \ | ||
| 187 | u64_stats_update_end(&ptr->syncp); \ | ||
| 188 | preempt_enable(); \ | ||
| 189 | } while (0) | ||
| 190 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1) | ||
| 191 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1) | ||
| 192 | #define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) | ||
| 193 | #define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ | ||
| 194 | do { \ | ||
| 195 | __typeof__(*mib[0]) *ptr; \ | ||
| 196 | preempt_disable(); \ | ||
| 197 | ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ | ||
| 198 | u64_stats_update_begin(&ptr->syncp); \ | ||
| 199 | ptr->mibs[basefield##PKTS]++; \ | ||
| 200 | ptr->mibs[basefield##OCTETS] += addend; \ | ||
| 201 | u64_stats_update_end(&ptr->syncp); \ | ||
| 202 | preempt_enable(); \ | ||
| 203 | } while (0) | ||
| 204 | #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \ | ||
| 205 | do { \ | ||
| 206 | __typeof__(*mib[0]) *ptr; \ | ||
| 207 | ptr = __this_cpu_ptr((mib)[!in_softirq()]); \ | ||
| 208 | u64_stats_update_begin(&ptr->syncp); \ | ||
| 209 | ptr->mibs[basefield##PKTS]++; \ | ||
| 210 | ptr->mibs[basefield##OCTETS] += addend; \ | ||
| 211 | u64_stats_update_end(&ptr->syncp); \ | ||
| 212 | } while (0) | ||
| 213 | #else | ||
| 214 | #define SNMP_INC_STATS64_BH(mib, field) SNMP_INC_STATS_BH(mib, field) | ||
| 215 | #define SNMP_INC_STATS64_USER(mib, field) SNMP_INC_STATS_USER(mib, field) | ||
| 216 | #define SNMP_INC_STATS64(mib, field) SNMP_INC_STATS(mib, field) | ||
| 217 | #define SNMP_DEC_STATS64(mib, field) SNMP_DEC_STATS(mib, field) | ||
| 218 | #define SNMP_ADD_STATS64_BH(mib, field, addend) SNMP_ADD_STATS_BH(mib, field, addend) | ||
| 219 | #define SNMP_ADD_STATS64_USER(mib, field, addend) SNMP_ADD_STATS_USER(mib, field, addend) | ||
| 220 | #define SNMP_ADD_STATS64(mib, field, addend) SNMP_ADD_STATS(mib, field, addend) | ||
| 221 | #define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend) | ||
| 222 | #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) SNMP_UPD_PO_STATS_BH(mib, basefield, addend) | ||
| 223 | #endif | ||
| 224 | |||
| 167 | #endif | 225 | #endif |
