Skip to content

Commit 83ffe99

Browse files
Pravin B Shelardavem330
authored andcommitted
openvswitch: Fix ovs_vport_get_stats()
Not every device has dev->tstats set. So when OVS tries to calculate vport stats it causes kernel panic. Following patch fixes it by using standard API to get net-device stats. ---8<--- Unable to handle kernel paging request at virtual address 766b4008 Internal error: Oops: 96000005 [#1] PREEMPT SMP Modules linked in: vport_vxlan vxlan ip6_udp_tunnel udp_tunnel tun bridge stp llc openvswitch ipv6 CPU: 7 PID: 1108 Comm: ovs-vswitchd Not tainted 4.3.0-rc3+ #82 PC is at ovs_vport_get_stats+0x150/0x1f8 [openvswitch] <snip> Call trace: [<ffffffbffc0859f8>] ovs_vport_get_stats+0x150/0x1f8 [openvswitch] [<ffffffbffc07cdb0>] ovs_vport_cmd_fill_info+0x140/0x1e0 [openvswitch] [<ffffffbffc07cf0c>] ovs_vport_cmd_dump+0xbc/0x138 [openvswitch] [<ffffffc00045a5ac>] netlink_dump+0xb8/0x258 [<ffffffc00045ace0>] __netlink_dump_start+0x120/0x178 [<ffffffc00045dd9c>] genl_family_rcv_msg+0x2d4/0x308 [<ffffffc00045de58>] genl_rcv_msg+0x88/0xc4 [<ffffffc00045cf24>] netlink_rcv_skb+0xd4/0x100 [<ffffffc00045dab0>] genl_rcv+0x30/0x48 [<ffffffc00045c830>] netlink_unicast+0x154/0x200 [<ffffffc00045cc9c>] netlink_sendmsg+0x308/0x364 [<ffffffc00041e10c>] sock_sendmsg+0x14/0x2c [<ffffffc000420d58>] SyS_sendto+0xbc/0xf0 Code: aa1603e1 f94037a4 aa1303e2 aa1703e0 (f9400465) Reported-by: Tomasz Sawicki <tomasz.sawicki@objectiveintegration.uk> Fixes: 8c87663 ("openvswitch: Remove vport stats.") Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 8690f47 commit 83ffe99

File tree

1 file changed

+13
-29
lines changed

1 file changed

+13
-29
lines changed

net/openvswitch/vport.c

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -280,35 +280,19 @@ void ovs_vport_del(struct vport *vport)
280280
*/
281281
void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
282282
{
283-
struct net_device *dev = vport->dev;
284-
int i;
285-
286-
memset(stats, 0, sizeof(*stats));
287-
stats->rx_errors = dev->stats.rx_errors;
288-
stats->tx_errors = dev->stats.tx_errors;
289-
stats->tx_dropped = dev->stats.tx_dropped;
290-
stats->rx_dropped = dev->stats.rx_dropped;
291-
292-
stats->rx_dropped += atomic_long_read(&dev->rx_dropped);
293-
stats->tx_dropped += atomic_long_read(&dev->tx_dropped);
294-
295-
for_each_possible_cpu(i) {
296-
const struct pcpu_sw_netstats *percpu_stats;
297-
struct pcpu_sw_netstats local_stats;
298-
unsigned int start;
299-
300-
percpu_stats = per_cpu_ptr(dev->tstats, i);
301-
302-
do {
303-
start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
304-
local_stats = *percpu_stats;
305-
} while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
306-
307-
stats->rx_bytes += local_stats.rx_bytes;
308-
stats->rx_packets += local_stats.rx_packets;
309-
stats->tx_bytes += local_stats.tx_bytes;
310-
stats->tx_packets += local_stats.tx_packets;
311-
}
283+
const struct rtnl_link_stats64 *dev_stats;
284+
struct rtnl_link_stats64 temp;
285+
286+
dev_stats = dev_get_stats(vport->dev, &temp);
287+
stats->rx_errors = dev_stats->rx_errors;
288+
stats->tx_errors = dev_stats->tx_errors;
289+
stats->tx_dropped = dev_stats->tx_dropped;
290+
stats->rx_dropped = dev_stats->rx_dropped;
291+
292+
stats->rx_bytes = dev_stats->rx_bytes;
293+
stats->rx_packets = dev_stats->rx_packets;
294+
stats->tx_bytes = dev_stats->tx_bytes;
295+
stats->tx_packets = dev_stats->tx_packets;
312296
}
313297

314298
/**

0 commit comments

Comments
 (0)