aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-09-02 20:11:45 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-03 23:02:13 -0400
commit2c11455321f37da6fe6cc36353149f9ac9183334 (patch)
tree8033ca6f3cc54780074c7d2a734ee3c62fec3ca3 /drivers/net
parent0fa0ee053aaa53939306376719450cfe56e33e3b (diff)
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/macvlan.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index c85c46d2a309..3aabfd9dd212 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -187,6 +187,8 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
187static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 187static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
188 struct net_device *dev) 188 struct net_device *dev)
189{ 189{
190 int i = skb_get_queue_mapping(skb);
191 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
190 const struct macvlan_dev *vlan = netdev_priv(dev); 192 const struct macvlan_dev *vlan = netdev_priv(dev);
191 unsigned int len = skb->len; 193 unsigned int len = skb->len;
192 int ret; 194 int ret;
@@ -195,12 +197,11 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
195 ret = dev_queue_xmit(skb); 197 ret = dev_queue_xmit(skb);
196 198
197 if (likely(ret == NET_XMIT_SUCCESS)) { 199 if (likely(ret == NET_XMIT_SUCCESS)) {
198 dev->stats.tx_packets++; 200 txq->tx_packets++;
199 dev->stats.tx_bytes += len; 201 txq->tx_bytes += len;
200 } else { 202 } else
201 dev->stats.tx_errors++; 203 txq->tx_dropped++;
202 dev->stats.tx_aborted_errors++; 204
203 }
204 return NETDEV_TX_OK; 205 return NETDEV_TX_OK;
205} 206}
206 207
@@ -484,6 +485,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
484 return 0; 485 return 0;
485} 486}
486 487
488static int macvlan_get_tx_queues(struct net *net,
489 struct nlattr *tb[],
490 unsigned int *num_tx_queues,
491 unsigned int *real_num_tx_queues)
492{
493 struct net_device *real_dev;
494
495 if (!tb[IFLA_LINK])
496 return -EINVAL;
497
498 real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
499 if (!real_dev)
500 return -ENODEV;
501
502 *num_tx_queues = real_dev->num_tx_queues;
503 *real_num_tx_queues = real_dev->real_num_tx_queues;
504 return 0;
505}
506
487static int macvlan_newlink(struct net_device *dev, 507static int macvlan_newlink(struct net_device *dev,
488 struct nlattr *tb[], struct nlattr *data[]) 508 struct nlattr *tb[], struct nlattr *data[])
489{ 509{
@@ -550,6 +570,7 @@ static void macvlan_dellink(struct net_device *dev)
550static struct rtnl_link_ops macvlan_link_ops __read_mostly = { 570static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
551 .kind = "macvlan", 571 .kind = "macvlan",
552 .priv_size = sizeof(struct macvlan_dev), 572 .priv_size = sizeof(struct macvlan_dev),
573 .get_tx_queues = macvlan_get_tx_queues,
553 .setup = macvlan_setup, 574 .setup = macvlan_setup,
554 .validate = macvlan_validate, 575 .validate = macvlan_validate,
555 .newlink = macvlan_newlink, 576 .newlink = macvlan_newlink,