diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 22bcb4e12e2a..d8c10764f130 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -88,10 +88,8 @@ struct netfront_cb { | |||
88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) | 88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) |
89 | 89 | ||
90 | struct netfront_stats { | 90 | struct netfront_stats { |
91 | u64 rx_packets; | 91 | u64 packets; |
92 | u64 tx_packets; | 92 | u64 bytes; |
93 | u64 rx_bytes; | ||
94 | u64 tx_bytes; | ||
95 | struct u64_stats_sync syncp; | 93 | struct u64_stats_sync syncp; |
96 | }; | 94 | }; |
97 | 95 | ||
@@ -160,7 +158,8 @@ struct netfront_info { | |||
160 | struct netfront_queue *queues; | 158 | struct netfront_queue *queues; |
161 | 159 | ||
162 | /* Statistics */ | 160 | /* Statistics */ |
163 | struct netfront_stats __percpu *stats; | 161 | struct netfront_stats __percpu *rx_stats; |
162 | struct netfront_stats __percpu *tx_stats; | ||
164 | 163 | ||
165 | atomic_t rx_gso_checksum_fixup; | 164 | atomic_t rx_gso_checksum_fixup; |
166 | }; | 165 | }; |
@@ -565,7 +564,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
565 | { | 564 | { |
566 | unsigned short id; | 565 | unsigned short id; |
567 | struct netfront_info *np = netdev_priv(dev); | 566 | struct netfront_info *np = netdev_priv(dev); |
568 | struct netfront_stats *stats = this_cpu_ptr(np->stats); | 567 | struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); |
569 | struct xen_netif_tx_request *tx; | 568 | struct xen_netif_tx_request *tx; |
570 | char *data = skb->data; | 569 | char *data = skb->data; |
571 | RING_IDX i; | 570 | RING_IDX i; |
@@ -672,10 +671,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
672 | if (notify) | 671 | if (notify) |
673 | notify_remote_via_irq(queue->tx_irq); | 672 | notify_remote_via_irq(queue->tx_irq); |
674 | 673 | ||
675 | u64_stats_update_begin(&stats->syncp); | 674 | u64_stats_update_begin(&tx_stats->syncp); |
676 | stats->tx_bytes += skb->len; | 675 | tx_stats->bytes += skb->len; |
677 | stats->tx_packets++; | 676 | tx_stats->packets++; |
678 | u64_stats_update_end(&stats->syncp); | 677 | u64_stats_update_end(&tx_stats->syncp); |
679 | 678 | ||
680 | /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ | 679 | /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ |
681 | xennet_tx_buf_gc(queue); | 680 | xennet_tx_buf_gc(queue); |
@@ -931,7 +930,7 @@ static int checksum_setup(struct net_device *dev, struct sk_buff *skb) | |||
931 | static int handle_incoming_queue(struct netfront_queue *queue, | 930 | static int handle_incoming_queue(struct netfront_queue *queue, |
932 | struct sk_buff_head *rxq) | 931 | struct sk_buff_head *rxq) |
933 | { | 932 | { |
934 | struct netfront_stats *stats = this_cpu_ptr(queue->info->stats); | 933 | struct netfront_stats *rx_stats = this_cpu_ptr(queue->info->rx_stats); |
935 | int packets_dropped = 0; | 934 | int packets_dropped = 0; |
936 | struct sk_buff *skb; | 935 | struct sk_buff *skb; |
937 | 936 | ||
@@ -952,10 +951,10 @@ static int handle_incoming_queue(struct netfront_queue *queue, | |||
952 | continue; | 951 | continue; |
953 | } | 952 | } |
954 | 953 | ||
955 | u64_stats_update_begin(&stats->syncp); | 954 | u64_stats_update_begin(&rx_stats->syncp); |
956 | stats->rx_packets++; | 955 | rx_stats->packets++; |
957 | stats->rx_bytes += skb->len; | 956 | rx_stats->bytes += skb->len; |
958 | u64_stats_update_end(&stats->syncp); | 957 | u64_stats_update_end(&rx_stats->syncp); |
959 | 958 | ||
960 | /* Pass it up. */ | 959 | /* Pass it up. */ |
961 | napi_gro_receive(&queue->napi, skb); | 960 | napi_gro_receive(&queue->napi, skb); |
@@ -1079,18 +1078,22 @@ static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, | |||
1079 | int cpu; | 1078 | int cpu; |
1080 | 1079 | ||
1081 | for_each_possible_cpu(cpu) { | 1080 | for_each_possible_cpu(cpu) { |
1082 | struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); | 1081 | struct netfront_stats *rx_stats = per_cpu_ptr(np->rx_stats, cpu); |
1082 | struct netfront_stats *tx_stats = per_cpu_ptr(np->tx_stats, cpu); | ||
1083 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | 1083 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; |
1084 | unsigned int start; | 1084 | unsigned int start; |
1085 | 1085 | ||
1086 | do { | 1086 | do { |
1087 | start = u64_stats_fetch_begin_irq(&stats->syncp); | 1087 | start = u64_stats_fetch_begin_irq(&tx_stats->syncp); |
1088 | tx_packets = tx_stats->packets; | ||
1089 | tx_bytes = tx_stats->bytes; | ||
1090 | } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); | ||
1088 | 1091 | ||
1089 | rx_packets = stats->rx_packets; | 1092 | do { |
1090 | tx_packets = stats->tx_packets; | 1093 | start = u64_stats_fetch_begin_irq(&rx_stats->syncp); |
1091 | rx_bytes = stats->rx_bytes; | 1094 | rx_packets = rx_stats->packets; |
1092 | tx_bytes = stats->tx_bytes; | 1095 | rx_bytes = rx_stats->bytes; |
1093 | } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); | 1096 | } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); |
1094 | 1097 | ||
1095 | tot->rx_packets += rx_packets; | 1098 | tot->rx_packets += rx_packets; |
1096 | tot->tx_packets += tx_packets; | 1099 | tot->tx_packets += tx_packets; |
@@ -1275,6 +1278,15 @@ static const struct net_device_ops xennet_netdev_ops = { | |||
1275 | #endif | 1278 | #endif |
1276 | }; | 1279 | }; |
1277 | 1280 | ||
1281 | static void xennet_free_netdev(struct net_device *netdev) | ||
1282 | { | ||
1283 | struct netfront_info *np = netdev_priv(netdev); | ||
1284 | |||
1285 | free_percpu(np->rx_stats); | ||
1286 | free_percpu(np->tx_stats); | ||
1287 | free_netdev(netdev); | ||
1288 | } | ||
1289 | |||
1278 | static struct net_device *xennet_create_dev(struct xenbus_device *dev) | 1290 | static struct net_device *xennet_create_dev(struct xenbus_device *dev) |
1279 | { | 1291 | { |
1280 | int err; | 1292 | int err; |
@@ -1295,8 +1307,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1295 | np->queues = NULL; | 1307 | np->queues = NULL; |
1296 | 1308 | ||
1297 | err = -ENOMEM; | 1309 | err = -ENOMEM; |
1298 | np->stats = netdev_alloc_pcpu_stats(struct netfront_stats); | 1310 | np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); |
1299 | if (np->stats == NULL) | 1311 | if (np->rx_stats == NULL) |
1312 | goto exit; | ||
1313 | np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); | ||
1314 | if (np->tx_stats == NULL) | ||
1300 | goto exit; | 1315 | goto exit; |
1301 | 1316 | ||
1302 | netdev->netdev_ops = &xennet_netdev_ops; | 1317 | netdev->netdev_ops = &xennet_netdev_ops; |
@@ -1327,7 +1342,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1327 | return netdev; | 1342 | return netdev; |
1328 | 1343 | ||
1329 | exit: | 1344 | exit: |
1330 | free_netdev(netdev); | 1345 | xennet_free_netdev(netdev); |
1331 | return ERR_PTR(err); | 1346 | return ERR_PTR(err); |
1332 | } | 1347 | } |
1333 | 1348 | ||
@@ -1369,7 +1384,7 @@ static int netfront_probe(struct xenbus_device *dev, | |||
1369 | return 0; | 1384 | return 0; |
1370 | 1385 | ||
1371 | fail: | 1386 | fail: |
1372 | free_netdev(netdev); | 1387 | xennet_free_netdev(netdev); |
1373 | dev_set_drvdata(&dev->dev, NULL); | 1388 | dev_set_drvdata(&dev->dev, NULL); |
1374 | return err; | 1389 | return err; |
1375 | } | 1390 | } |
@@ -2189,9 +2204,7 @@ static int xennet_remove(struct xenbus_device *dev) | |||
2189 | info->queues = NULL; | 2204 | info->queues = NULL; |
2190 | } | 2205 | } |
2191 | 2206 | ||
2192 | free_percpu(info->stats); | 2207 | xennet_free_netdev(info->netdev); |
2193 | |||
2194 | free_netdev(info->netdev); | ||
2195 | 2208 | ||
2196 | return 0; | 2209 | return 0; |
2197 | } | 2210 | } |