mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-18 22:14:16 +00:00 
			
		
		
		
	dummy: percpu stats and lockless xmit
Converts dummy network device driver to : - percpu stats - 64bit stats - lockless xmit (NETIF_F_LLTX) - performance features added (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									745e20f1b6
								
							
						
					
					
						commit
						6d81f41c58
					
				
					 2 changed files with 56 additions and 3 deletions
				
			
		|  | @ -36,6 +36,7 @@ | |||
| #include <linux/moduleparam.h> | ||||
| #include <linux/rtnetlink.h> | ||||
| #include <net/rtnetlink.h> | ||||
| #include <linux/u64_stats_sync.h> | ||||
| 
 | ||||
| static int numdummies = 1; | ||||
| 
 | ||||
|  | @ -55,21 +56,69 @@ static void set_multicast_list(struct net_device *dev) | |||
| { | ||||
| } | ||||
| 
 | ||||
| struct pcpu_dstats { | ||||
| 	u64			tx_packets; | ||||
| 	u64			tx_bytes; | ||||
| 	struct u64_stats_sync	syncp; | ||||
| }; | ||||
| 
 | ||||
| static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, | ||||
| 						   struct rtnl_link_stats64 *stats) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for_each_possible_cpu(i) { | ||||
| 		const struct pcpu_dstats *dstats; | ||||
| 		u64 tbytes, tpackets; | ||||
| 		unsigned int start; | ||||
| 
 | ||||
| 		dstats = per_cpu_ptr(dev->dstats, i); | ||||
| 		do { | ||||
| 			start = u64_stats_fetch_begin(&dstats->syncp); | ||||
| 			tbytes = dstats->tx_bytes; | ||||
| 			tpackets = dstats->tx_packets; | ||||
| 		} while (u64_stats_fetch_retry(&dstats->syncp, start)); | ||||
| 		stats->tx_bytes += tbytes; | ||||
| 		stats->tx_packets += tpackets; | ||||
| 	} | ||||
| 	return stats; | ||||
| } | ||||
| 
 | ||||
| static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) | ||||
| { | ||||
| 	dev->stats.tx_packets++; | ||||
| 	dev->stats.tx_bytes += skb->len; | ||||
| 	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); | ||||
| 
 | ||||
| 	u64_stats_update_begin(&dstats->syncp); | ||||
| 	dstats->tx_packets++; | ||||
| 	dstats->tx_bytes += skb->len; | ||||
| 	u64_stats_update_end(&dstats->syncp); | ||||
| 
 | ||||
| 	dev_kfree_skb(skb); | ||||
| 	return NETDEV_TX_OK; | ||||
| } | ||||
| 
 | ||||
| static int dummy_dev_init(struct net_device *dev) | ||||
| { | ||||
| 	dev->dstats = alloc_percpu(struct pcpu_dstats); | ||||
| 	if (!dev->dstats) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void dummy_dev_free(struct net_device *dev) | ||||
| { | ||||
| 	free_percpu(dev->dstats); | ||||
| 	free_netdev(dev); | ||||
| } | ||||
| 
 | ||||
| static const struct net_device_ops dummy_netdev_ops = { | ||||
| 	.ndo_init		= dummy_dev_init, | ||||
| 	.ndo_start_xmit		= dummy_xmit, | ||||
| 	.ndo_validate_addr	= eth_validate_addr, | ||||
| 	.ndo_set_multicast_list = set_multicast_list, | ||||
| 	.ndo_set_mac_address	= dummy_set_address, | ||||
| 	.ndo_get_stats64	= dummy_get_stats64, | ||||
| }; | ||||
| 
 | ||||
| static void dummy_setup(struct net_device *dev) | ||||
|  | @ -78,14 +127,17 @@ static void dummy_setup(struct net_device *dev) | |||
| 
 | ||||
| 	/* Initialize the device structure. */ | ||||
| 	dev->netdev_ops = &dummy_netdev_ops; | ||||
| 	dev->destructor = free_netdev; | ||||
| 	dev->destructor = dummy_dev_free; | ||||
| 
 | ||||
| 	/* Fill in device structure with ethernet-generic values. */ | ||||
| 	dev->tx_queue_len = 0; | ||||
| 	dev->flags |= IFF_NOARP; | ||||
| 	dev->flags &= ~IFF_MULTICAST; | ||||
| 	dev->features	|= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; | ||||
| 	dev->features	|= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; | ||||
| 	random_ether_addr(dev->dev_addr); | ||||
| } | ||||
| 
 | ||||
| static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) | ||||
| { | ||||
| 	if (tb[IFLA_ADDRESS]) { | ||||
|  |  | |||
|  | @ -1057,6 +1057,7 @@ struct net_device { | |||
| 		void				*ml_priv; | ||||
| 		struct pcpu_lstats __percpu	*lstats; /* loopback stats */ | ||||
| 		struct pcpu_tstats __percpu	*tstats; /* tunnel stats */ | ||||
| 		struct pcpu_dstats __percpu	*dstats; /* dummy stats */ | ||||
| 	}; | ||||
| 	/* GARP */ | ||||
| 	struct garp_port	*garp_port; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Eric Dumazet
						Eric Dumazet