mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	macvlan: add multiqueue capability
macvlan devices are currently not multi-queue capable. We can do that defining rtnl_link_ops method, get_tx_queues(), called from rtnl_create_link() This new method gets num_tx_queues/real_num_tx_queues from lower device. macvlan_get_tx_queues() is a copy of vlan_get_tx_queues(). Because macvlan_start_xmit() has to update netdev_queue stats only (and not dev->stats), I chose to change tx_errors/tx_aborted_errors accounting to tx_dropped, since netdev_queue structure doesnt define tx_errors / tx_aborted_errors. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									0fa0ee053a
								
							
						
					
					
						commit
						2c11455321
					
				
					 1 changed files with 27 additions and 6 deletions
				
			
		| 
						 | 
					@ -187,6 +187,8 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 | 
				
			||||||
static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 | 
					static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
				      struct net_device *dev)
 | 
									      struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						int i = skb_get_queue_mapping(skb);
 | 
				
			||||||
 | 
						struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
 | 
				
			||||||
	const struct macvlan_dev *vlan = netdev_priv(dev);
 | 
						const struct macvlan_dev *vlan = netdev_priv(dev);
 | 
				
			||||||
	unsigned int len = skb->len;
 | 
						unsigned int len = skb->len;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -195,12 +197,11 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
	ret = dev_queue_xmit(skb);
 | 
						ret = dev_queue_xmit(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (likely(ret == NET_XMIT_SUCCESS)) {
 | 
						if (likely(ret == NET_XMIT_SUCCESS)) {
 | 
				
			||||||
		dev->stats.tx_packets++;
 | 
							txq->tx_packets++;
 | 
				
			||||||
		dev->stats.tx_bytes += len;
 | 
							txq->tx_bytes += len;
 | 
				
			||||||
	} else {
 | 
						} else
 | 
				
			||||||
		dev->stats.tx_errors++;
 | 
							txq->tx_dropped++;
 | 
				
			||||||
		dev->stats.tx_aborted_errors++;
 | 
					
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -484,6 +485,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int macvlan_get_tx_queues(struct net *net,
 | 
				
			||||||
 | 
									 struct nlattr *tb[],
 | 
				
			||||||
 | 
									 unsigned int *num_tx_queues,
 | 
				
			||||||
 | 
									 unsigned int *real_num_tx_queues)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct net_device *real_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!tb[IFLA_LINK])
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
 | 
				
			||||||
 | 
						if (!real_dev)
 | 
				
			||||||
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*num_tx_queues      = real_dev->num_tx_queues;
 | 
				
			||||||
 | 
						*real_num_tx_queues = real_dev->real_num_tx_queues;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int macvlan_newlink(struct net_device *dev,
 | 
					static int macvlan_newlink(struct net_device *dev,
 | 
				
			||||||
			   struct nlattr *tb[], struct nlattr *data[])
 | 
								   struct nlattr *tb[], struct nlattr *data[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -550,6 +570,7 @@ static void macvlan_dellink(struct net_device *dev)
 | 
				
			||||||
static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 | 
					static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 | 
				
			||||||
	.kind		= "macvlan",
 | 
						.kind		= "macvlan",
 | 
				
			||||||
	.priv_size	= sizeof(struct macvlan_dev),
 | 
						.priv_size	= sizeof(struct macvlan_dev),
 | 
				
			||||||
 | 
						.get_tx_queues  = macvlan_get_tx_queues,
 | 
				
			||||||
	.setup		= macvlan_setup,
 | 
						.setup		= macvlan_setup,
 | 
				
			||||||
	.validate	= macvlan_validate,
 | 
						.validate	= macvlan_validate,
 | 
				
			||||||
	.newlink	= macvlan_newlink,
 | 
						.newlink	= macvlan_newlink,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue