aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h15
-rw-r--r--include/net/netns/mib.h2
-rw-r--r--include/net/snmp.h2
-rw-r--r--net/ipv6/af_inet6.c8
-rw-r--r--net/ipv6/proc.c15
5 files changed, 23 insertions, 19 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index a366a8a1fe23..3f0258d2ef01 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -132,6 +132,15 @@ extern struct ctl_path net_ipv6_ctl_path[];
132 SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\ 132 SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\
133}) 133})
134 134
135/* per device and per net counters are atomic_long_t */
136#define _DEVINC_ATOMIC_ATOMIC(net, statname, idev, field) \
137({ \
138 struct inet6_dev *_idev = (idev); \
139 if (likely(_idev != NULL)) \
140 SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \
141 SNMP_INC_STATS_ATOMIC_LONG((net)->mib.statname##_statistics, (field));\
142})
143
135#define _DEVADD(net, statname, modifier, idev, field, val) \ 144#define _DEVADD(net, statname, modifier, idev, field, val) \
136({ \ 145({ \
137 struct inet6_dev *_idev = (idev); \ 146 struct inet6_dev *_idev = (idev); \
@@ -168,11 +177,11 @@ extern struct ctl_path net_ipv6_ctl_path[];
168 _DEVINCATOMIC(net, icmpv6, _BH, idev, field) 177 _DEVINCATOMIC(net, icmpv6, _BH, idev, field)
169 178
170#define ICMP6MSGOUT_INC_STATS(net, idev, field) \ 179#define ICMP6MSGOUT_INC_STATS(net, idev, field) \
171 _DEVINCATOMIC(net, icmpv6msg, , idev, field +256) 180 _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256)
172#define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \ 181#define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \
173 _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field +256) 182 _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256)
174#define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \ 183#define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \
175 _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field) 184 _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field)
176 185
177struct ip6_ra_chain { 186struct ip6_ra_chain {
178 struct ip6_ra_chain *next; 187 struct ip6_ra_chain *next;
diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
index f360135cb69f..30f6728ee98c 100644
--- a/include/net/netns/mib.h
+++ b/include/net/netns/mib.h
@@ -18,7 +18,7 @@ struct netns_mib {
18 DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6); 18 DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
19 DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); 19 DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
20 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); 20 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
21 DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics); 21 DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib, icmpv6msg_statistics);
22#endif 22#endif
23#ifdef CONFIG_XFRM_STATISTICS 23#ifdef CONFIG_XFRM_STATISTICS
24 DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics); 24 DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 0feafa68da01..2f65e1686fc8 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -84,7 +84,7 @@ struct icmpv6_mib_device {
84#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX 84#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX
85/* per network ns counters */ 85/* per network ns counters */
86struct icmpv6msg_mib { 86struct icmpv6msg_mib {
87 unsigned long mibs[ICMP6MSG_MIB_MAX]; 87 atomic_long_t mibs[ICMP6MSG_MIB_MAX];
88}; 88};
89/* per device counters, (shared on all cpus) */ 89/* per device counters, (shared on all cpus) */
90struct icmpv6msg_mib_device { 90struct icmpv6msg_mib_device {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 1040424c788f..282dc7a91f32 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -985,9 +985,9 @@ static int __net_init ipv6_init_mibs(struct net *net)
985 sizeof(struct icmpv6_mib), 985 sizeof(struct icmpv6_mib),
986 __alignof__(struct icmpv6_mib)) < 0) 986 __alignof__(struct icmpv6_mib)) < 0)
987 goto err_icmp_mib; 987 goto err_icmp_mib;
988 if (snmp_mib_init((void __percpu **)net->mib.icmpv6msg_statistics, 988 net->mib.icmpv6msg_statistics = kzalloc(sizeof(struct icmpv6msg_mib),
989 sizeof(struct icmpv6msg_mib), 989 GFP_KERNEL);
990 __alignof__(struct icmpv6msg_mib)) < 0) 990 if (!net->mib.icmpv6msg_statistics)
991 goto err_icmpmsg_mib; 991 goto err_icmpmsg_mib;
992 return 0; 992 return 0;
993 993
@@ -1008,7 +1008,7 @@ static void ipv6_cleanup_mibs(struct net *net)
1008 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6); 1008 snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6);
1009 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics); 1009 snmp_mib_free((void __percpu **)net->mib.ipv6_statistics);
1010 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics); 1010 snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics);
1011 snmp_mib_free((void __percpu **)net->mib.icmpv6msg_statistics); 1011 kfree(net->mib.icmpv6msg_statistics);
1012} 1012}
1013 1013
1014static int __net_init inet6_net_init(struct net *net) 1014static int __net_init inet6_net_init(struct net *net)
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 1008ce94bc33..fdeb6d03da81 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -142,11 +142,7 @@ static const struct snmp_mib snmp6_udplite6_list[] = {
142 SNMP_MIB_SENTINEL 142 SNMP_MIB_SENTINEL
143}; 143};
144 144
145/* can be called either with percpu mib (pcpumib != NULL), 145static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, atomic_long_t *smib)
146 * or shared one (smib != NULL)
147 */
148static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **pcpumib,
149 atomic_long_t *smib)
150{ 146{
151 char name[32]; 147 char name[32];
152 int i; 148 int i;
@@ -163,14 +159,14 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **pcpum
163 snprintf(name, sizeof(name), "Icmp6%s%s", 159 snprintf(name, sizeof(name), "Icmp6%s%s",
164 i & 0x100 ? "Out" : "In", p); 160 i & 0x100 ? "Out" : "In", p);
165 seq_printf(seq, "%-32s\t%lu\n", name, 161 seq_printf(seq, "%-32s\t%lu\n", name,
166 pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i)); 162 atomic_long_read(smib + i));
167 } 163 }
168 164
169 /* print by number (nonzero only) - ICMPMsgStat format */ 165 /* print by number (nonzero only) - ICMPMsgStat format */
170 for (i = 0; i < ICMP6MSG_MIB_MAX; i++) { 166 for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
171 unsigned long val; 167 unsigned long val;
172 168
173 val = pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i); 169 val = atomic_long_read(smib + i);
174 if (!val) 170 if (!val)
175 continue; 171 continue;
176 snprintf(name, sizeof(name), "Icmp6%sType%u", 172 snprintf(name, sizeof(name), "Icmp6%sType%u",
@@ -215,8 +211,7 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
215 snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp)); 211 snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp));
216 snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics, 212 snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics,
217 NULL, snmp6_icmp6_list); 213 NULL, snmp6_icmp6_list);
218 snmp6_seq_show_icmpv6msg(seq, 214 snmp6_seq_show_icmpv6msg(seq, net->mib.icmpv6msg_statistics->mibs);
219 (void __percpu **)net->mib.icmpv6msg_statistics, NULL);
220 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6, 215 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6,
221 NULL, snmp6_udp6_list); 216 NULL, snmp6_udp6_list);
222 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6, 217 snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6,
@@ -246,7 +241,7 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
246 snmp6_ipstats_list); 241 snmp6_ipstats_list);
247 snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs, 242 snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs,
248 snmp6_icmp6_list); 243 snmp6_icmp6_list);
249 snmp6_seq_show_icmpv6msg(seq, NULL, idev->stats.icmpv6msgdev->mibs); 244 snmp6_seq_show_icmpv6msg(seq, idev->stats.icmpv6msgdev->mibs);
250 return 0; 245 return 0;
251} 246}
252 247