On Fri, 2016-04-15 at 16:05 -0700, Michael Ma wrote: > Would definitely appreciate that. If you can share the patch it will > be helpful as well. Let me know if I can help with this...
Sure, here is what I am going to test : diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 941ec99cd3b6..f890ebe78629 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4003,11 +4003,17 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, * skb_tx_hash and will put the skbs in the queue we expect on their * way down to the bonding driver. */ - u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; + struct bonding *bond = netdev_priv(dev); + u16 txq; /* Save the original txq to restore before passing to the driver */ qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; + if (!bond->queue_id_selection_enabled) + return fallback(dev, skb); + + txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; + if (unlikely(txq >= dev->real_num_tx_queues)) { do { txq -= dev->real_num_tx_queues; @@ -4020,7 +4026,8 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev { struct bonding *bond = netdev_priv(dev); - if (bond_should_override_tx_queue(bond) && + if (bond->queue_id_selection_enabled && + bond_should_override_tx_queue(bond) && !bond_slave_override(bond, skb)) return NETDEV_TX_OK; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 577e57cad1dc..1a8a5153f027 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1270,6 +1270,7 @@ static int bond_option_ad_select_set(struct bonding *bond, static int bond_option_queue_id_set(struct bonding *bond, const struct bond_opt_value *newval) { + bool queue_id_selection_enabled = false; struct slave *slave, *update_slave; struct net_device *sdev; struct list_head *iter; @@ -1318,6 +1319,12 @@ static int bond_option_queue_id_set(struct bonding *bond, /* Actually set the qids for the slave */ update_slave->queue_id = qid; + bond_for_each_slave(bond, slave, iter) { + if (update_slave->queue_id) + queue_id_selection_enabled = true; + } + bond->queue_id_selection_enabled = queue_id_selection_enabled; + out: return ret; diff --git a/include/net/bonding.h b/include/net/bonding.h index 791800ddd6d9..29e29491c571 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -204,6 +204,7 @@ struct bonding { struct slave __rcu *primary_slave; struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ bool force_primary; + bool queue_id_selection_enabled; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ int (*recv_probe)(const struct sk_buff *, struct bonding *, struct slave *);