Message ID | 4A9EC383.4070304@gmail.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Wed, 02 Sep 2009 21:12:03 +0200 > [PATCH net-next-2.6] vlan: multiqueue vlan device > > vlan devices are currently not multi-queue capable. > > We can do that with a new rtnl_link_ops method, > get_tx_queues(), called from rtnl_create_link() > > This new method gets num_tx_queues/real_num_tx_queues > from real device. > > register_vlan_device() is also handled. > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Applied, but now I need you to do an audit :-) I believe that drivers will change the number of TX queues in use at times where we'll need to trigger an event or something so that vlan's can learn about the value changing. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Miller a écrit : > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Wed, 02 Sep 2009 21:12:03 +0200 > >> [PATCH net-next-2.6] vlan: multiqueue vlan device >> >> vlan devices are currently not multi-queue capable. >> >> We can do that with a new rtnl_link_ops method, >> get_tx_queues(), called from rtnl_create_link() >> >> This new method gets num_tx_queues/real_num_tx_queues >> from real device. >> >> register_vlan_device() is also handled. >> >> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> > > Applied, but now I need you to do an audit :-) > > I believe that drivers will change the number of TX queues > in use at times where we'll need to trigger an event or > something so that vlan's can learn about the value changing. Yes, I know :) This is why I kept both num_tx_queues and real_num_tx_queues values, and not the later :) Thanks -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 3c1895e..b630196 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -70,6 +70,9 @@ struct rtnl_link_ops { size_t (*get_xstats_size)(const struct net_device *dev); int (*fill_xstats)(struct sk_buff *skb, const struct net_device *dev); + int (*get_tx_queues)(struct net *net, struct nlattr *tb[], + unsigned int *tx_queues, + unsigned int *real_tx_queues); }; extern int __rtnl_link_register(struct rtnl_link_ops *ops); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index e814794..8836575 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -330,12 +330,13 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } - new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, - vlan_setup); + new_dev = alloc_netdev_mq(sizeof(struct vlan_dev_info), name, + vlan_setup, real_dev->num_tx_queues); if (new_dev == NULL) return -ENOBUFS; + new_dev->real_num_tx_queues = real_dev->real_num_tx_queues; dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index e9c91dc..cd5c2ae 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c @@ -100,6 +100,25 @@ static int vlan_changelink(struct net_device *dev, return 0; } +static int vlan_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 vlan_newlink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -216,6 +235,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { .maxtype = IFLA_VLAN_MAX, .policy = vlan_policy, .priv_size = sizeof(struct vlan_dev_info), + .get_tx_queues = vlan_get_tx_queues, .setup = vlan_setup, .validate = vlan_validate, .newlink = vlan_newlink, diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b44775f..bbcba2a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -974,12 +974,20 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, { int err; struct net_device *dev; + unsigned int num_queues = 1; + unsigned int real_num_queues = 1; + if (ops->get_tx_queues) { + err = ops->get_tx_queues(net, tb, &num_queues, &real_num_queues); + if (err) + goto err; + } err = -ENOMEM; - dev = alloc_netdev(ops->priv_size, ifname, ops->setup); + dev = alloc_netdev_mq(ops->priv_size, ifname, ops->setup, num_queues); if (!dev) goto err; + dev->real_num_tx_queues = real_num_queues; if (strchr(dev->name, '%')) { err = dev_alloc_name(dev, dev->name); if (err < 0)