diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 | 
| commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
| tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/net/dummy.c | |
| parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
| parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) | |
| download | olio-linux-3.10-5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0.tar.xz olio-linux-3.10-5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0.zip  | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
  bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
  vlan: Calling vlan_hwaccel_do_receive() is always valid.
  tproxy: use the interface primary IP address as a default value for --on-ip
  tproxy: added IPv6 support to the socket match
  cxgb3: function namespace cleanup
  tproxy: added IPv6 support to the TPROXY target
  tproxy: added IPv6 socket lookup function to nf_tproxy_core
  be2net: Changes to use only priority codes allowed by f/w
  tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
  tproxy: added tproxy sockopt interface in the IPV6 layer
  tproxy: added udp6_lib_lookup function
  tproxy: added const specifiers to udp lookup functions
  tproxy: split off ipv6 defragmentation to a separate module
  l2tp: small cleanup
  nf_nat: restrict ICMP translation for embedded header
  can: mcp251x: fix generation of error frames
  can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
  can-raw: add msg_flags to distinguish local traffic
  9p: client code cleanup
  rds: make local functions/variables static
  ...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/net/dummy.c')
| -rw-r--r-- | drivers/net/dummy.c | 58 | 
1 files changed, 55 insertions, 3 deletions
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 37dcfdc6345..ff2d29b1785 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -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]) {  |