Symmetric OR-XOR RSS hash
Subsystems (8)
v3 cover Symmetric OR-XOR RSS hash
Add support for a new type of input_xfrm: Symmetric OR-XOR. Symmetric OR-XOR performs hash as follows:
(SRC_IP | DST_IP, SRC_IP ^ DST_IP, SRC_PORT | DST_PORT, SRC_PORT ^ DST_PORT)
Configuration is done through ethtool -x/X command.
For mlx5, the default is already symmetric hash, this patch now exposes this to userspace and allows enabling/disabling of the feature.
Changelog -v2->v3: https://lore.kernel.org/netdev/[email protected]/
* Reorder fields in ethtool_ops (Jakub)
* Add a selftest (Jakub)
v1->v2: https://lore.kernel.org/all/[email protected]/
* Fix wording in comments (Edward)
Thanks,
Gal
Gal Pressman (5):
ethtool: Symmetric OR-XOR RSS hash
net/mlx5e: Symmetric OR-XOR RSS hash control
selftests: drv-net: Make rand_port() get a port more reliably
selftests: drv-net: Introduce a function that checks whether a port is
available on remote host
selftests: drv-net-hw: Add a test for symmetric RSS hash
Documentation/networking/ethtool-netlink.rst | 2 +- Documentation/networking/scaling.rst | 14 +++- .../net/ethernet/intel/iavf/iavf_ethtool.c | 2 +- drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en/rss.c | 13 +++- .../net/ethernet/mellanox/mlx5/core/en/rss.h | 4 +- .../ethernet/mellanox/mlx5/core/en/rx_res.c | 11 +-- .../ethernet/mellanox/mlx5/core/en/rx_res.h | 5 +- .../net/ethernet/mellanox/mlx5/core/en/tir.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en/tir.h | 1 + .../ethernet/mellanox/mlx5/core/en_ethtool.c | 17 +++- include/linux/ethtool.h | 5 +- include/uapi/linux/ethtool.h | 4 + net/ethtool/ioctl.c | 8 +- .../testing/selftests/drivers/net/hw/Makefile | 1 + .../drivers/net/hw/rss_input_xfrm.py | 77 +++++++++++++++++++ .../selftests/drivers/net/lib/py/load.py | 7 +- tools/testing/selftests/net/lib/py/utils.py | 22 +++--- 18 files changed, 155 insertions(+), 42 deletions(-) create mode 100755 tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py
Signature · 1 line
2.40.1
PATCH v3 1/5 ethtool: Symmetric OR-XOR RSS hash
Add an additional type of symmetric RSS hash type: OR-XOR. The "Symmetric-OR-XOR" algorithm transforms the input as follows:
(SRC_IP | DST_IP, SRC_IP ^ DST_IP, SRC_PORT | DST_PORT, SRC_PORT ^ DST_PORT)
Change 'cap_rss_sym_xor_supported' to 'supported_input_xfrm', a bitmap of supported RXH_XFRM_* types.
--- Documentation/networking/ethtool-netlink.rst | 2 +- Documentation/networking/scaling.rst | 14 ++++++++++---- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 2 +- drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +- include/linux/ethtool.h | 5 ++--- include/uapi/linux/ethtool.h | 4 ++++ net/ethtool/ioctl.c | 8 ++++---- 7 files changed, 23 insertions(+), 14 deletions(-)
Documentation/networking/ethtool-netlink.rst +1 -1
@@ -1934,7 +1934,7 @@ ETHTOOL_A_RSS_INDIR attribute returns RSS indirection table where each byte indicates queue number. ETHTOOL_A_RSS_INPUT_XFRM attribute is a bitmap indicating the type of transformation applied to the input protocol fields before given to the RSS -hfunc. Current supported option is symmetric-xor. +hfunc. Current supported options are symmetric-xor and symmetric-or-xor. PLCA_GET_CFG ============
Documentation/networking/scaling.rst +10 -4
@@ -49,14 +49,20 @@ destination address) and TCP/UDP (source port, destination port) tuples are swapped, the computed hash is the same. This is beneficial in some applications that monitor TCP/IP flows (IDS, firewalls, ...etc) and need both directions of the flow to land on the same Rx queue (and CPU). The -"Symmetric-XOR" is a type of RSS algorithms that achieves this hash -symmetry by XORing the input source and destination fields of the IP -and/or L4 protocols. This, however, results in reduced input entropy and -could potentially be exploited. Specifically, the algorithm XORs the input +"Symmetric-XOR" and "Symmetric-OR-XOR" are types of RSS algorithms that +achieve this hash symmetry by XOR/ORing the input source and destination +fields of the IP and/or L4 protocols. This, however, results in reduced +input entropy and could potentially be exploited. + +Specifically, the "Symmetric-XOR" algorithm XORs the input as follows:: # (SRC_IP ^ DST_IP, SRC_IP ^ DST_IP, SRC_PORT ^ DST_PORT, SRC_PORT ^ DST_PORT) +The "Symmetric-OR-XOR" algorithm transforms the input as follows:: + + # (SRC_IP | DST_IP, SRC_IP ^ DST_IP, SRC_PORT | DST_PORT, SRC_PORT ^ DST_PORT) + The result is then fed to the underlying RSS algorithm. Some advanced NICs allow steering packets to queues based on
drivers/net/ethernet/intel/iavf/iavf_ethtool.c +1 -1
@@ -1808,7 +1808,7 @@ static int iavf_set_rxfh(struct net_device *netdev,static const struct ethtool_ops iavf_ethtool_ops = { .supported_coalesce_params =ETHTOOL_COALESCE_USECS |ETHTOOL_COALESCE_USE_ADAPTIVE , - .cap_rss_sym_xor_supported = true, + .supported_input_xfrm =RXH_XFRM_SYM_XOR , .get_drvinfo = iavf_get_drvinfo, .get_link = ethtool_op_get_link, .get_ringparam = iavf_get_ringparam,
drivers/net/ethernet/intel/ice/ice_ethtool.c +1 -1
@@ -4774,7 +4774,7 @@ static const struct ethtool_ops ice_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS |ETHTOOL_COALESCE_USE_ADAPTIVE | ETHTOOL_COALESCE_RX_USECS_HIGH, - .cap_rss_sym_xor_supported = true, + .supported_input_xfrm = RXH_XFRM_SYM_XOR, .rxfh_per_ctx_key = true, .get_link_ksettings = ice_get_link_ksettings, .set_link_ksettings = ice_set_link_ksettings,
include/linux/ethtool.h +2 -3
@@ -763,13 +763,12 @@ struct kernel_ethtool_ts_info {/** * struct ethtool_ops - optional netdev operations +* @supported_input_xfrm: supported types of input xfrm from %RXH_XFRM_*. * @cap_link_lanes_supported: indicates if the driver supports lanes * parameter. * @cap_rss_ctx_supported: indicates if the driver supports RSS * contexts via legacy API, drivers implementing @create_rxfh_context * do not have to set this bit. -* @cap_rss_sym_xor_supported: indicates if the driver supports symmetric-xor -* RSS. * @rxfh_per_ctx_key: device supports setting different RSS key for each * additional context. Netlink API should report hfunc, key, and input_xfrm * for every context, not just context 0.
@@ -995,9 +994,9 @@ struct kernel_ethtool_ts_info {* of the generic netdev features interface. */ struct ethtool_ops { +u32 supported_input_xfrm:8 ;u32 cap_link_lanes_supported:1 ;u32 cap_rss_ctx_supported:1 ; -u32 cap_rss_sym_xor_supported:1 ;u32 rxfh_per_ctx_key:1 ;u32 cap_rss_rxnfc_adds:1 ;u32 rxfh_indir_space;
include/uapi/linux/ethtool.h +4 -0
@@ -2269,6 +2269,10 @@ static inline int ethtool_validate_duplex(__u8 duplex)* be exploited to reduce the RSS queue spread. */ #define RXH_XFRM_SYM_XOR (1 << 0) +/* Similar to SYM_XOR, except that one copy of the XOR'ed fields is replaced by +* an OR of the same fields +*/ +#define RXH_XFRM_SYM_OR_XOR (1 << 1)#define RXH_XFRM_NO_CHANGE 0xff/* L2-L4 network traffic flow types */
net/ethtool/ioctl.c +4 -4
@@ -1005,11 +1005,11 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,if (rc)return rc; -/* Sanity check: if symmetric-xor is set, then: +/* Sanity check: if symmetric-xor/symmetric-or-xor is set, then: * 1 - no other fields besides IP src/dst and/or L4 src/dst * 2 - If src is set, dst must also be set */ - if ((rxfh.input_xfrm & RXH_XFRM_SYM_XOR) && + if ((rxfh.input_xfrm & (RXH_XFRM_SYM_XOR | RXH_XFRM_SYM_OR_XOR)) && ((info.data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)) || (!!(info.data & RXH_IP_SRC) ^ !!(info.data & RXH_IP_DST)) ||
@@ -1382,11 +1382,11 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,return -EOPNOTSUPP ;/* Check input data transformation capabilities */ if (rxfh.input_xfrm && rxfh.input_xfrm !=RXH_XFRM_SYM_XOR && + rxfh.input_xfrm !=RXH_XFRM_SYM_OR_XOR && rxfh.input_xfrm !=RXH_XFRM_NO_CHANGE )return -EINVAL ;if (rxfh.input_xfrm !=RXH_XFRM_NO_CHANGE && - (rxfh.input_xfrm &RXH_XFRM_SYM_XOR ) && - !ops->cap_rss_sym_xor_supported) + rxfh.input_xfrm & ~ops->supported_input_xfrm)return -EOPNOTSUPP ; create = rxfh.rss_context ==ETH_RXFH_CONTEXT_ALLOC ;
Signature · 1 line
2.40.1
PATCH v3 2/5 net/mlx5e: Symmetric OR-XOR RSS hash control
In reply to Gal PressmanAllow control over the symmetric RSS hash, which was previously set to enabled by default by the driver.
Symmetric OR-XOR RSS can now be queried and controlled using the 'ethtool -x/X' command.
--- .../net/ethernet/mellanox/mlx5/core/en/rss.c | 13 +++++++++++-- .../net/ethernet/mellanox/mlx5/core/en/rss.h | 4 ++-- .../net/ethernet/mellanox/mlx5/core/en/rx_res.c | 11 ++++++----- .../net/ethernet/mellanox/mlx5/core/en/rx_res.h | 5 +++-- .../net/ethernet/mellanox/mlx5/core/en/tir.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en/tir.h | 1 + .../ethernet/mellanox/mlx5/core/en_ethtool.c | 17 ++++++++++++++--- 7 files changed, 38 insertions(+), 15 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/rss.c +11 -2
@@ -156,6 +156,7 @@ static void mlx5e_rss_params_init(struct mlx5e_rss *rss) {enum mlx5_traffic_types tt; + rss->hash.symmetric = true; rss->hash.hfunc =ETH_RSS_HASH_TOP ;netdev_rss_key_fill (rss->hash.toeplitz_hash_key,sizeof (rss->hash.toeplitz_hash_key));
@@ -551,7 +552,7 @@ int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,return final_err; } -int mlx5e_rss_get_rxfh (struct mlx5e_rss *rss,u32 *indir,u8 *key,u8 *hfunc) +int mlx5e_rss_get_rxfh (struct mlx5e_rss *rss,u32 *indir,u8 *key,u8 *hfunc,bool *symmetric) {if (indir) memcpy(indir, rss->indir.table,
@@ -564,11 +565,14 @@ int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc)if (hfunc) *hfunc = rss->hash.hfunc; +if (symmetric) + *symmetric = rss->hash.symmetric; +return 0 ; }int mlx5e_rss_set_rxfh (struct mlx5e_rss *rss,const u32 *indir, -const u8 *key,const u8 *hfunc, +const u8 *key,const u8 *hfunc,const bool *symmetric,u32 *rqns,u32 *vhca_ids,unsigned int num_rqns) {bool changed_indir = false;
@@ -608,6 +612,11 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir, rss->indir.actual_table_size * sizeof(*rss->indir.table)); } +if (symmetric) { + rss->hash.symmetric = *symmetric; + changed_hash = true; + } +if (changed_indir && rss->enabled) { err =mlx5e_rss_apply (rss, rqns, vhca_ids, num_rqns);if (err) {
drivers/net/ethernet/mellanox/mlx5/core/en/rss.h +2 -2
@@ -44,9 +44,9 @@ void mlx5e_rss_disable(struct mlx5e_rss *rss);int mlx5e_rss_packet_merge_set_param (struct mlx5e_rss *rss,struct mlx5e_packet_merge_param *pkt_merge_param); -int mlx5e_rss_get_rxfh (struct mlx5e_rss *rss,u32 *indir,u8 *key,u8 *hfunc); +int mlx5e_rss_get_rxfh (struct mlx5e_rss *rss,u32 *indir,u8 *key,u8 *hfunc,bool *symmetric);int mlx5e_rss_set_rxfh (struct mlx5e_rss *rss,const u32 *indir, -const u8 *key,const u8 *hfunc, +const u8 *key,const u8 *hfunc,const bool *symmetric,u32 *rqns,u32 *vhca_ids,unsigned int num_rqns);struct mlx5e_rss_params_hash mlx5e_rss_get_hash (struct mlx5e_rss *rss);u8 mlx5e_rss_get_hash_fields (struct mlx5e_rss *rss,enum mlx5_traffic_types tt);
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c +6 -5
@@ -196,7 +196,7 @@ void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int n }int mlx5e_rx_res_rss_get_rxfh (struct mlx5e_rx_res *res,u32 rss_idx, -u32 *indir,u8 *key,u8 *hfunc) +u32 *indir,u8 *key,u8 *hfunc,bool *symmetric) {struct mlx5e_rss *rss;
@@ -207,11 +207,12 @@ int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,if (!rss)return -ENOENT ; -return mlx5e_rss_get_rxfh (rss, indir, key, hfunc); +return mlx5e_rss_get_rxfh (rss, indir, key, hfunc, symmetric); }int mlx5e_rx_res_rss_set_rxfh (struct mlx5e_rx_res *res,u32 rss_idx, -const u32 *indir,const u8 *key,const u8 *hfunc) +const u32 *indir,const u8 *key,const u8 *hfunc, +const bool *symmetric) {u32 *vhca_ids =get_vhca_ids (res,0 );struct mlx5e_rss *rss;
@@ -223,8 +224,8 @@ int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,if (!rss)return -ENOENT ; -return mlx5e_rss_set_rxfh (rss, indir, key, hfunc, res->rss_rqns, vhca_ids, - res->rss_nch); +return mlx5e_rss_set_rxfh (rss, indir, key, hfunc, symmetric, + res->rss_rqns, vhca_ids, res->rss_nch); } int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h +3 -2
@@ -44,9 +44,10 @@ void mlx5e_rx_res_xsk_update(struct mlx5e_rx_res *res, struct mlx5e_channels *ch/* Configuration API */ void mlx5e_rx_res_rss_set_indir_uniform (struct mlx5e_rx_res *res,unsigned int nch);int mlx5e_rx_res_rss_get_rxfh (struct mlx5e_rx_res *res,u32 rss_idx, -u32 *indir,u8 *key,u8 *hfunc); +u32 *indir,u8 *key,u8 *hfunc,bool *symmetric);int mlx5e_rx_res_rss_set_rxfh (struct mlx5e_rx_res *res,u32 rss_idx, -const u32 *indir,const u8 *key,const u8 *hfunc); +const u32 *indir,const u8 *key,const u8 *hfunc, +const bool *symmetric);int mlx5e_rx_res_rss_get_hash_fields (struct mlx5e_rx_res *res,u32 rss_idx,enum mlx5_traffic_types tt);
drivers/net/ethernet/mellanox/mlx5/core/en/tir.c +1 -1
@@ -124,7 +124,7 @@ void mlx5e_tir_builder_build_rss(struct mlx5e_tir_builder *builder,const size_t len =MLX5_FLD_SZ_BYTES (tirc, rx_hash_toeplitz_key);void *rss_key =MLX5_ADDR_OF (tirc, tirc, rx_hash_toeplitz_key); -MLX5_SET (tirc, tirc, rx_hash_symmetric,1 ); +MLX5_SET (tirc, tirc, rx_hash_symmetric, rss_hash->symmetric);memcpy (rss_key, rss_hash->toeplitz_hash_key, len); }
drivers/net/ethernet/mellanox/mlx5/core/en/tir.h +1 -0
@@ -9,6 +9,7 @@struct mlx5e_rss_params_hash {u8 hfunc;u8 toeplitz_hash_key[40 ]; +bool symmetric; };struct mlx5e_rss_params_traffic_type {
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +14 -3
@@ -1458,18 +1458,27 @@ static int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param * {struct mlx5e_priv *priv =netdev_priv (netdev);u32 rss_context = rxfh->rss_context; +bool symmetric;int err;mutex_lock (&priv->state_lock); err =mlx5e_rx_res_rss_get_rxfh (priv->rx_res, rss_context, - rxfh->indir, rxfh->key, &rxfh->hfunc); + rxfh->indir, rxfh->key, &rxfh->hfunc, &symmetric);mutex_unlock (&priv->state_lock); -return err; + +if (err) +return err; + +if (symmetric) + rxfh->input_xfrm =RXH_XFRM_SYM_OR_XOR ; + +return 0 ; }static int mlx5e_set_rxfh (struct net_device *dev,struct ethtool_rxfh_param *rxfh,struct netlink_ext_ack *extack) { +bool symmetric = rxfh->input_xfrm ==RXH_XFRM_SYM_OR_XOR ;struct mlx5e_priv *priv =netdev_priv (dev);u32 *rss_context = &rxfh->rss_context;u8 hfunc = rxfh->hfunc;
@@ -1504,7 +1513,8 @@ static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxf err =mlx5e_rx_res_rss_set_rxfh (priv->rx_res, *rss_context, rxfh->indir, rxfh->key, - hfunc ==ETH_RSS_HASH_NO_CHANGE ?NULL : &hfunc); + hfunc ==ETH_RSS_HASH_NO_CHANGE ?NULL : &hfunc, + rxfh->input_xfrm ==RXH_XFRM_NO_CHANGE ?NULL : &symmetric); unlock:mutex_unlock (&priv->state_lock);
@@ -2613,6 +2623,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {ETHTOOL_COALESCE_MAX_FRAMES |ETHTOOL_COALESCE_USE_ADAPTIVE | ETHTOOL_COALESCE_USE_CQE, + .supported_input_xfrm = RXH_XFRM_SYM_OR_XOR, .get_drvinfo = mlx5e_get_drvinfo, .get_link = ethtool_op_get_link, .get_link_ext_state = mlx5e_get_link_ext_state,
Signature · 1 line
2.40.1
PATCH v3 3/5 selftests: drv-net: Make rand_port() get a port more reliably
In reply to Gal PressmanInstead of guessing a port and checking whether it's available, get an available port from the OS.
--- tools/testing/selftests/net/lib/py/utils.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
tools/testing/selftests/net/lib/py/utils.py +4 -11
@@ -125,18 +125,11 @@ def ethtool(args, json=None, ns=None, host=None): def rand_port(): """ - Get a random unprivileged port, try to make sure it's not already used. + Get a random unprivileged port. """ - for _ in range(1000): - port = random.randint(10000, 65535) - try: - with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: - s.bind(("", port)) - return port - except OSError as e: - if e.errno != errno.EADDRINUSE: - raise - raise Exception("Can't find any free unprivileged port") + with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: + s.bind(("", 0)) + return s.getsockname()[1] def wait_port_listen(port, proto="tcp", ns=None, host=None, sleep=0.005, deadline=5):
Signature · 1 line
2.40.1
PATCH v3 4/5 selftests: drv-net: Introduce a function that checks whether a port is available on remote host
In reply to Gal PressmanAdd a function that checks whether a port is available on the remote host, this will be used downstream to verify that ports that were allocated locally are also available on the remote side.
--- tools/testing/selftests/net/lib/py/utils.py | 7 +++++++ 1 file changed, 7 insertions(+)
tools/testing/selftests/net/lib/py/utils.py +7 -0
@@ -123,6 +123,13 @@ def ethtool(args, json=None, ns=None, host=None): return tool('ethtool', args, json=json, ns=ns, host=host) +def check_port_available_remote(port, host): + """ + Check if a port is available on remote host. + Raise exception if not available. + """ + cmd(f"python3 -c 'import socket; s=socket.socket(socket.AF_INET6, socket.SOCK_STREAM); s.bind((\"\", {port}))'", host=host) + def rand_port(): """ Get a random unprivileged port.
Signature · 1 line
2.40.1
PATCH v3 5/5 selftests: drv-net-hw: Add a test for symmetric RSS hash
In reply to Gal PressmanAdd a selftest that verifies symmetric RSS hash is working as intended. The test runs two iterations of iperf3 traffic, swapping the src/dst TCP ports, and verifies that the same RX queue is receiving the traffic in both cases.
--- .../testing/selftests/drivers/net/hw/Makefile | 1 + .../drivers/net/hw/rss_input_xfrm.py | 77 +++++++++++++++++++ .../selftests/drivers/net/lib/py/load.py | 7 +- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py
tools/testing/selftests/drivers/net/hw/Makefile +1 -0
@@ -15,6 +15,7 @@ TEST_PROGS = \ nic_performance.py \ pp_alloc_fail.py \ rss_ctx.py \ + rss_input_xfrm.py \ # TEST_FILES := \
tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py new file +77 -0
77 lines not on this page · raw message
tools/testing/selftests/drivers/net/lib/py/load.py +5 -2
@@ -5,7 +5,7 @@ import time from lib.py import ksft_pr, cmd, ip, rand_port, wait_port_listen, bkg class GenerateTraffic: - def __init__(self, env, port=None): + def __init__(self, env, port=None, cport=None, parallel=16): env.require_cmd("iperf3", remote=True) self.env = env
@@ -15,7 +15,10 @@ class GenerateTraffic: self._iperf_server = cmd(f"iperf3 -s -1 -p {port}", background=True) wait_port_listen(port) time.sleep(0.1) - self._iperf_client = cmd(f"iperf3 -c {env.addr} -P 16 -p {port} -t 86400", + client_cmd = f"iperf3 -c {env.addr} -P {parallel} -p {port} -t 86400" + if cport and parallel == 1: + client_cmd = f"{client_cmd} --cport {cport}" + self._iperf_client = cmd(client_cmd, background=True, host=env.remote) # Wait for traffic to ramp up
Signature · 1 line
2.40.1
Jakub Kicinski
maintainerRe: [PATCH net-next v3 5/5] selftests: drv-net-hw: Add a test for symmetric RSS hash
Quoted 12 lines · On Sun, 16 Feb 2025 20:24:53 +0200 Gal Pressman wrote:
tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py new file +12
-0+ # Check for symmetric xor/or-xor + if input_xfrm and (input_xfrm == 1 or input_xfrm == 2): + port1 = _get_rand_port(cfg.remote) + port2 = _get_rand_port(cfg.remote) + ksft_pr(f'Running traffic on ports: {port1 = }, {port2 = }') + + cnts = _get_rx_cnts(cfg) + GenerateTraffic(cfg, port=port1, parallel=1, + cport=port2).wait_pkts_and_stop(20000) + cnts = _get_rx_cnts(cfg, prev=cnts) + rxq1 = _get_active_rx_queue(cnts) + ksft_pr(f'Received traffic on {rxq1 = }')
tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py line 61
Quoted 10 lines
tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py new file +10
-0+ + cnts = _get_rx_cnts(cfg) + GenerateTraffic(cfg, port=port2, parallel=1, + cport=port1).wait_pkts_and_stop(20000) + cnts = _get_rx_cnts(cfg, prev=cnts) + rxq2 = _get_active_rx_queue(cnts) + ksft_pr(f'Received traffic on {rxq2 = }') + + ksft_eq( + rxq1, rxq2, comment=f"Received traffic on different queues ({rxq1} != {rxq2}) while symmetric hash is configured")
Wouldn't it be both faster and less error prone to test this with UDP sockets?
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) sock.connect(cfg.remove_addr_v[ipver], remote_port) sock.recvmsg(100)
tgt = f"{ipver}:{cfg.addr_v[ipver]}:{local_port},sourceport={remote_port}" cmd("echo a | socat - UDP" + tgt, host=cfg.remote)
cpu = sock.getsockopt(socket.SOL_SOCKET, socket.SO_INCOMING_CPU)
Run this for 10 pairs for ports, make sure we hit at least 2 CPUs, and that the CPUs match for each pair.
Would be good to test both IPv4 and IPv6. I'm going to merge:
https://lore.kernel.org/all/[email protected]/
it should make writing the v4 + v6 test combos easier.
Signature · 1 line
pw-bot: cr
Re: [PATCH net-next v3 5/5] selftests: drv-net-hw: Add a test for symmetric RSS hash
Quoted 7 lines · Jakub Kicinski
Wouldn't it be both faster and less error prone to test this with UDP sockets?
sock =
socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)sock.connect(cfg.remove_addr_v[ipver], remote_port)sock.recvmsg(100)
Quoted 7 lines
tgt = f"{ipver}:{cfg.addr_v[ipver]}:{local_port},sourceport={remote_port}"
cmd("echo a | socat - UDP" + tgt, host=cfg.remote)cpu =
sock.getsockopt(socket.SOL_SOCKET, socket.SO_INCOMING_CPU)Run this for 10 pairs for ports, make sure we hit at least 2 CPUs, and that the CPUs match for each pair.
Thanks, I can do that.
Quoted 4 lines
Would be good to test both IPv4 and IPv6. I'm going to merge:
https://lore.kernel.org/all/[email protected]/
it should make writing the v4 + v6 test combos easier.
Should I wait for it to get merged?
Jakub Kicinski
maintainerRe: [PATCH net-next v3 5/5] selftests: drv-net-hw: Add a test for symmetric RSS hash
Quoted 5 lines · On Tue, 18 Feb 2025 22:26:25 +0200 Gal Pressman wrote:
Quoted 3 lines
Would be good to test both IPv4 and IPv6. I'm going to merge:
https://lore.kernel.org/all/[email protected]/
it should make writing the v4 + v6 test combos easier.Should I wait for it to get merged?
Yes, please, I remove the members you'd need to use to test both v4 and v6 so you patch will stop working once mine is merged. Stan reported a problem, I'll repost once again and hopefully the new version goes in tomorrow.