aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ifb.c
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2011-06-20 07:42:30 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-21 18:55:09 -0400
commit3b0c9cbb6e5fe25a4162be68ed1459b6f7432da9 (patch)
treef6505769a0d9c286f2aa4db7f1e1cdca2fafc09c /drivers/net/ifb.c
parent43d620c82985b19008d87a437b4cf83f356264f7 (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.c56
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 @@
41struct ifb_private { 41struct 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
48static int numifbs = 2; 56static int numifbs = 2;
@@ -54,10 +62,8 @@ static int ifb_close(struct net_device *dev);
54 62
55static void ri_tasklet(unsigned long dev) 63static 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
132static 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
123static const struct net_device_ops ifb_netdev_ops = { 159static 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)
153static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) 190static 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