Skip to content

Commit 2c11455

Browse files
Eric Dumazetdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0fa0ee0 commit 2c11455

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

drivers/net/macvlan.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
187187
static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
188188
struct net_device *dev)
189189
{
190+
int i = skb_get_queue_mapping(skb);
191+
struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
190192
const struct macvlan_dev *vlan = netdev_priv(dev);
191193
unsigned int len = skb->len;
192194
int ret;
@@ -195,12 +197,11 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
195197
ret = dev_queue_xmit(skb);
196198

197199
if (likely(ret == NET_XMIT_SUCCESS)) {
198-
dev->stats.tx_packets++;
199-
dev->stats.tx_bytes += len;
200-
} else {
201-
dev->stats.tx_errors++;
202-
dev->stats.tx_aborted_errors++;
203-
}
200+
txq->tx_packets++;
201+
txq->tx_bytes += len;
202+
} else
203+
txq->tx_dropped++;
204+
204205
return NETDEV_TX_OK;
205206
}
206207

@@ -484,6 +485,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
484485
return 0;
485486
}
486487

488+
static 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+
487507
static int macvlan_newlink(struct net_device *dev,
488508
struct nlattr *tb[], struct nlattr *data[])
489509
{
@@ -550,6 +570,7 @@ static void macvlan_dellink(struct net_device *dev)
550570
static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
551571
.kind = "macvlan",
552572
.priv_size = sizeof(struct macvlan_dev),
573+
.get_tx_queues = macvlan_get_tx_queues,
553574
.setup = macvlan_setup,
554575
.validate = macvlan_validate,
555576
.newlink = macvlan_newlink,

0 commit comments

Comments
 (0)