aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-20 14:07:37 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-20 14:07:37 -0400
commitaac3942cedc339b1e7b6bad28f3abe4ceb15bcc3 (patch)
tree49abe1f74a0a3290cf611878a704914a9f5e6577
parent6f458dfb409272082c9bfa412f77ff2fc21c626f (diff)
parent6c85f2bdda2086d804e198a3f31b685bc2f86b04 (diff)
Merge branch 'team_multiq'
Jiri Pirko says: ==================== This patchset represents the way I walked when I was adding multiqueue support for team driver. Jiri Pirko (6): net: honour netif_set_real_num_tx_queues() retval rtnl: allow to specify different num for rx and tx queue count rtnl: allow to specify number of rx and tx queues on device creation net: rename bond_queue_mapping to slave_dev_queue_mapping bond_sysfs: use ream_num_tx_queues rather than params.tx_queue team: add multiqueue support ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c20
-rw-r--r--drivers/net/bonding/bond_sysfs.c2
-rw-r--r--drivers/net/team/team.c65
-rw-r--r--include/linux/if_link.h2
-rw-r--r--include/linux/if_team.h8
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--include/net/rtnetlink.h10
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--net/core/rtnetlink.c27
9 files changed, 114 insertions, 29 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 3960b1b26178..6fae5f3ec7f6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -395,8 +395,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
395 skb->dev = slave_dev; 395 skb->dev = slave_dev;
396 396
397 BUILD_BUG_ON(sizeof(skb->queue_mapping) != 397 BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
398 sizeof(qdisc_skb_cb(skb)->bond_queue_mapping)); 398 sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
399 skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping; 399 skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping;
400 400
401 if (unlikely(netpoll_tx_running(slave_dev))) 401 if (unlikely(netpoll_tx_running(slave_dev)))
402 bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); 402 bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
@@ -4184,7 +4184,7 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
4184 /* 4184 /*
4185 * Save the original txq to restore before passing to the driver 4185 * Save the original txq to restore before passing to the driver
4186 */ 4186 */
4187 qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping; 4187 qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
4188 4188
4189 if (unlikely(txq >= dev->real_num_tx_queues)) { 4189 if (unlikely(txq >= dev->real_num_tx_queues)) {
4190 do { 4190 do {
@@ -4845,17 +4845,19 @@ static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
4845 return 0; 4845 return 0;
4846} 4846}
4847 4847
4848static int bond_get_tx_queues(struct net *net, struct nlattr *tb[]) 4848static unsigned int bond_get_num_tx_queues(void)
4849{ 4849{
4850 return tx_queues; 4850 return tx_queues;
4851} 4851}
4852 4852
4853static struct rtnl_link_ops bond_link_ops __read_mostly = { 4853static struct rtnl_link_ops bond_link_ops __read_mostly = {
4854 .kind = "bond", 4854 .kind = "bond",
4855 .priv_size = sizeof(struct bonding), 4855 .priv_size = sizeof(struct bonding),
4856 .setup = bond_setup, 4856 .setup = bond_setup,
4857 .validate = bond_validate, 4857 .validate = bond_validate,
4858 .get_tx_queues = bond_get_tx_queues, 4858 .get_num_tx_queues = bond_get_num_tx_queues,
4859 .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
4860 as for TX queues */
4859}; 4861};
4860 4862
4861/* Create a new bond based on the specified name and bonding parameters. 4863/* Create a new bond based on the specified name and bonding parameters.
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 485bedb8278c..dc15d248443f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1495,7 +1495,7 @@ static ssize_t bonding_store_queue_id(struct device *d,
1495 /* Check buffer length, valid ifname and queue id */ 1495 /* Check buffer length, valid ifname and queue id */
1496 if (strlen(buffer) > IFNAMSIZ || 1496 if (strlen(buffer) > IFNAMSIZ ||
1497 !dev_valid_name(buffer) || 1497 !dev_valid_name(buffer) ||
1498 qid > bond->params.tx_queues) 1498 qid > bond->dev->real_num_tx_queues)
1499 goto err_no_cmd; 1499 goto err_no_cmd;
1500 1500
1501 /* Get the pointer to that interface if it exists */ 1501 /* Get the pointer to that interface if it exists */
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 813e1319095f..b104c05225f7 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -27,6 +27,7 @@
27#include <net/rtnetlink.h> 27#include <net/rtnetlink.h>
28#include <net/genetlink.h> 28#include <net/genetlink.h>
29#include <net/netlink.h> 29#include <net/netlink.h>
30#include <net/sch_generic.h>
30#include <linux/if_team.h> 31#include <linux/if_team.h>
31 32
32#define DRV_NAME "team" 33#define DRV_NAME "team"
@@ -1121,6 +1122,22 @@ static const struct team_option team_options[] = {
1121 }, 1122 },
1122}; 1123};
1123 1124
1125static struct lock_class_key team_netdev_xmit_lock_key;
1126static struct lock_class_key team_netdev_addr_lock_key;
1127
1128static void team_set_lockdep_class_one(struct net_device *dev,
1129 struct netdev_queue *txq,
1130 void *unused)
1131{
1132 lockdep_set_class(&txq->_xmit_lock, &team_netdev_xmit_lock_key);
1133}
1134
1135static void team_set_lockdep_class(struct net_device *dev)
1136{
1137 lockdep_set_class(&dev->addr_list_lock, &team_netdev_addr_lock_key);
1138 netdev_for_each_tx_queue(dev, team_set_lockdep_class_one, NULL);
1139}
1140
1124static int team_init(struct net_device *dev) 1141static int team_init(struct net_device *dev)
1125{ 1142{
1126 struct team *team = netdev_priv(dev); 1143 struct team *team = netdev_priv(dev);
@@ -1148,6 +1165,8 @@ static int team_init(struct net_device *dev)
1148 goto err_options_register; 1165 goto err_options_register;
1149 netif_carrier_off(dev); 1166 netif_carrier_off(dev);
1150 1167
1168 team_set_lockdep_class(dev);
1169
1151 return 0; 1170 return 0;
1152 1171
1153err_options_register: 1172err_options_register:
@@ -1216,6 +1235,29 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
1216 return NETDEV_TX_OK; 1235 return NETDEV_TX_OK;
1217} 1236}
1218 1237
1238static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb)
1239{
1240 /*
1241 * This helper function exists to help dev_pick_tx get the correct
1242 * destination queue. Using a helper function skips a call to
1243 * skb_tx_hash and will put the skbs in the queue we expect on their
1244 * way down to the team driver.
1245 */
1246 u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
1247
1248 /*
1249 * Save the original txq to restore before passing to the driver
1250 */
1251 qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
1252
1253 if (unlikely(txq >= dev->real_num_tx_queues)) {
1254 do {
1255 txq -= dev->real_num_tx_queues;
1256 } while (txq >= dev->real_num_tx_queues);
1257 }
1258 return txq;
1259}
1260
1219static void team_change_rx_flags(struct net_device *dev, int change) 1261static void team_change_rx_flags(struct net_device *dev, int change)
1220{ 1262{
1221 struct team *team = netdev_priv(dev); 1263 struct team *team = netdev_priv(dev);
@@ -1469,6 +1511,7 @@ static const struct net_device_ops team_netdev_ops = {
1469 .ndo_open = team_open, 1511 .ndo_open = team_open,
1470 .ndo_stop = team_close, 1512 .ndo_stop = team_close,
1471 .ndo_start_xmit = team_xmit, 1513 .ndo_start_xmit = team_xmit,
1514 .ndo_select_queue = team_select_queue,
1472 .ndo_change_rx_flags = team_change_rx_flags, 1515 .ndo_change_rx_flags = team_change_rx_flags,
1473 .ndo_set_rx_mode = team_set_rx_mode, 1516 .ndo_set_rx_mode = team_set_rx_mode,
1474 .ndo_set_mac_address = team_set_mac_address, 1517 .ndo_set_mac_address = team_set_mac_address,
@@ -1543,12 +1586,24 @@ static int team_validate(struct nlattr *tb[], struct nlattr *data[])
1543 return 0; 1586 return 0;
1544} 1587}
1545 1588
1589static unsigned int team_get_num_tx_queues(void)
1590{
1591 return TEAM_DEFAULT_NUM_TX_QUEUES;
1592}
1593
1594static unsigned int team_get_num_rx_queues(void)
1595{
1596 return TEAM_DEFAULT_NUM_RX_QUEUES;
1597}
1598
1546static struct rtnl_link_ops team_link_ops __read_mostly = { 1599static struct rtnl_link_ops team_link_ops __read_mostly = {
1547 .kind = DRV_NAME, 1600 .kind = DRV_NAME,
1548 .priv_size = sizeof(struct team), 1601 .priv_size = sizeof(struct team),
1549 .setup = team_setup, 1602 .setup = team_setup,
1550 .newlink = team_newlink, 1603 .newlink = team_newlink,
1551 .validate = team_validate, 1604 .validate = team_validate,
1605 .get_num_tx_queues = team_get_num_tx_queues,
1606 .get_num_rx_queues = team_get_num_rx_queues,
1552}; 1607};
1553 1608
1554 1609
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index f715750d0b87..ac173bd2ab65 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -140,6 +140,8 @@ enum {
140 IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ 140 IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
141 IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */ 141 IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
142#define IFLA_PROMISCUITY IFLA_PROMISCUITY 142#define IFLA_PROMISCUITY IFLA_PROMISCUITY
143 IFLA_NUM_TX_QUEUES,
144 IFLA_NUM_RX_QUEUES,
143 __IFLA_MAX 145 __IFLA_MAX
144}; 146};
145 147
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 7fd0cdeb9444..6960fc1841a7 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -14,6 +14,7 @@
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <linux/netpoll.h> 16#include <linux/netpoll.h>
17#include <net/sch_generic.h>
17 18
18struct team_pcpu_stats { 19struct team_pcpu_stats {
19 u64 rx_packets; 20 u64 rx_packets;
@@ -98,6 +99,10 @@ static inline void team_netpoll_send_skb(struct team_port *port,
98static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, 99static inline int team_dev_queue_xmit(struct team *team, struct team_port *port,
99 struct sk_buff *skb) 100 struct sk_buff *skb)
100{ 101{
102 BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
103 sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
104 skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
105
101 skb->dev = port->dev; 106 skb->dev = port->dev;
102 if (unlikely(netpoll_tx_running(port->dev))) { 107 if (unlikely(netpoll_tx_running(port->dev))) {
103 team_netpoll_send_skb(port, skb); 108 team_netpoll_send_skb(port, skb);
@@ -236,6 +241,9 @@ extern void team_options_unregister(struct team *team,
236extern int team_mode_register(const struct team_mode *mode); 241extern int team_mode_register(const struct team_mode *mode);
237extern void team_mode_unregister(const struct team_mode *mode); 242extern void team_mode_unregister(const struct team_mode *mode);
238 243
244#define TEAM_DEFAULT_NUM_TX_QUEUES 16
245#define TEAM_DEFAULT_NUM_RX_QUEUES 16
246
239#endif /* __KERNEL__ */ 247#endif /* __KERNEL__ */
240 248
241#define TEAM_STRING_MAX_LEN 32 249#define TEAM_STRING_MAX_LEN 32
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ab0251d541ab..eb06e58bed0b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2110,7 +2110,12 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev,
2110static inline int netif_copy_real_num_queues(struct net_device *to_dev, 2110static inline int netif_copy_real_num_queues(struct net_device *to_dev,
2111 const struct net_device *from_dev) 2111 const struct net_device *from_dev)
2112{ 2112{
2113 netif_set_real_num_tx_queues(to_dev, from_dev->real_num_tx_queues); 2113 int err;
2114
2115 err = netif_set_real_num_tx_queues(to_dev,
2116 from_dev->real_num_tx_queues);
2117 if (err)
2118 return err;
2114#ifdef CONFIG_RPS 2119#ifdef CONFIG_RPS
2115 return netif_set_real_num_rx_queues(to_dev, 2120 return netif_set_real_num_rx_queues(to_dev,
2116 from_dev->real_num_rx_queues); 2121 from_dev->real_num_rx_queues);
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index bbcfd0993432..6b00c4fc4291 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -44,8 +44,10 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
44 * @get_xstats_size: Function to calculate required room for dumping device 44 * @get_xstats_size: Function to calculate required room for dumping device
45 * specific statistics 45 * specific statistics
46 * @fill_xstats: Function to dump device specific statistics 46 * @fill_xstats: Function to dump device specific statistics
47 * @get_tx_queues: Function to determine number of transmit queues to create when 47 * @get_num_tx_queues: Function to determine number of transmit queues
48 * creating a new device. 48 * to create when creating a new device.
49 * @get_num_rx_queues: Function to determine number of receive queues
50 * to create when creating a new device.
49 */ 51 */
50struct rtnl_link_ops { 52struct rtnl_link_ops {
51 struct list_head list; 53 struct list_head list;
@@ -77,8 +79,8 @@ struct rtnl_link_ops {
77 size_t (*get_xstats_size)(const struct net_device *dev); 79 size_t (*get_xstats_size)(const struct net_device *dev);
78 int (*fill_xstats)(struct sk_buff *skb, 80 int (*fill_xstats)(struct sk_buff *skb,
79 const struct net_device *dev); 81 const struct net_device *dev);
80 int (*get_tx_queues)(struct net *net, 82 unsigned int (*get_num_tx_queues)(void);
81 struct nlattr *tb[]); 83 unsigned int (*get_num_rx_queues)(void);
82}; 84};
83 85
84extern int __rtnl_link_register(struct rtnl_link_ops *ops); 86extern int __rtnl_link_register(struct rtnl_link_ops *ops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 9d7d54a00e63..d9611e032418 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -220,7 +220,7 @@ struct tcf_proto {
220 220
221struct qdisc_skb_cb { 221struct qdisc_skb_cb {
222 unsigned int pkt_len; 222 unsigned int pkt_len;
223 u16 bond_queue_mapping; 223 u16 slave_dev_queue_mapping;
224 u16 _pad; 224 u16 _pad;
225 unsigned char data[20]; 225 unsigned char data[20];
226}; 226};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 045db8ad87c8..5bb1ebca2eb0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -771,6 +771,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
771 + nla_total_size(4) /* IFLA_LINK */ 771 + nla_total_size(4) /* IFLA_LINK */
772 + nla_total_size(4) /* IFLA_MASTER */ 772 + nla_total_size(4) /* IFLA_MASTER */
773 + nla_total_size(4) /* IFLA_PROMISCUITY */ 773 + nla_total_size(4) /* IFLA_PROMISCUITY */
774 + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */
775 + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
774 + nla_total_size(1) /* IFLA_OPERSTATE */ 776 + nla_total_size(1) /* IFLA_OPERSTATE */
775 + nla_total_size(1) /* IFLA_LINKMODE */ 777 + nla_total_size(1) /* IFLA_LINKMODE */
776 + nla_total_size(ext_filter_mask 778 + nla_total_size(ext_filter_mask
@@ -889,6 +891,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
889 nla_put_u32(skb, IFLA_MTU, dev->mtu) || 891 nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
890 nla_put_u32(skb, IFLA_GROUP, dev->group) || 892 nla_put_u32(skb, IFLA_GROUP, dev->group) ||
891 nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) || 893 nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
894 nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) ||
895 nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) ||
892 (dev->ifindex != dev->iflink && 896 (dev->ifindex != dev->iflink &&
893 nla_put_u32(skb, IFLA_LINK, dev->iflink)) || 897 nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
894 (dev->master && 898 (dev->master &&
@@ -1106,6 +1110,8 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
1106 [IFLA_AF_SPEC] = { .type = NLA_NESTED }, 1110 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
1107 [IFLA_EXT_MASK] = { .type = NLA_U32 }, 1111 [IFLA_EXT_MASK] = { .type = NLA_U32 },
1108 [IFLA_PROMISCUITY] = { .type = NLA_U32 }, 1112 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
1113 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
1114 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
1109}; 1115};
1110EXPORT_SYMBOL(ifla_policy); 1116EXPORT_SYMBOL(ifla_policy);
1111 1117
@@ -1624,17 +1630,22 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1624{ 1630{
1625 int err; 1631 int err;
1626 struct net_device *dev; 1632 struct net_device *dev;
1627 unsigned int num_queues = 1; 1633 unsigned int num_tx_queues = 1;
1634 unsigned int num_rx_queues = 1;
1628 1635
1629 if (ops->get_tx_queues) { 1636 if (tb[IFLA_NUM_TX_QUEUES])
1630 err = ops->get_tx_queues(src_net, tb); 1637 num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
1631 if (err < 0) 1638 else if (ops->get_num_tx_queues)
1632 goto err; 1639 num_tx_queues = ops->get_num_tx_queues();
1633 num_queues = err; 1640
1634 } 1641 if (tb[IFLA_NUM_RX_QUEUES])
1642 num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]);
1643 else if (ops->get_num_rx_queues)
1644 num_rx_queues = ops->get_num_rx_queues();
1635 1645
1636 err = -ENOMEM; 1646 err = -ENOMEM;
1637 dev = alloc_netdev_mq(ops->priv_size, ifname, ops->setup, num_queues); 1647 dev = alloc_netdev_mqs(ops->priv_size, ifname, ops->setup,
1648 num_tx_queues, num_rx_queues);
1638 if (!dev) 1649 if (!dev)
1639 goto err; 1650 goto err;
1640 1651