* [PATCH net-next 0/2] ethtool, net/mlx4_en: RSS hash function selection
@ 2014-11-05 11:59 Amir Vadai
2014-11-05 11:59 ` [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function Amir Vadai
2014-11-05 11:59 ` [PATCH net-next 2/2] net/mlx4_en: " Amir Vadai
0 siblings, 2 replies; 10+ messages in thread
From: Amir Vadai @ 2014-11-05 11:59 UTC (permalink / raw)
To: David S. Miller, Ben Hutchings
Cc: netdev, Or Gerlitz, Eyal Perry, Yevgeny Petrilin, Amir Vadai
Hi,
This patchset by Eyal adds support in set/get of RSS hash function. Current
supported functions are Toeplitz and XOR. The API is design to enable adding
new hash functions without breaking backward compatibility.
If a driver want to use this API need to implement [gs]et_rxfh_func() callbacks
in ethtool_ops.
Userspace patch will be sent after API is available in kernel.
The patchset was applied and tested over commit 30349bd ("net: phy: spi_ks8995:
remove sysfs bin file by registered attribute")
Amir
Eyal Perry (2):
ethtool: Support for configurable RSS hash function
net/mlx4_en: Support for configurable RSS hash function
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40 +++++++++++++++++++
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 +++++
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++--
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +-
include/linux/ethtool.h | 28 +++++++++++++
include/uapi/linux/ethtool.h | 6 ++-
net/core/ethtool.c | 52 +++++++++++++++++--------
7 files changed, 127 insertions(+), 22 deletions(-)
--
1.8.3.4
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function 2014-11-05 11:59 [PATCH net-next 0/2] ethtool, net/mlx4_en: RSS hash function selection Amir Vadai @ 2014-11-05 11:59 ` Amir Vadai 2014-11-05 21:51 ` Ben Hutchings 2014-11-05 11:59 ` [PATCH net-next 2/2] net/mlx4_en: " Amir Vadai 1 sibling, 1 reply; 10+ messages in thread From: Amir Vadai @ 2014-11-05 11:59 UTC (permalink / raw) To: David S. Miller, Ben Hutchings Cc: netdev, Or Gerlitz, Eyal Perry, Yevgeny Petrilin, Amir Vadai From: Eyal Perry <eyalpe@mellanox.com> This patch adds an RSS hash functions string-set, and two ethtool-options for set/get current RSS hash function. User-kernel API is done through the new hfunc mask field in the ethtool_rxfh struct. A bit set in the hfunc is corresponding to an index in the string-set. Signed-off-by: Eyal Perry <eyalpe@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> --- include/linux/ethtool.h | 28 ++++++++++++++++++++++++ include/uapi/linux/ethtool.h | 6 ++++- net/core/ethtool.c | 52 ++++++++++++++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c1a2d60..61003b1 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -59,6 +59,29 @@ enum ethtool_phys_id_state { ETHTOOL_ID_OFF }; +enum { + RSS_HASH_TOP_BIT, /* Configurable RSS hash function - Toeplitz */ + RSS_HASH_XOR_BIT, /* Configurable RSS hash function - Xor */ + + /* + * Add your fresh new hash function bits above and remember to update + * rss_hash_func_strings[] below + */ + RSS_HASH_FUNCS_COUNT +}; + +#define __RSS_HASH_BIT(bit) ((u32)1 << (bit)) +#define __RSS_HASH(name) __RSS_HASH_BIT(RSS_HASH_##name##_BIT) + +#define RSS_HASH_TOP __RSS_HASH(TOP) +#define RSS_HASH_XOR __RSS_HASH(XOR) + +static const char +rss_hash_func_strings[RSS_HASH_FUNCS_COUNT][ETH_GSTRING_LEN] = { + [RSS_HASH_TOP_BIT] = "toeplitz", + [RSS_HASH_XOR_BIT] = "xor", +}; + struct net_device; /* Some generic methods drivers may use in their ethtool_ops */ @@ -158,6 +181,9 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) * Returns zero if not supported for this specific device. * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table. * Returns zero if not supported for this specific device. + * @get_rxfh_func: Get the hardware RX flow hash function. + * @set_rxfh_func: Set the hardware RX flow hash function. Returns a negative + * error code or zero. * @get_rxfh: Get the contents of the RX flow hash indirection table and hash * key. * Will only be called if one or both of @get_rxfh_indir_size and @@ -241,6 +267,8 @@ struct ethtool_ops { int (*reset)(struct net_device *, u32 *); u32 (*get_rxfh_key_size)(struct net_device *); u32 (*get_rxfh_indir_size)(struct net_device *); + u32 (*get_rxfh_func)(struct net_device *); + int (*set_rxfh_func)(struct net_device *, u32); int (*get_rxfh)(struct net_device *, u32 *indir, u8 *key); int (*set_rxfh)(struct net_device *, const u32 *indir, const u8 *key); diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index eb2095b..eb91da4 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -534,6 +534,7 @@ struct ethtool_pauseparam { * @ETH_SS_NTUPLE_FILTERS: Previously used with %ETHTOOL_GRXNTUPLE; * now deprecated * @ETH_SS_FEATURES: Device feature names + * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names */ enum ethtool_stringset { ETH_SS_TEST = 0, @@ -541,6 +542,7 @@ enum ethtool_stringset { ETH_SS_PRIV_FLAGS, ETH_SS_NTUPLE_FILTERS, ETH_SS_FEATURES, + ETH_SS_RSS_HASH_FUNCS, }; /** @@ -900,7 +902,9 @@ struct ethtool_rxfh { __u32 rss_context; __u32 indir_size; __u32 key_size; - __u32 rsvd[2]; + __u8 hfunc; + __u8 rsvd8[3]; + __u32 rsvd32; __u32 rss_config[0]; }; #define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 06dfb29..4791c17 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -185,6 +185,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset) if (sset == ETH_SS_FEATURES) return ARRAY_SIZE(netdev_features_strings); + if (sset == ETH_SS_RSS_HASH_FUNCS) + return ARRAY_SIZE(rss_hash_func_strings); + if (ops->get_sset_count && ops->get_strings) return ops->get_sset_count(dev, sset); else @@ -199,6 +202,9 @@ static void __ethtool_get_strings(struct net_device *dev, if (stringset == ETH_SS_FEATURES) memcpy(data, netdev_features_strings, sizeof(netdev_features_strings)); + else if (stringset == ETH_SS_RSS_HASH_FUNCS) + memcpy(data, rss_hash_func_strings, + sizeof(rss_hash_func_strings)); else /* ops->get_strings is valid because checked earlier */ ops->get_strings(dev, stringset, data); @@ -682,7 +688,7 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev, int ret; const struct ethtool_ops *ops = dev->ethtool_ops; u32 user_indir_size, user_key_size; - u32 dev_indir_size = 0, dev_key_size = 0; + u32 dev_indir_size = 0, dev_key_size = 0, dev_hfunc = 0; struct ethtool_rxfh rxfh; u32 total_size; u32 indir_bytes; @@ -690,17 +696,18 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev, u8 *hkey = NULL; u8 *rss_config; - if (!(dev->ethtool_ops->get_rxfh_indir_size || - dev->ethtool_ops->get_rxfh_key_size) || - !dev->ethtool_ops->get_rxfh) + if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size || + ops->get_rxfh_func) || !ops->get_rxfh) return -EOPNOTSUPP; + if (ops->get_rxfh_func) + dev_hfunc = ops->get_rxfh_func(dev); if (ops->get_rxfh_indir_size) dev_indir_size = ops->get_rxfh_indir_size(dev); if (ops->get_rxfh_key_size) dev_key_size = ops->get_rxfh_key_size(dev); - if ((dev_key_size + dev_indir_size) == 0) + if ((dev_key_size + dev_indir_size + dev_hfunc) == 0) return -EOPNOTSUPP; if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) @@ -709,17 +716,19 @@ static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev, user_key_size = rxfh.key_size; /* Check that reserved fields are 0 for now */ - if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1]) + if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || + rxfh.rsvd8[2] || rxfh.rsvd32) return -EINVAL; rxfh.indir_size = dev_indir_size; rxfh.key_size = dev_key_size; + rxfh.hfunc = dev_hfunc; if (copy_to_user(useraddr, &rxfh, sizeof(rxfh))) return -EFAULT; - /* If the user buffer size is 0, this is just a query for the - * device table size and key size. Otherwise, if the User size is - * not equal to device table size or key size it's an error. + /* If the user buffer size is 0, this is just a query for the device + * hash function, table size and key size. Otherwise, if the User size + * is not equal to device table size or key size it's an error. */ if (!user_indir_size && !user_key_size) return 0; @@ -760,32 +769,43 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, const struct ethtool_ops *ops = dev->ethtool_ops; struct ethtool_rxnfc rx_rings; struct ethtool_rxfh rxfh; - u32 dev_indir_size = 0, dev_key_size = 0, i; + u32 dev_indir_size = 0, dev_key_size = 0, dev_hfunc = 0, i; u32 *indir = NULL, indir_bytes = 0; u8 *hkey = NULL; u8 *rss_config; u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]); - if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) || - !ops->get_rxnfc || !ops->set_rxfh) + if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size || + ops->get_rxfh_func) || !ops->get_rxnfc || !ops->set_rxfh) return -EOPNOTSUPP; + if (ops->get_rxfh_func) + dev_hfunc = ops->get_rxfh_func(dev); if (ops->get_rxfh_indir_size) dev_indir_size = ops->get_rxfh_indir_size(dev); if (ops->get_rxfh_key_size) dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev); - if ((dev_key_size + dev_indir_size) == 0) + if ((dev_key_size + dev_indir_size + dev_hfunc) == 0) return -EOPNOTSUPP; if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) return -EFAULT; /* Check that reserved fields are 0 for now */ - if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1]) + if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || + rxfh.rsvd8[2] || rxfh.rsvd32) return -EINVAL; + if (rxfh.hfunc != dev_hfunc) { + if (!ops->set_rxfh_func) + return -EOPNOTSUPP; + ret = ops->set_rxfh_func(dev, rxfh.hfunc); + if (ret) + return ret; + } + /* If either indir or hash key is valid, proceed further. - * It is not valid to request that both be unchanged. + * Must request at least one change: indir size, hash key or function. */ if ((rxfh.indir_size && rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE && @@ -793,7 +813,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, (rxfh.key_size && (rxfh.key_size != dev_key_size)) || (rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE && rxfh.key_size == 0)) - return -EINVAL; + return rxfh.hfunc ? 0 : -EINVAL; if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) indir_bytes = dev_indir_size * sizeof(indir[0]); -- 1.8.3.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function 2014-11-05 11:59 ` [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function Amir Vadai @ 2014-11-05 21:51 ` Ben Hutchings 2014-11-06 9:41 ` Eyal perry 0 siblings, 1 reply; 10+ messages in thread From: Ben Hutchings @ 2014-11-05 21:51 UTC (permalink / raw) To: Amir Vadai Cc: David S. Miller, netdev, Or Gerlitz, Eyal Perry, Yevgeny Petrilin [-- Attachment #1: Type: text/plain, Size: 7383 bytes --] On Wed, 2014-11-05 at 13:59 +0200, Amir Vadai wrote: > From: Eyal Perry <eyalpe@mellanox.com> > > This patch adds an RSS hash functions string-set, and two > ethtool-options for set/get current RSS hash function. User-kernel API is done > through the new hfunc mask field in the ethtool_rxfh struct. A bit set > in the hfunc is corresponding to an index in the string-set. > > Signed-off-by: Eyal Perry <eyalpe@mellanox.com> > Signed-off-by: Amir Vadai <amirv@mellanox.com> > --- > include/linux/ethtool.h | 28 ++++++++++++++++++++++++ > include/uapi/linux/ethtool.h | 6 ++++- > net/core/ethtool.c | 52 ++++++++++++++++++++++++++++++-------------- > 3 files changed, 69 insertions(+), 17 deletions(-) > > diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h > index c1a2d60..61003b1 100644 > --- a/include/linux/ethtool.h > +++ b/include/linux/ethtool.h > @@ -59,6 +59,29 @@ enum ethtool_phys_id_state { > ETHTOOL_ID_OFF > }; > > +enum { > + RSS_HASH_TOP_BIT, /* Configurable RSS hash function - Toeplitz */ > + RSS_HASH_XOR_BIT, /* Configurable RSS hash function - Xor */ > + > + /* > + * Add your fresh new hash function bits above and remember to update > + * rss_hash_func_strings[] below > + */ > + RSS_HASH_FUNCS_COUNT > +}; > + > +#define __RSS_HASH_BIT(bit) ((u32)1 << (bit)) > +#define __RSS_HASH(name) __RSS_HASH_BIT(RSS_HASH_##name##_BIT) > + > +#define RSS_HASH_TOP __RSS_HASH(TOP) > +#define RSS_HASH_XOR __RSS_HASH(XOR) I think #define RSS_HASH_UNKNOWN 0 might also be useful. And I think all of these names should get an ETH_ prefix. > +static const char > +rss_hash_func_strings[RSS_HASH_FUNCS_COUNT][ETH_GSTRING_LEN] = { > + [RSS_HASH_TOP_BIT] = "toeplitz", > + [RSS_HASH_XOR_BIT] = "xor", > +}; This belongs in net/core/ethtool.c. > struct net_device; > > /* Some generic methods drivers may use in their ethtool_ops */ > @@ -158,6 +181,9 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) > * Returns zero if not supported for this specific device. > * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table. > * Returns zero if not supported for this specific device. > + * @get_rxfh_func: Get the hardware RX flow hash function. > + * @set_rxfh_func: Set the hardware RX flow hash function. Returns a negative > + * error code or zero. > * @get_rxfh: Get the contents of the RX flow hash indirection table and hash > * key. > * Will only be called if one or both of @get_rxfh_indir_size and > @@ -241,6 +267,8 @@ struct ethtool_ops { > int (*reset)(struct net_device *, u32 *); > u32 (*get_rxfh_key_size)(struct net_device *); > u32 (*get_rxfh_indir_size)(struct net_device *); > + u32 (*get_rxfh_func)(struct net_device *); > + int (*set_rxfh_func)(struct net_device *, u32); Why not another parameter to get_rxfh/set_rxfh? I know it's a pain to update all the implementations, but changing algorithm potentially changes the supported indirection table and key lengths. They have to be validated together. > int (*get_rxfh)(struct net_device *, u32 *indir, u8 *key); > int (*set_rxfh)(struct net_device *, const u32 *indir, > const u8 *key); > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h > index eb2095b..eb91da4 100644 > --- a/include/uapi/linux/ethtool.h > +++ b/include/uapi/linux/ethtool.h > @@ -534,6 +534,7 @@ struct ethtool_pauseparam { > * @ETH_SS_NTUPLE_FILTERS: Previously used with %ETHTOOL_GRXNTUPLE; > * now deprecated > * @ETH_SS_FEATURES: Device feature names > + * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names > */ > enum ethtool_stringset { > ETH_SS_TEST = 0, > @@ -541,6 +542,7 @@ enum ethtool_stringset { > ETH_SS_PRIV_FLAGS, > ETH_SS_NTUPLE_FILTERS, > ETH_SS_FEATURES, > + ETH_SS_RSS_HASH_FUNCS, > }; > > /** > @@ -900,7 +902,9 @@ struct ethtool_rxfh { > __u32 rss_context; > __u32 indir_size; > __u32 key_size; > - __u32 rsvd[2]; > + __u8 hfunc; Missing kernel-doc. This needs to be very clear about what the valid values are. > + __u8 rsvd8[3]; > + __u32 rsvd32; > __u32 rss_config[0]; > }; > #define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff > diff --git a/net/core/ethtool.c b/net/core/ethtool.c > index 06dfb29..4791c17 100644 > --- a/net/core/ethtool.c > +++ b/net/core/ethtool.c > @@ -185,6 +185,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset) > if (sset == ETH_SS_FEATURES) > return ARRAY_SIZE(netdev_features_strings); > > + if (sset == ETH_SS_RSS_HASH_FUNCS) > + return ARRAY_SIZE(rss_hash_func_strings); > + > if (ops->get_sset_count && ops->get_strings) > return ops->get_sset_count(dev, sset); > else [...] > @@ -760,32 +769,43 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, > const struct ethtool_ops *ops = dev->ethtool_ops; > struct ethtool_rxnfc rx_rings; > struct ethtool_rxfh rxfh; > - u32 dev_indir_size = 0, dev_key_size = 0, i; > + u32 dev_indir_size = 0, dev_key_size = 0, dev_hfunc = 0, i; > u32 *indir = NULL, indir_bytes = 0; > u8 *hkey = NULL; > u8 *rss_config; > u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]); > > - if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) || > - !ops->get_rxnfc || !ops->set_rxfh) > + if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size || > + ops->get_rxfh_func) || !ops->get_rxnfc || !ops->set_rxfh) > return -EOPNOTSUPP; > > + if (ops->get_rxfh_func) > + dev_hfunc = ops->get_rxfh_func(dev); > if (ops->get_rxfh_indir_size) > dev_indir_size = ops->get_rxfh_indir_size(dev); > if (ops->get_rxfh_key_size) > dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev); > - if ((dev_key_size + dev_indir_size) == 0) > + if ((dev_key_size + dev_indir_size + dev_hfunc) == 0) > return -EOPNOTSUPP; > > if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) > return -EFAULT; > > /* Check that reserved fields are 0 for now */ > - if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1]) > + if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || > + rxfh.rsvd8[2] || rxfh.rsvd32) > return -EINVAL; > > + if (rxfh.hfunc != dev_hfunc) { > + if (!ops->set_rxfh_func) > + return -EOPNOTSUPP; > + ret = ops->set_rxfh_func(dev, rxfh.hfunc); > + if (ret) > + return ret; > + } > + > /* If either indir or hash key is valid, proceed further. > - * It is not valid to request that both be unchanged. > + * Must request at least one change: indir size, hash key or function. > */ > if ((rxfh.indir_size && > rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE && > @@ -793,7 +813,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, > (rxfh.key_size && (rxfh.key_size != dev_key_size)) || > (rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE && > rxfh.key_size == 0)) > - return -EINVAL; > + return rxfh.hfunc ? 0 : -EINVAL; Shouldn't the condition be rxfh.hfunc != dev_hfunc ? Ben. > if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) > indir_bytes = dev_indir_size * sizeof(indir[0]); -- Ben Hutchings The program is absolutely right; therefore, the computer must be wrong. [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function 2014-11-05 21:51 ` Ben Hutchings @ 2014-11-06 9:41 ` Eyal perry 0 siblings, 0 replies; 10+ messages in thread From: Eyal perry @ 2014-11-06 9:41 UTC (permalink / raw) To: Ben Hutchings, Amir Vadai Cc: David S. Miller, netdev, Or Gerlitz, Eyal Perry, Yevgeny Petrilin On 11/5/2014 11:51 PM, Ben Hutchings wrote: > On Wed, 2014-11-05 at 13:59 +0200, Amir Vadai wrote: >> From: Eyal Perry <eyalpe@mellanox.com> >> >> This patch adds an RSS hash functions string-set, and two >> ethtool-options for set/get current RSS hash function. User-kernel API is done >> through the new hfunc mask field in the ethtool_rxfh struct. A bit set >> in the hfunc is corresponding to an index in the string-set. >> >> Signed-off-by: Eyal Perry <eyalpe@mellanox.com> >> Signed-off-by: Amir Vadai <amirv@mellanox.com> >> --- >> include/linux/ethtool.h | 28 ++++++++++++++++++++++++ >> include/uapi/linux/ethtool.h | 6 ++++- >> net/core/ethtool.c | 52 ++++++++++++++++++++++++++++++-------------- >> 3 files changed, 69 insertions(+), 17 deletions(-) >> >> diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h >> index c1a2d60..61003b1 100644 >> --- a/include/linux/ethtool.h >> +++ b/include/linux/ethtool.h >> @@ -59,6 +59,29 @@ enum ethtool_phys_id_state { >> ETHTOOL_ID_OFF >> }; >> >> +enum { >> + RSS_HASH_TOP_BIT, /* Configurable RSS hash function - Toeplitz */ >> + RSS_HASH_XOR_BIT, /* Configurable RSS hash function - Xor */ >> + >> + /* >> + * Add your fresh new hash function bits above and remember to update >> + * rss_hash_func_strings[] below >> + */ >> + RSS_HASH_FUNCS_COUNT >> +}; >> + >> +#define __RSS_HASH_BIT(bit) ((u32)1 << (bit)) >> +#define __RSS_HASH(name) __RSS_HASH_BIT(RSS_HASH_##name##_BIT) >> + >> +#define RSS_HASH_TOP __RSS_HASH(TOP) >> +#define RSS_HASH_XOR __RSS_HASH(XOR) > > I think #define RSS_HASH_UNKNOWN 0 might also be useful. > > And I think all of these names should get an ETH_ prefix. > I'll add it in V1. >> +static const char >> +rss_hash_func_strings[RSS_HASH_FUNCS_COUNT][ETH_GSTRING_LEN] = { >> + [RSS_HASH_TOP_BIT] = "toeplitz", >> + [RSS_HASH_XOR_BIT] = "xor", >> +}; > > This belongs in net/core/ethtool.c. > I agree, will be fixed in V1. >> struct net_device; >> >> /* Some generic methods drivers may use in their ethtool_ops */ >> @@ -158,6 +181,9 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) >> * Returns zero if not supported for this specific device. >> * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table. >> * Returns zero if not supported for this specific device. >> + * @get_rxfh_func: Get the hardware RX flow hash function. >> + * @set_rxfh_func: Set the hardware RX flow hash function. Returns a negative >> + * error code or zero. >> * @get_rxfh: Get the contents of the RX flow hash indirection table and hash >> * key. >> * Will only be called if one or both of @get_rxfh_indir_size and >> @@ -241,6 +267,8 @@ struct ethtool_ops { >> int (*reset)(struct net_device *, u32 *); >> u32 (*get_rxfh_key_size)(struct net_device *); >> u32 (*get_rxfh_indir_size)(struct net_device *); >> + u32 (*get_rxfh_func)(struct net_device *); >> + int (*set_rxfh_func)(struct net_device *, u32); > > Why not another parameter to get_rxfh/set_rxfh? I know it's a pain to > update all the implementations, but changing algorithm potentially > changes the supported indirection table and key lengths. They have to > be validated together. > OK, I'll do it for V1. >> int (*get_rxfh)(struct net_device *, u32 *indir, u8 *key); >> int (*set_rxfh)(struct net_device *, const u32 *indir, >> const u8 *key); >> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h >> index eb2095b..eb91da4 100644 >> --- a/include/uapi/linux/ethtool.h >> +++ b/include/uapi/linux/ethtool.h >> @@ -534,6 +534,7 @@ struct ethtool_pauseparam { >> * @ETH_SS_NTUPLE_FILTERS: Previously used with %ETHTOOL_GRXNTUPLE; >> * now deprecated >> * @ETH_SS_FEATURES: Device feature names >> + * @ETH_SS_RSS_HASH_FUNCS: RSS hush function names >> */ >> enum ethtool_stringset { >> ETH_SS_TEST = 0, >> @@ -541,6 +542,7 @@ enum ethtool_stringset { >> ETH_SS_PRIV_FLAGS, >> ETH_SS_NTUPLE_FILTERS, >> ETH_SS_FEATURES, >> + ETH_SS_RSS_HASH_FUNCS, >> }; >> >> /** >> @@ -900,7 +902,9 @@ struct ethtool_rxfh { >> __u32 rss_context; >> __u32 indir_size; >> __u32 key_size; >> - __u32 rsvd[2]; >> + __u8 hfunc; > > Missing kernel-doc. This needs to be very clear about what the valid > values are. > I'll add it in V1. >> + __u8 rsvd8[3]; >> + __u32 rsvd32; >> __u32 rss_config[0]; >> }; >> #define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c >> index 06dfb29..4791c17 100644 >> --- a/net/core/ethtool.c >> +++ b/net/core/ethtool.c >> @@ -185,6 +185,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset) >> if (sset == ETH_SS_FEATURES) >> return ARRAY_SIZE(netdev_features_strings); >> >> + if (sset == ETH_SS_RSS_HASH_FUNCS) >> + return ARRAY_SIZE(rss_hash_func_strings); >> + >> if (ops->get_sset_count && ops->get_strings) >> return ops->get_sset_count(dev, sset); >> else > [...] >> @@ -760,32 +769,43 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, >> const struct ethtool_ops *ops = dev->ethtool_ops; >> struct ethtool_rxnfc rx_rings; >> struct ethtool_rxfh rxfh; >> - u32 dev_indir_size = 0, dev_key_size = 0, i; >> + u32 dev_indir_size = 0, dev_key_size = 0, dev_hfunc = 0, i; >> u32 *indir = NULL, indir_bytes = 0; >> u8 *hkey = NULL; >> u8 *rss_config; >> u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]); >> >> - if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) || >> - !ops->get_rxnfc || !ops->set_rxfh) >> + if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size || >> + ops->get_rxfh_func) || !ops->get_rxnfc || !ops->set_rxfh) >> return -EOPNOTSUPP; >> >> + if (ops->get_rxfh_func) >> + dev_hfunc = ops->get_rxfh_func(dev); >> if (ops->get_rxfh_indir_size) >> dev_indir_size = ops->get_rxfh_indir_size(dev); >> if (ops->get_rxfh_key_size) >> dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev); >> - if ((dev_key_size + dev_indir_size) == 0) >> + if ((dev_key_size + dev_indir_size + dev_hfunc) == 0) >> return -EOPNOTSUPP; >> >> if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) >> return -EFAULT; >> >> /* Check that reserved fields are 0 for now */ >> - if (rxfh.rss_context || rxfh.rsvd[0] || rxfh.rsvd[1]) >> + if (rxfh.rss_context || rxfh.rsvd8[0] || rxfh.rsvd8[1] || >> + rxfh.rsvd8[2] || rxfh.rsvd32) >> return -EINVAL; >> >> + if (rxfh.hfunc != dev_hfunc) { >> + if (!ops->set_rxfh_func) >> + return -EOPNOTSUPP; >> + ret = ops->set_rxfh_func(dev, rxfh.hfunc); >> + if (ret) >> + return ret; >> + } >> + >> /* If either indir or hash key is valid, proceed further. >> - * It is not valid to request that both be unchanged. >> + * Must request at least one change: indir size, hash key or function. >> */ >> if ((rxfh.indir_size && >> rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE && >> @@ -793,7 +813,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, >> (rxfh.key_size && (rxfh.key_size != dev_key_size)) || >> (rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE && >> rxfh.key_size == 0)) >> - return -EINVAL; >> + return rxfh.hfunc ? 0 : -EINVAL; > > Shouldn't the condition be rxfh.hfunc != dev_hfunc ? > > Ben. > On current implementation it's not necessary since we have already checked that above. However, according to your suggestion, after I'll remove the set/get_rxfh_func() callbacks I wouldn't be able to check that condition at this point of the code. Best Regards, Eyal. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 11:59 [PATCH net-next 0/2] ethtool, net/mlx4_en: RSS hash function selection Amir Vadai 2014-11-05 11:59 ` [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function Amir Vadai @ 2014-11-05 11:59 ` Amir Vadai 2014-11-05 12:27 ` Or Gerlitz 2014-11-05 13:53 ` Or Gerlitz 1 sibling, 2 replies; 10+ messages in thread From: Amir Vadai @ 2014-11-05 11:59 UTC (permalink / raw) To: David S. Miller, Ben Hutchings Cc: netdev, Or Gerlitz, Eyal Perry, Yevgeny Petrilin, Amir Vadai From: Eyal Perry <eyalpe@mellanox.com> The ConnectX HW is capable of using one of the following hash functions: Toeplitz and an XOR hash function. This patch implements ethtool_ops {get,set}_rxfh_func callbacks for the mlx4_en driver in order to query and configure the RSS hash function to be used by the device. Signed-off-by: Eyal Perry <eyalpe@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40 +++++++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 ++++++ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++--- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 8ea4d5b..f33785a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -973,6 +973,44 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev) return priv->rx_ring_num; } +static u32 mlx4_en_get_rxfh_func(struct net_device *dev) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + + return priv->rss_hash_fn; +} + +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + u32 prev_rss_hash_fn = priv->rss_hash_fn; + int err = 0; + + if (!(hfunc & priv->rss_hash_fn_caps)) + return -EINVAL; + + priv->rss_hash_fn = hfunc; + if (hfunc == RSS_HASH_TOP && !(dev->features & NETIF_F_RXHASH)) + en_warn(priv, + "Toeplitz hash function should be used in conjunction with RX hashing for optimal performance\n"); + if (hfunc == RSS_HASH_XOR && (dev->features & NETIF_F_RXHASH)) + en_warn(priv, + "Enabling both XOR Hash function and RX Hashing can limit RPS functionality\n"); + + mutex_lock(&mdev->state_lock); + if (priv->port_up && priv->rss_hash_fn != prev_rss_hash_fn) { + mlx4_en_stop_port(dev, 1); + err = mlx4_en_start_port(dev); + } + mutex_unlock(&mdev->state_lock); + + if (err) + en_err(priv, "Failed to restart port %d\n", priv->port); + + return err; +} + static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) { struct mlx4_en_priv *priv = netdev_priv(dev); @@ -1799,6 +1837,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_rxnfc = mlx4_en_get_rxnfc, .set_rxnfc = mlx4_en_set_rxnfc, .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, + .get_rxfh_func = mlx4_en_get_rxfh_func, + .set_rxfh_func = mlx4_en_set_rxfh_func, .get_rxfh = mlx4_en_get_rxfh, .set_rxfh = mlx4_en_set_rxfh, .get_channels = mlx4_en_get_channels, diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 0efbae9..a9e96a6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2585,6 +2585,15 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->features |= NETIF_F_GSO_UDP_TUNNEL; } + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR) { + priv->rss_hash_fn_caps |= RSS_HASH_XOR; + priv->rss_hash_fn = RSS_HASH_XOR; + } + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) { + priv->rss_hash_fn_caps |= RSS_HASH_TOP; + priv->rss_hash_fn = RSS_HASH_TOP; + } + mdev->pndev[port] = dev; netif_carrier_off(dev); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b173a0c..41c1ff9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) } rss_context->flags = rss_mask; - rss_context->hash_fn = MLX4_RSS_HASH_TOP; - for (i = 0; i < 10; i++) - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); - + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) { + rss_context->hash_fn = MLX4_RSS_HASH_XOR; + } else { + rss_context->hash_fn = MLX4_RSS_HASH_TOP; + for (i = 0; i < 10; i++) + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); + } err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); if (err) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index ef83d12..e1c3364 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -375,7 +375,6 @@ struct mlx4_en_port_profile { }; struct mlx4_en_profile { - int rss_xor; int udp_rss; u8 rss_mask; u32 active_ports; @@ -615,6 +614,8 @@ struct mlx4_en_priv { __be16 vxlan_port; u32 pflags; + u8 rss_hash_fn; + u8 rss_hash_fn_caps; }; enum mlx4_en_wol { -- 1.8.3.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 11:59 ` [PATCH net-next 2/2] net/mlx4_en: " Amir Vadai @ 2014-11-05 12:27 ` Or Gerlitz 2014-11-05 13:05 ` Eyal perry 2014-11-05 13:53 ` Or Gerlitz 1 sibling, 1 reply; 10+ messages in thread From: Or Gerlitz @ 2014-11-05 12:27 UTC (permalink / raw) To: Eyal Perry Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev, Yevgeny Petrilin On 11/5/2014 1:59 PM, Amir Vadai wrote: > From: Eyal Perry <eyalpe@mellanox.com> > > The ConnectX HW is capable of using one of the following hash functions: > Toeplitz and an XOR hash function. > This patch implements ethtool_ops {get,set}_rxfh_func callbacks for the > mlx4_en driver in order to query and configure the RSS hash function to > be used by the device. > > Signed-off-by: Eyal Perry <eyalpe@mellanox.com> > Signed-off-by: Amir Vadai <amirv@mellanox.com> > --- > drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40 +++++++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 ++++++ > drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++--- > drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +- > 4 files changed, 58 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c > index 8ea4d5b..f33785a 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c > @@ -973,6 +973,44 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev) > return priv->rx_ring_num; > } > > +static u32 mlx4_en_get_rxfh_func(struct net_device *dev) > +{ > + struct mlx4_en_priv *priv = netdev_priv(dev); > + > + return priv->rss_hash_fn; > +} > + > +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc) > +{ > + struct mlx4_en_priv *priv = netdev_priv(dev); > + struct mlx4_en_dev *mdev = priv->mdev; > + u32 prev_rss_hash_fn = priv->rss_hash_fn; > + int err = 0; > + > + if (!(hfunc & priv->rss_hash_fn_caps)) > + return -EINVAL; > + > + priv->rss_hash_fn = hfunc; Seems that you are blindly setting here priv->rss_hash_fn to the function (xor or top) requested by the user w.o prior checking if the firmware actually supports that (e.g test it against priv->rss_hash_fn_caps, right? > + if (hfunc == RSS_HASH_TOP && !(dev->features & NETIF_F_RXHASH)) > + en_warn(priv, > + "Toeplitz hash function should be used in conjunction with RX hashing for optimal performance\n"); > + if (hfunc == RSS_HASH_XOR && (dev->features & NETIF_F_RXHASH)) > + en_warn(priv, > + "Enabling both XOR Hash function and RX Hashing can limit RPS functionality\n"); > + > + mutex_lock(&mdev->state_lock); > + if (priv->port_up && priv->rss_hash_fn != prev_rss_hash_fn) { > + mlx4_en_stop_port(dev, 1); > + err = mlx4_en_start_port(dev); > + } > + mutex_unlock(&mdev->state_lock); > + > + if (err) > + en_err(priv, "Failed to restart port %d\n", priv->port); > + > + return err; > +} > + > static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) > { > struct mlx4_en_priv *priv = netdev_priv(dev); > @@ -1799,6 +1837,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { > .get_rxnfc = mlx4_en_get_rxnfc, > .set_rxnfc = mlx4_en_set_rxnfc, > .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, > + .get_rxfh_func = mlx4_en_get_rxfh_func, > + .set_rxfh_func = mlx4_en_set_rxfh_func, > .get_rxfh = mlx4_en_get_rxfh, > .set_rxfh = mlx4_en_set_rxfh, > .get_channels = mlx4_en_get_channels, > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c > index 0efbae9..a9e96a6 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c > @@ -2585,6 +2585,15 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, > dev->features |= NETIF_F_GSO_UDP_TUNNEL; > } > > + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR) { > + priv->rss_hash_fn_caps |= RSS_HASH_XOR; > + priv->rss_hash_fn = RSS_HASH_XOR; > + } > + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) { > + priv->rss_hash_fn_caps |= RSS_HASH_TOP; > + priv->rss_hash_fn = RSS_HASH_TOP; > + } > + > mdev->pndev[port] = dev; > > netif_carrier_off(dev); > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c > index b173a0c..41c1ff9 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c > @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) > } > > rss_context->flags = rss_mask; > - rss_context->hash_fn = MLX4_RSS_HASH_TOP; > - for (i = 0; i < 10; i++) > - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); > - > + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) { > + rss_context->hash_fn = MLX4_RSS_HASH_XOR; > + } else { > + rss_context->hash_fn = MLX4_RSS_HASH_TOP; > + for (i = 0; i < 10; i++) > + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); > + } So this patch effectively changes the default from top to xor, right? is that intentional? if yes, spare few words on the change log. > err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, > &rss_map->indir_qp, &rss_map->indir_state); > if (err) > diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > index ef83d12..e1c3364 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > @@ -375,7 +375,6 @@ struct mlx4_en_port_profile { > }; > > struct mlx4_en_profile { > - int rss_xor; > int udp_rss; > u8 rss_mask; > u32 active_ports; > @@ -615,6 +614,8 @@ struct mlx4_en_priv { > __be16 vxlan_port; > > u32 pflags; > + u8 rss_hash_fn; > + u8 rss_hash_fn_caps; > }; > > enum mlx4_en_wol { ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 12:27 ` Or Gerlitz @ 2014-11-05 13:05 ` Eyal perry 2014-11-05 13:30 ` Or Gerlitz 0 siblings, 1 reply; 10+ messages in thread From: Eyal perry @ 2014-11-05 13:05 UTC (permalink / raw) To: Or Gerlitz, Eyal Perry Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev, Yevgeny Petrilin On 11/5/2014 2:27 PM, Or Gerlitz wrote: > On 11/5/2014 1:59 PM, Amir Vadai wrote: >> From: Eyal Perry <eyalpe@mellanox.com> >> >> The ConnectX HW is capable of using one of the following hash functions: >> Toeplitz and an XOR hash function. >> This patch implements ethtool_ops {get,set}_rxfh_func callbacks for the >> mlx4_en driver in order to query and configure the RSS hash function to >> be used by the device. >> >> Signed-off-by: Eyal Perry <eyalpe@mellanox.com> >> Signed-off-by: Amir Vadai <amirv@mellanox.com> >> --- >> drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 40 >> +++++++++++++++++++++++++ >> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 ++++++ >> drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++--- >> drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +- >> 4 files changed, 58 insertions(+), 5 deletions(-) >> [...] >> + >> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc) >> +{ >> + struct mlx4_en_priv *priv = netdev_priv(dev); >> + struct mlx4_en_dev *mdev = priv->mdev; >> + u32 prev_rss_hash_fn = priv->rss_hash_fn; >> + int err = 0; >> + >> + if (!(hfunc & priv->rss_hash_fn_caps)) >> + return -EINVAL; >> + >> + priv->rss_hash_fn = hfunc; > > Seems that you are blindly setting here priv->rss_hash_fn to the > function (xor or top) requested > by the user w.o prior checking if the firmware actually supports that > (e.g test it against priv->rss_hash_fn_caps, right? > That exactly what I do 3 lines above, priv->rss_hash_fn_caps is derived from firmware capabilities. [...] >> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c >> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c >> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct >> mlx4_en_priv *priv) >> } >> rss_context->flags = rss_mask; >> - rss_context->hash_fn = MLX4_RSS_HASH_TOP; >> - for (i = 0; i < 10; i++) >> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >> - >> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) { >> + rss_context->hash_fn = MLX4_RSS_HASH_XOR; >> + } else { >> + rss_context->hash_fn = MLX4_RSS_HASH_TOP; >> + for (i = 0; i < 10; i++) >> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >> + } > > So this patch effectively changes the default from top to xor, right? is > that intentional? if yes, spare few words on the change log. > No, in general the default shouldn't be affected by the patch (unless there's a bug). The default value is set in mlx4_en_init_netdev() and it will remain Toeplitz unless firmware is supports only XOR hash function. [...] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 13:05 ` Eyal perry @ 2014-11-05 13:30 ` Or Gerlitz 2014-11-05 13:48 ` Eyal perry 0 siblings, 1 reply; 10+ messages in thread From: Or Gerlitz @ 2014-11-05 13:30 UTC (permalink / raw) To: Eyal perry, Eyal Perry Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev, Yevgeny Petrilin On 11/5/2014 3:05 PM, Eyal perry wrote: > On 11/5/2014 2:27 PM, Or Gerlitz wrote: >>> + >>> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc) >>> +{ >>> + struct mlx4_en_priv *priv = netdev_priv(dev); >>> + struct mlx4_en_dev *mdev = priv->mdev; >>> + u32 prev_rss_hash_fn = priv->rss_hash_fn; >>> + int err = 0; >>> + >>> + if (!(hfunc & priv->rss_hash_fn_caps)) >>> + return -EINVAL; >>> + >>> + priv->rss_hash_fn = hfunc; >> Seems that you are blindly setting here priv->rss_hash_fn to the function (xor or top) requested by the user w.o prior checking if the firmware actually supports that >> (e.g test it against priv->rss_hash_fn_caps, right? >> > That exactly what I do 3 lines above, priv->rss_hash_fn_caps is derived from firmware capabilities. got it, thanks. > > [...] > >>> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c >>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c >>> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct >>> mlx4_en_priv *priv) >>> } >>> rss_context->flags = rss_mask; >>> - rss_context->hash_fn = MLX4_RSS_HASH_TOP; >>> - for (i = 0; i < 10; i++) >>> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >>> - >>> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) { >>> + rss_context->hash_fn = MLX4_RSS_HASH_XOR; >>> + } else { >>> + rss_context->hash_fn = MLX4_RSS_HASH_TOP; >>> + for (i = 0; i < 10; i++) >>> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >>> + } >> So this patch effectively changes the default from top to xor, right? is >> that intentional? if yes, spare few words on the change log. >> > No, in general the default shouldn't be affected by the patch (unless > there's a bug). The default value is set in mlx4_en_init_netdev() and it > will remain Toeplitz unless firmware is supports only XOR hash function. > Oh, I see why I was confused and what I think need to be fixed. You are using both MLX4_RSS_HASH_TOP/XOR and RSS_HASH_TOP/XOR, any reason for that? Also, priv->rss_hash_fn should equal one value, right? so this code "if (priv->rss_hash_fn & something)" is confusing, should be "if (priv->rss_hash_fn == something)" Or. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 13:30 ` Or Gerlitz @ 2014-11-05 13:48 ` Eyal perry 0 siblings, 0 replies; 10+ messages in thread From: Eyal perry @ 2014-11-05 13:48 UTC (permalink / raw) To: Or Gerlitz, Eyal Perry Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev, Yevgeny Petrilin On 11/5/2014 3:30 PM, Or Gerlitz wrote: > On 11/5/2014 3:05 PM, Eyal perry wrote: >> On 11/5/2014 2:27 PM, Or Gerlitz wrote: >>>> + >>>> +static int mlx4_en_set_rxfh_func(struct net_device *dev, u32 hfunc) >>>> +{ >>>> + struct mlx4_en_priv *priv = netdev_priv(dev); >>>> + struct mlx4_en_dev *mdev = priv->mdev; >>>> + u32 prev_rss_hash_fn = priv->rss_hash_fn; >>>> + int err = 0; >>>> + >>>> + if (!(hfunc & priv->rss_hash_fn_caps)) >>>> + return -EINVAL; >>>> + >>>> + priv->rss_hash_fn = hfunc; >>> Seems that you are blindly setting here priv->rss_hash_fn to the >>> function (xor or top) requested by the user w.o prior checking if the >>> firmware actually supports that >>> (e.g test it against priv->rss_hash_fn_caps, right? >>> >> That exactly what I do 3 lines above, priv->rss_hash_fn_caps is >> derived from firmware capabilities. > > got it, thanks. > >> >> [...] >> >>>> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c >>>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c >>>> @@ -1113,10 +1113,13 @@ int mlx4_en_config_rss_steer(struct >>>> mlx4_en_priv *priv) >>>> } >>>> rss_context->flags = rss_mask; >>>> - rss_context->hash_fn = MLX4_RSS_HASH_TOP; >>>> - for (i = 0; i < 10; i++) >>>> - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >>>> - >>>> + if (priv->rss_hash_fn & MLX4_RSS_HASH_XOR) { >>>> + rss_context->hash_fn = MLX4_RSS_HASH_XOR; >>>> + } else { >>>> + rss_context->hash_fn = MLX4_RSS_HASH_TOP; >>>> + for (i = 0; i < 10; i++) >>>> + rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); >>>> + } >>> So this patch effectively changes the default from top to xor, right? is >>> that intentional? if yes, spare few words on the change log. >>> >> No, in general the default shouldn't be affected by the patch (unless >> there's a bug). The default value is set in mlx4_en_init_netdev() and it >> will remain Toeplitz unless firmware is supports only XOR hash function. >> > > Oh, I see why I was confused and what I think need to be fixed. You are > using both MLX4_RSS_HASH_TOP/XOR and RSS_HASH_TOP/XOR, any reason for that? Yes, RSS_HASH_TOP/XOR are bits on a generic bitmask while the MLX4_RSS_HASH_TOP/XOR are HW specific values. > > Also, priv->rss_hash_fn should equal one value, right? so this code "if > (priv->rss_hash_fn & something)" is confusing, should be "if > (priv->rss_hash_fn == something)" That's right, I'll fix it for V1. Thanks. > > Or. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 2/2] net/mlx4_en: Support for configurable RSS hash function 2014-11-05 11:59 ` [PATCH net-next 2/2] net/mlx4_en: " Amir Vadai 2014-11-05 12:27 ` Or Gerlitz @ 2014-11-05 13:53 ` Or Gerlitz 1 sibling, 0 replies; 10+ messages in thread From: Or Gerlitz @ 2014-11-05 13:53 UTC (permalink / raw) To: Eyal Perry Cc: Amir Vadai, David S. Miller, Ben Hutchings, netdev, Yevgeny Petrilin On 11/5/2014 1:59 PM, Amir Vadai wrote: > --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c > @@ -2585,6 +2585,15 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, > dev->features |= NETIF_F_GSO_UDP_TUNNEL; > } > > + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_XOR) { > + priv->rss_hash_fn_caps |= RSS_HASH_XOR; > + priv->rss_hash_fn = RSS_HASH_XOR; > + } > + if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS_TOP) { > + priv->rss_hash_fn_caps |= RSS_HASH_TOP; > + priv->rss_hash_fn = RSS_HASH_TOP; > + } > + can we somehow change this code to be more clear and assign priv->rss_hash_fn once? > mdev->pndev[port] = dev; > > netif_carrier_off(dev); ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-11-06 9:41 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-11-05 11:59 [PATCH net-next 0/2] ethtool, net/mlx4_en: RSS hash function selection Amir Vadai 2014-11-05 11:59 ` [PATCH net-next 1/2] ethtool: Support for configurable RSS hash function Amir Vadai 2014-11-05 21:51 ` Ben Hutchings 2014-11-06 9:41 ` Eyal perry 2014-11-05 11:59 ` [PATCH net-next 2/2] net/mlx4_en: " Amir Vadai 2014-11-05 12:27 ` Or Gerlitz 2014-11-05 13:05 ` Eyal perry 2014-11-05 13:30 ` Or Gerlitz 2014-11-05 13:48 ` Eyal perry 2014-11-05 13:53 ` Or Gerlitz
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).