diff options
author | stephen hemminger <shemminger@vyatta.com> | 2011-06-20 07:42:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-21 18:55:09 -0400 |
commit | 3b0c9cbb6e5fe25a4162be68ed1459b6f7432da9 (patch) | |
tree | f6505769a0d9c286f2aa4db7f1e1cdca2fafc09c /drivers/net/ifb.c | |
parent | 43d620c82985b19008d87a437b4cf83f356264f7 (diff) |
ifb: convert to 64 bit stats
Convert input functional block device to use 64 bit stats.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ifb.c')
-rw-r--r-- | drivers/net/ifb.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ce53f4a23b1..6e82dd32e80 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -41,8 +41,16 @@ | |||
41 | struct ifb_private { | 41 | struct ifb_private { |
42 | struct tasklet_struct ifb_tasklet; | 42 | struct tasklet_struct ifb_tasklet; |
43 | int tasklet_pending; | 43 | int tasklet_pending; |
44 | |||
45 | struct u64_stats_sync rsync; | ||
44 | struct sk_buff_head rq; | 46 | struct sk_buff_head rq; |
47 | u64 rx_packets; | ||
48 | u64 rx_bytes; | ||
49 | |||
50 | struct u64_stats_sync tsync; | ||
45 | struct sk_buff_head tq; | 51 | struct sk_buff_head tq; |
52 | u64 tx_packets; | ||
53 | u64 tx_bytes; | ||
46 | }; | 54 | }; |
47 | 55 | ||
48 | static int numifbs = 2; | 56 | static int numifbs = 2; |
@@ -54,10 +62,8 @@ static int ifb_close(struct net_device *dev); | |||
54 | 62 | ||
55 | static void ri_tasklet(unsigned long dev) | 63 | static void ri_tasklet(unsigned long dev) |
56 | { | 64 | { |
57 | |||
58 | struct net_device *_dev = (struct net_device *)dev; | 65 | struct net_device *_dev = (struct net_device *)dev; |
59 | struct ifb_private *dp = netdev_priv(_dev); | 66 | struct ifb_private *dp = netdev_priv(_dev); |
60 | struct net_device_stats *stats = &_dev->stats; | ||
61 | struct netdev_queue *txq; | 67 | struct netdev_queue *txq; |
62 | struct sk_buff *skb; | 68 | struct sk_buff *skb; |
63 | 69 | ||
@@ -77,15 +83,18 @@ static void ri_tasklet(unsigned long dev) | |||
77 | 83 | ||
78 | skb->tc_verd = 0; | 84 | skb->tc_verd = 0; |
79 | skb->tc_verd = SET_TC_NCLS(skb->tc_verd); | 85 | skb->tc_verd = SET_TC_NCLS(skb->tc_verd); |
80 | stats->tx_packets++; | 86 | |
81 | stats->tx_bytes +=skb->len; | 87 | u64_stats_update_begin(&dp->tsync); |
88 | dp->tx_packets++; | ||
89 | dp->tx_bytes += skb->len; | ||
90 | u64_stats_update_end(&dp->tsync); | ||
82 | 91 | ||
83 | rcu_read_lock(); | 92 | rcu_read_lock(); |
84 | skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif); | 93 | skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif); |
85 | if (!skb->dev) { | 94 | if (!skb->dev) { |
86 | rcu_read_unlock(); | 95 | rcu_read_unlock(); |
87 | dev_kfree_skb(skb); | 96 | dev_kfree_skb(skb); |
88 | stats->tx_dropped++; | 97 | _dev->stats.tx_dropped++; |
89 | if (skb_queue_len(&dp->tq) != 0) | 98 | if (skb_queue_len(&dp->tq) != 0) |
90 | goto resched; | 99 | goto resched; |
91 | break; | 100 | break; |
@@ -120,9 +129,37 @@ resched: | |||
120 | 129 | ||
121 | } | 130 | } |
122 | 131 | ||
132 | static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev, | ||
133 | struct rtnl_link_stats64 *stats) | ||
134 | { | ||
135 | struct ifb_private *dp = netdev_priv(dev); | ||
136 | unsigned int start; | ||
137 | |||
138 | do { | ||
139 | start = u64_stats_fetch_begin_bh(&dp->rsync); | ||
140 | stats->rx_packets = dp->rx_packets; | ||
141 | stats->rx_bytes = dp->rx_bytes; | ||
142 | } while (u64_stats_fetch_retry_bh(&dp->rsync, start)); | ||
143 | |||
144 | do { | ||
145 | start = u64_stats_fetch_begin_bh(&dp->tsync); | ||
146 | |||
147 | stats->tx_packets = dp->tx_packets; | ||
148 | stats->tx_bytes = dp->tx_bytes; | ||
149 | |||
150 | } while (u64_stats_fetch_retry_bh(&dp->tsync, start)); | ||
151 | |||
152 | stats->rx_dropped = dev->stats.rx_dropped; | ||
153 | stats->tx_dropped = dev->stats.tx_dropped; | ||
154 | |||
155 | return stats; | ||
156 | } | ||
157 | |||
158 | |||
123 | static const struct net_device_ops ifb_netdev_ops = { | 159 | static const struct net_device_ops ifb_netdev_ops = { |
124 | .ndo_open = ifb_open, | 160 | .ndo_open = ifb_open, |
125 | .ndo_stop = ifb_close, | 161 | .ndo_stop = ifb_close, |
162 | .ndo_get_stats64 = ifb_stats64, | ||
126 | .ndo_start_xmit = ifb_xmit, | 163 | .ndo_start_xmit = ifb_xmit, |
127 | .ndo_validate_addr = eth_validate_addr, | 164 | .ndo_validate_addr = eth_validate_addr, |
128 | }; | 165 | }; |
@@ -153,15 +190,16 @@ static void ifb_setup(struct net_device *dev) | |||
153 | static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) | 190 | static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) |
154 | { | 191 | { |
155 | struct ifb_private *dp = netdev_priv(dev); | 192 | struct ifb_private *dp = netdev_priv(dev); |
156 | struct net_device_stats *stats = &dev->stats; | ||
157 | u32 from = G_TC_FROM(skb->tc_verd); | 193 | u32 from = G_TC_FROM(skb->tc_verd); |
158 | 194 | ||
159 | stats->rx_packets++; | 195 | u64_stats_update_begin(&dp->rsync); |
160 | stats->rx_bytes+=skb->len; | 196 | dp->rx_packets++; |
197 | dp->rx_bytes += skb->len; | ||
198 | u64_stats_update_end(&dp->rsync); | ||
161 | 199 | ||
162 | if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) { | 200 | if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) { |
163 | dev_kfree_skb(skb); | 201 | dev_kfree_skb(skb); |
164 | stats->rx_dropped++; | 202 | dev->stats.rx_dropped++; |
165 | return NETDEV_TX_OK; | 203 | return NETDEV_TX_OK; |
166 | } | 204 | } |
167 | 205 | ||