* [PATCH] bonding: bond_select_queue off by one @ 2011-02-18 2:07 Phil Oester 2011-02-18 3:46 ` Ben Hutchings 2011-02-18 4:41 ` Jay Vosburgh 0 siblings, 2 replies; 6+ messages in thread From: Phil Oester @ 2011-02-18 2:07 UTC (permalink / raw) To: netdev [-- Attachment #1: Type: text/plain, Size: 506 bytes --] The bonding driver's bond_select_queue function simply returns skb->queue_mapping. However queue_mapping could be == 16 for queue #16. This causes the following message to be flooded to syslog: kernel: bondx selects TX queue 16, but real number of TX queues is 16 ndo_select_queue wants a zero-based number, so bonding driver needs to subtract one to return the proper queue number. Also fix grammar in a comment while in the vicinity. Phil Oester Signed-off-by: Phil Oester <kernel@linuxace.com> [-- Attachment #2: patch-bond-txq --] [-- Type: text/plain, Size: 691 bytes --] --- linux-2.6/drivers/net/bonding/bond_main.c.orig 2011-01-30 09:15:09.813843817 -0800 +++ linux-2.6/drivers/net/bonding/bond_main.c 2011-02-17 18:02:46.919050909 -0800 @@ -4537,11 +4537,11 @@ { /* * This helper function exists to help dev_pick_tx get the correct - * destination queue. Using a helper function skips the a call to + * destination queue. Using a helper function skips a call to * skb_tx_hash and will put the skbs in the queue we expect on their * way down to the bonding driver. */ - return skb->queue_mapping; + return skb->queue_mapping ? skb->queue_mapping - 1 : 0; } static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] bonding: bond_select_queue off by one 2011-02-18 2:07 [PATCH] bonding: bond_select_queue off by one Phil Oester @ 2011-02-18 3:46 ` Ben Hutchings 2011-02-18 4:41 ` Jay Vosburgh 1 sibling, 0 replies; 6+ messages in thread From: Ben Hutchings @ 2011-02-18 3:46 UTC (permalink / raw) To: Phil Oester; +Cc: netdev On Thu, 2011-02-17 at 18:07 -0800, Phil Oester wrote: > The bonding driver's bond_select_queue function simply returns > skb->queue_mapping. However queue_mapping could be == 16 > for queue #16. This causes the following message to be flooded > to syslog: > > kernel: bondx selects TX queue 16, but real number of TX queues is 16 > > ndo_select_queue wants a zero-based number, so bonding driver needs > to subtract one to return the proper queue number. Also fix grammar in > a comment while in the vicinity. > > Phil Oester > > Signed-off-by: Phil Oester <kernel@linuxace.com> > --- linux-2.6/drivers/net/bonding/bond_main.c.orig 2011-01-30 09:15:09.813843817 -0800 > +++ linux-2.6/drivers/net/bonding/bond_main.c 2011-02-17 18:02:46.919050909 -0800 > @@ -4537,11 +4537,11 @@ > { > /* > * This helper function exists to help dev_pick_tx get the correct > - * destination queue. Using a helper function skips the a call to > + * destination queue. Using a helper function skips a call to > * skb_tx_hash and will put the skbs in the queue we expect on their > * way down to the bonding driver. > */ > - return skb->queue_mapping; > + return skb->queue_mapping ? skb->queue_mapping - 1 : 0; > } > > static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) This looks basically correct, but it should use the proper functions: skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; Ben. -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] bonding: bond_select_queue off by one 2011-02-18 2:07 [PATCH] bonding: bond_select_queue off by one Phil Oester 2011-02-18 3:46 ` Ben Hutchings @ 2011-02-18 4:41 ` Jay Vosburgh 2011-02-18 22:49 ` Andy Gospodarek 1 sibling, 1 reply; 6+ messages in thread From: Jay Vosburgh @ 2011-02-18 4:41 UTC (permalink / raw) To: Andy Gospodarek, Phil Oester; +Cc: netdev Phil Oester <kernel@linuxace.com> wrote: >The bonding driver's bond_select_queue function simply returns >skb->queue_mapping. However queue_mapping could be == 16 >for queue #16. This causes the following message to be flooded >to syslog: > >kernel: bondx selects TX queue 16, but real number of TX queues is 16 > >ndo_select_queue wants a zero-based number, so bonding driver needs >to subtract one to return the proper queue number. Also fix grammar in >a comment while in the vicinity. Andy, can you comment on this? If memory serves, the omission of queue ID zero was on purpose; is this patch going to break any of the functionality added by: commit bb1d912323d5dd50e1079e389f4e964be14f0ae3 Author: Andy Gospodarek <andy@greyhouse.net> Date: Wed Jun 2 08:40:18 2010 +0000 bonding: allow user-controlled output slave selection Ben Hutchings <bhutchings@solarflare.com> wrote: >This looks basically correct, but it should use the proper functions: > > skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; As Ben points out, skb_rx_queue_recorded, skb_record_rx_queue, et al, do the offset by one internally, but the bond_slave_override function is comparing the slave's queue_id to the skb->queue_mapping. That makes me wonder if this patch is going to mess things up, and if bond_slave_override should also use the skb_rx_queue_recorded, et al, functions. -J >Phil Oester > >Signed-off-by: Phil Oester <kernel@linuxace.com> > > >--- linux-2.6/drivers/net/bonding/bond_main.c.orig 2011-01-30 09:15:09.813843817 -0800 >+++ linux-2.6/drivers/net/bonding/bond_main.c 2011-02-17 18:02:46.919050909 -0800 >@@ -4537,11 +4537,11 @@ > { > /* > * This helper function exists to help dev_pick_tx get the correct >- * destination queue. Using a helper function skips the a call to >+ * destination queue. Using a helper function skips a call to > * skb_tx_hash and will put the skbs in the queue we expect on their > * way down to the bonding driver. > */ >- return skb->queue_mapping; >+ return skb->queue_mapping ? skb->queue_mapping - 1 : 0; > } > > static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) --- -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] bonding: bond_select_queue off by one 2011-02-18 4:41 ` Jay Vosburgh @ 2011-02-18 22:49 ` Andy Gospodarek 2011-02-18 23:06 ` Ben Hutchings 0 siblings, 1 reply; 6+ messages in thread From: Andy Gospodarek @ 2011-02-18 22:49 UTC (permalink / raw) To: Jay Vosburgh; +Cc: Andy Gospodarek, Phil Oester, netdev On Thu, Feb 17, 2011 at 08:41:48PM -0800, Jay Vosburgh wrote: > Phil Oester <kernel@linuxace.com> wrote: > > >The bonding driver's bond_select_queue function simply returns > >skb->queue_mapping. However queue_mapping could be == 16 > >for queue #16. This causes the following message to be flooded > >to syslog: > > > >kernel: bondx selects TX queue 16, but real number of TX queues is 16 > > > >ndo_select_queue wants a zero-based number, so bonding driver needs > >to subtract one to return the proper queue number. Also fix grammar in > >a comment while in the vicinity. > > Andy, can you comment on this? > > If memory serves, the omission of queue ID zero was on purpose; > is this patch going to break any of the functionality added by: > > commit bb1d912323d5dd50e1079e389f4e964be14f0ae3 > Author: Andy Gospodarek <andy@greyhouse.net> > Date: Wed Jun 2 08:40:18 2010 +0000 > > bonding: allow user-controlled output slave selection > My original intent was that a queue_mapping == 0 would indicate that the mode's default transmit routine would be used. We could still operate under this assumption, however. I think the patch below will work. > Ben Hutchings <bhutchings@solarflare.com> wrote: > > >This looks basically correct, but it should use the proper functions: > > > > skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; > > As Ben points out, skb_rx_queue_recorded, skb_record_rx_queue, > et al, do the offset by one internally, but the bond_slave_override > function is comparing the slave's queue_id to the skb->queue_mapping. > > That makes me wonder if this patch is going to mess things up, > and if bond_slave_override should also use the skb_rx_queue_recorded, et > al, functions. > They could be use them, but I really dislike using functions with 'rx' in the name for options that are clearly for transmit. I would rather get rid of access to queue_id or queue_mapping in the code in question. How about something like this? I have not fully tested this, but will and would appreciate feedback from Phil or anyone else. Signed-off-by: Andy Gospodarek <andy@greyhouse.net> --- drivers/net/bonding/bond_main.c | 11 ++++++----- drivers/net/bonding/bond_sysfs.c | 2 +- drivers/net/bonding/bonding.h | 16 ++++++++++++++++ include/linux/skbuff.h | 15 +++++++++++++++ net/core/dev.c | 4 ++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 77e3c6a..02d8161 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4511,20 +4511,21 @@ static inline int bond_slave_override(struct bonding *bond, read_lock(&bond->lock); - if (!BOND_IS_OK(bond) || !skb->queue_mapping) + if (!BOND_IS_OK(bond) || !skb_tx_queue_recorded(skb)) goto out; /* Find out if any slaves have the same mapping as this skb. */ bond_for_each_slave(bond, check_slave, i) { - if (check_slave->queue_id == skb->queue_mapping) { + if (slave_tx_queue_recorded(check_slave) && + slave_get_tx_queue(check_slave) == skb_get_tx_queue(skb)) { slave = check_slave; break; } } /* If the slave isn't UP, use default transmit policy. */ - if (slave && slave->queue_id && IS_UP(slave->dev) && - (slave->link == BOND_LINK_UP)) { + if (slave && slave_tx_queue_recorded(slave) && + IS_UP(slave->dev) && (slave->link == BOND_LINK_UP)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); } @@ -4541,7 +4542,7 @@ 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. */ - return skb->queue_mapping; + return skb_tx_queue_recorded(skb) ? skb_get_tx_queue(skb) : 0; } static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 72bb0f6..b3bc092 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1499,7 +1499,7 @@ static ssize_t bonding_store_queue_id(struct device *d, /* Check buffer length, valid ifname and queue id */ if (strlen(buffer) > IFNAMSIZ || !dev_valid_name(buffer) || - qid > bond->params.tx_queues) + qid >= bond->params.tx_queues) goto err_no_cmd; /* Get the pointer to that interface if it exists */ diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 31fe980..75b5798 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -422,4 +422,20 @@ static inline void bond_unregister_ipv6_notifier(void) } #endif +static inline void slave_record_tx_queue(struct slave *slave, u16 tx_queue) +{ + slave->queue_id = tx_queue + 1; +} + +static inline u16 slave_get_tx_queue(const struct slave *slave) +{ + return slave->queue_id - 1; +} + +static inline bool slave_tx_queue_recorded(const struct slave *slave) +{ + return slave->queue_id != 0; +} + + #endif /* _LINUX_BONDING_H */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 31f02d0..49d101c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2194,6 +2194,21 @@ static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) return skb->queue_mapping != 0; } +static inline void skb_record_tx_queue(struct sk_buff *skb, u16 tx_queue) +{ + skb->queue_mapping = tx_queue + 1; +} + +static inline u16 skb_get_tx_queue(const struct sk_buff *skb) +{ + return skb->queue_mapping - 1; +} + +static inline bool skb_tx_queue_recorded(const struct sk_buff *skb) +{ + return skb->queue_mapping != 0; +} + extern u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, unsigned int num_tx_queues); diff --git a/net/core/dev.c b/net/core/dev.c index a413276..50aa490 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2211,8 +2211,8 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, u16 qoffset = 0; u16 qcount = num_tx_queues; - if (skb_rx_queue_recorded(skb)) { - hash = skb_get_rx_queue(skb); + if (skb_tx_queue_recorded(skb)) { + hash = skb_get_tx_queue(skb); while (unlikely(hash >= num_tx_queues)) hash -= num_tx_queues; return hash; ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] bonding: bond_select_queue off by one 2011-02-18 22:49 ` Andy Gospodarek @ 2011-02-18 23:06 ` Ben Hutchings 2011-02-21 18:06 ` Andy Gospodarek 0 siblings, 1 reply; 6+ messages in thread From: Ben Hutchings @ 2011-02-18 23:06 UTC (permalink / raw) To: Andy Gospodarek; +Cc: Jay Vosburgh, Phil Oester, netdev On Fri, 2011-02-18 at 17:49 -0500, Andy Gospodarek wrote: > On Thu, Feb 17, 2011 at 08:41:48PM -0800, Jay Vosburgh wrote: > > Phil Oester <kernel@linuxace.com> wrote: > > > > >The bonding driver's bond_select_queue function simply returns > > >skb->queue_mapping. However queue_mapping could be == 16 > > >for queue #16. This causes the following message to be flooded > > >to syslog: > > > > > >kernel: bondx selects TX queue 16, but real number of TX queues is 16 > > > > > >ndo_select_queue wants a zero-based number, so bonding driver needs > > >to subtract one to return the proper queue number. Also fix grammar in > > >a comment while in the vicinity. > > > > Andy, can you comment on this? > > > > If memory serves, the omission of queue ID zero was on purpose; > > is this patch going to break any of the functionality added by: > > > > commit bb1d912323d5dd50e1079e389f4e964be14f0ae3 > > Author: Andy Gospodarek <andy@greyhouse.net> > > Date: Wed Jun 2 08:40:18 2010 +0000 > > > > bonding: allow user-controlled output slave selection > > > > My original intent was that a queue_mapping == 0 would indicate that the > mode's default transmit routine would be used. We could still operate > under this assumption, however. I think the patch below will work. > > > Ben Hutchings <bhutchings@solarflare.com> wrote: > > > > >This looks basically correct, but it should use the proper functions: > > > > > > skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; > > > > As Ben points out, skb_rx_queue_recorded, skb_record_rx_queue, > > et al, do the offset by one internally, but the bond_slave_override > > function is comparing the slave's queue_id to the skb->queue_mapping. > > > > That makes me wonder if this patch is going to mess things up, > > and if bond_slave_override should also use the skb_rx_queue_recorded, et > > al, functions. > > > > They could be use them, but I really dislike using functions with 'rx' > in the name for options that are clearly for transmit. This isn't an option for transmit, it is a record of the result of RX hashing (or steering). It may or may not then be used to select a TX queue. [...] > --- a/include/linux/skbuff.h > +++ b/include/linux/skbuff.h > @@ -2194,6 +2194,21 @@ static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) > return skb->queue_mapping != 0; > } > > +static inline void skb_record_tx_queue(struct sk_buff *skb, u16 tx_queue) > +{ > + skb->queue_mapping = tx_queue + 1; > +} > + > +static inline u16 skb_get_tx_queue(const struct sk_buff *skb) > +{ > + return skb->queue_mapping - 1; > +} > + > +static inline bool skb_tx_queue_recorded(const struct sk_buff *skb) > +{ > + return skb->queue_mapping != 0; > +} > + [...] This is nonsense. After the TX queue has been selected, it's recorded in queue_mapping *without* the offset (skb_set_queue_mapping()). Ben. -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] bonding: bond_select_queue off by one 2011-02-18 23:06 ` Ben Hutchings @ 2011-02-21 18:06 ` Andy Gospodarek 0 siblings, 0 replies; 6+ messages in thread From: Andy Gospodarek @ 2011-02-21 18:06 UTC (permalink / raw) To: Ben Hutchings; +Cc: Andy Gospodarek, Jay Vosburgh, Phil Oester, netdev On Fri, Feb 18, 2011 at 11:06:12PM +0000, Ben Hutchings wrote: > On Fri, 2011-02-18 at 17:49 -0500, Andy Gospodarek wrote: > > --- a/include/linux/skbuff.h > > +++ b/include/linux/skbuff.h > > @@ -2194,6 +2194,21 @@ static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) > > return skb->queue_mapping != 0; > > } > > > > +static inline void skb_record_tx_queue(struct sk_buff *skb, u16 tx_queue) > > +{ > > + skb->queue_mapping = tx_queue + 1; > > +} > > + > > +static inline u16 skb_get_tx_queue(const struct sk_buff *skb) > > +{ > > + return skb->queue_mapping - 1; > > +} > > + > > +static inline bool skb_tx_queue_recorded(const struct sk_buff *skb) > > +{ > > + return skb->queue_mapping != 0; > > +} > > + > [...] > > This is nonsense. After the TX queue has been selected, it's recorded > in queue_mapping *without* the offset (skb_set_queue_mapping()). > I see that now. Yay for symmetry! :) I'm actually looking over this now and will post a tested patch to address the original reporter's problem. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-02-21 18:13 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-02-18 2:07 [PATCH] bonding: bond_select_queue off by one Phil Oester 2011-02-18 3:46 ` Ben Hutchings 2011-02-18 4:41 ` Jay Vosburgh 2011-02-18 22:49 ` Andy Gospodarek 2011-02-18 23:06 ` Ben Hutchings 2011-02-21 18:06 ` Andy Gospodarek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).