Skip to content

Commit

Permalink
ethdev: flatten RSS configuration in flow API
Browse files Browse the repository at this point in the history
Since its inception, the rte_flow RSS action has been relying in part on
external struct rte_eth_rss_conf for compatibility with the legacy RSS API.
This structure lacks parameters such as the hash algorithm to use, and more
recently, a method to tell which layer RSS should be performed on [1].

Given struct rte_eth_rss_conf will never be flexible enough to represent a
complete RSS configuration (e.g. RETA table), this patch supersedes it by
extending the rte_flow RSS action directly.

A subsequent patch will add a field to use a non-default RSS hash
algorithm. To that end, a field named "types" replaces the field formerly
known as "rss_hf" and standing for "RSS hash functions" as it was
confusing. Actual RSS hash function types are defined by enum
rte_eth_hash_function.

This patch updates all PMDs and example applications accordingly.

It breaks ABI compatibility for the following public functions:

- rte_flow_copy()
- rte_flow_create()
- rte_flow_query()
- rte_flow_validate()

[1] commit 676b605 ("doc: announce ethdev API change for RSS
    configuration")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
  • Loading branch information
am6 authored and Ferruh Yigit committed Apr 27, 2018
1 parent 19b3bc4 commit ac8d22d
Show file tree
Hide file tree
Showing 29 changed files with 492 additions and 358 deletions.
48 changes: 22 additions & 26 deletions app/test-pmd/cmdline_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,8 @@ enum index {
/** Storage for struct rte_flow_action_rss including external data. */
struct action_rss_data {
struct rte_flow_action_rss conf;
uint8_t key[RSS_HASH_KEY_LENGTH];
uint16_t queue[ACTION_RSS_QUEUE_NUM];
struct rte_eth_rss_conf rss_conf;
uint8_t rss_key[RSS_HASH_KEY_LENGTH];
};

/** Maximum number of subsequent tokens and arguments on the stack. */
Expand Down Expand Up @@ -1587,7 +1586,7 @@ static const struct token token_list[] = {
},
[ACTION_RSS_TYPES] = {
.name = "types",
.help = "RSS hash types",
.help = "specific RSS hash types",
.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)),
},
[ACTION_RSS_TYPE] = {
Expand All @@ -1602,21 +1601,21 @@ static const struct token token_list[] = {
.next = NEXT(action_rss, NEXT_ENTRY(STRING)),
.args = ARGS(ARGS_ENTRY_ARB(0, 0),
ARGS_ENTRY_ARB
(offsetof(struct action_rss_data, rss_conf) +
offsetof(struct rte_eth_rss_conf, rss_key_len),
sizeof(((struct rte_eth_rss_conf *)0)->
rss_key_len)),
ARGS_ENTRY(struct action_rss_data, rss_key)),
(offsetof(struct action_rss_data, conf) +
offsetof(struct rte_flow_action_rss, key_len),
sizeof(((struct rte_flow_action_rss *)0)->
key_len)),
ARGS_ENTRY(struct action_rss_data, key)),
},
[ACTION_RSS_KEY_LEN] = {
.name = "key_len",
.help = "RSS hash key length in bytes",
.next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)),
.args = ARGS(ARGS_ENTRY_ARB_BOUNDED
(offsetof(struct action_rss_data, rss_conf) +
offsetof(struct rte_eth_rss_conf, rss_key_len),
sizeof(((struct rte_eth_rss_conf *)0)->
rss_key_len),
(offsetof(struct action_rss_data, conf) +
offsetof(struct rte_flow_action_rss, key_len),
sizeof(((struct rte_flow_action_rss *)0)->
key_len),
0,
RSS_HASH_KEY_LENGTH)),
},
Expand Down Expand Up @@ -2075,27 +2074,24 @@ parse_vc_action_rss(struct context *ctx, const struct token *token,
action_rss_data = ctx->object;
*action_rss_data = (struct action_rss_data){
.conf = (struct rte_flow_action_rss){
.rss_conf = &action_rss_data->rss_conf,
.num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
.types = rss_hf,
.key_len = sizeof(action_rss_data->key),
.queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM),
.key = action_rss_data->key,
.queue = action_rss_data->queue,
},
.key = "testpmd's default RSS hash key",
.queue = { 0 },
.rss_conf = (struct rte_eth_rss_conf){
.rss_key = action_rss_data->rss_key,
.rss_key_len = sizeof(action_rss_data->rss_key),
.rss_hf = rss_hf,
},
.rss_key = "testpmd's default RSS hash key",
};
for (i = 0; i < action_rss_data->conf.num; ++i)
for (i = 0; i < action_rss_data->conf.queue_num; ++i)
action_rss_data->queue[i] = i;
if (!port_id_is_invalid(ctx->port, DISABLED_WARN) &&
ctx->port != (portid_t)RTE_PORT_ALL) {
struct rte_eth_dev_info info;

rte_eth_dev_info_get(ctx->port, &info);
action_rss_data->rss_conf.rss_key_len =
RTE_MIN(sizeof(action_rss_data->rss_key),
action_rss_data->conf.key_len =
RTE_MIN(sizeof(action_rss_data->key),
info.hash_key_size);
}
action->conf = &action_rss_data->conf;
Expand Down Expand Up @@ -2123,7 +2119,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
return -1;
if (!(ctx->objdata >> 16) && ctx->object) {
action_rss_data = ctx->object;
action_rss_data->rss_conf.rss_hf = 0;
action_rss_data->conf.types = 0;
}
if (!strcmp_partial("end", str, len)) {
ctx->objdata &= 0xffff;
Expand All @@ -2142,7 +2138,7 @@ parse_vc_action_rss_type(struct context *ctx, const struct token *token,
if (!ctx->object)
return len;
action_rss_data = ctx->object;
action_rss_data->rss_conf.rss_hf |= rss_type_table[i].rss_type;
action_rss_data->conf.types |= rss_type_table[i].rss_type;
return len;
}

Expand Down Expand Up @@ -2192,7 +2188,7 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
if (!ctx->object)
return len;
action_rss_data = ctx->object;
action_rss_data->conf.num = i;
action_rss_data->conf.queue_num = i;
action_rss_data->conf.queue = i ? action_rss_data->queue : NULL;
return len;
}
Expand Down
39 changes: 13 additions & 26 deletions app/test-pmd/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,40 +1117,27 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action)
off = 0;
if (dst.rss)
*dst.rss = (struct rte_flow_action_rss){
.num = src.rss->num,
.types = src.rss->types,
.key_len = src.rss->key_len,
.queue_num = src.rss->queue_num,
};
off += sizeof(*src.rss);
if (src.rss->num) {
if (src.rss->key_len) {
off = RTE_ALIGN_CEIL(off, sizeof(double));
size = sizeof(*src.rss->queue) * src.rss->num;
size = sizeof(*src.rss->key) * src.rss->key_len;
if (dst.rss)
dst.rss->queue = memcpy
dst.rss->key = memcpy
((void *)((uintptr_t)dst.rss + off),
src.rss->queue, size);
src.rss->key, size);
off += size;
}
off = RTE_ALIGN_CEIL(off, sizeof(double));
if (dst.rss) {
dst.rss->rss_conf = (void *)((uintptr_t)dst.rss + off);
*(struct rte_eth_rss_conf *)(uintptr_t)
dst.rss->rss_conf = (struct rte_eth_rss_conf){
.rss_key_len = src.rss->rss_conf->rss_key_len,
.rss_hf = src.rss->rss_conf->rss_hf,
};
}
off += sizeof(*src.rss->rss_conf);
if (src.rss->rss_conf->rss_key_len) {
if (src.rss->queue_num) {
off = RTE_ALIGN_CEIL(off, sizeof(double));
size = sizeof(*src.rss->rss_conf->rss_key) *
src.rss->rss_conf->rss_key_len;
if (dst.rss) {
((struct rte_eth_rss_conf *)(uintptr_t)
dst.rss->rss_conf)->rss_key =
(void *)((uintptr_t)dst.rss + off);
memcpy(dst.rss->rss_conf->rss_key,
src.rss->rss_conf->rss_key,
size);
}
size = sizeof(*src.rss->queue) * src.rss->queue_num;
if (dst.rss)
dst.rss->queue = memcpy
((void *)((uintptr_t)dst.rss + off),
src.rss->queue, size);
off += size;
}
size = off;
Expand Down
28 changes: 19 additions & 9 deletions doc/guides/prog_guide/rte_flow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,12 @@ Action: ``RSS``
Similar to QUEUE, except RSS is additionally performed on packets to spread
them among several queues according to the provided parameters.

Unlike global RSS settings used by other DPDK APIs, unsetting the ``types``
field does not disable RSS in a flow rule. Doing so instead requests safe
unspecified "best-effort" settings from the underlying PMD, which depending
on the flow rule, may result in anything ranging from empty (single queue)
to all-inclusive RSS.

Note: RSS hash result is stored in the ``hash.rss`` mbuf field which
overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi``
field only, both can be requested simultaneously.
Expand All @@ -1309,15 +1315,19 @@ field only, both can be requested simultaneously.

.. table:: RSS

+--------------+--------------------------------+
| Field | Value |
+==============+================================+
| ``rss_conf`` | RSS parameters |
+--------------+--------------------------------+
| ``num`` | number of entries in ``queue`` |
+--------------+--------------------------------+
| ``queue`` | queue indices to use |
+--------------+--------------------------------+
+---------------+---------------------------------------------+
| Field | Value |
+===============+=============================================+
| ``types`` | specific RSS hash types (see ``ETH_RSS_*``) |
+---------------+---------------------------------------------+
| ``key_len`` | hash key length in bytes |
+---------------+---------------------------------------------+
| ``queue_num`` | number of entries in ``queue`` |
+---------------+---------------------------------------------+
| ``key`` | hash key |
+---------------+---------------------------------------------+
| ``queue`` | queue indices to use |
+---------------+---------------------------------------------+

Action: ``PF``
^^^^^^^^^^^^^^
Expand Down
13 changes: 10 additions & 3 deletions doc/guides/rel_notes/release_18_05.rst
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ API Changes
present.
* C99-style flexible arrays were replaced with standard pointers in RSS
action and in RAW pattern item structures due to compatibility issues.
* The RSS action was modified to not rely on external
``struct rte_eth_rss_conf`` anymore to instead expose its own and more
appropriately named configuration fields directly
(``rss_conf->rss_key`` => ``key``,
``rss_conf->rss_key_len`` => ``key_len``,
``rss_conf->rss_hf`` => ``types``,
``num`` => ``queue_num``).


ABI Changes
Expand Down Expand Up @@ -317,9 +324,9 @@ ABI Changes
``rte_flow_isolate``, ``rte_flow_query`` and ``rte_flow_validate``, due to
changes in error type definitions (``enum rte_flow_error_type``), removal
of the unused DUP action (``enum rte_flow_action_type``), modified
behavior for flow rule actions (see API changes) and removal of C99
flexible arrays from RSS action (``struct rte_flow_action_rss``) and RAW
pattern item (``struct rte_flow_item_raw``).
behavior for flow rule actions (see API changes), removal of C99 flexible
array from RAW pattern item (``struct rte_flow_item_raw``) and complete
rework of the RSS action definition (``struct rte_flow_action_rss``).


Removed Items
Expand Down
6 changes: 4 additions & 2 deletions doc/guides/testpmd_app_ug/testpmd_funcs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3422,8 +3422,10 @@ This section lists supported actions and their attributes, if any.

- ``rss``: spread packets among several queues.

- ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens
are the same as `set_hash_input_set`_, an empty list means none (0).
- ``types [{RSS hash type} [...]] end``: specific RSS hash types, allowed
tokens are the same as `set_hash_input_set`_, except that an empty list
does not disable RSS but instead requests unspecified "best-effort"
settings.

- ``key {string}``: RSS hash key, overrides ``key_len``.

Expand Down
13 changes: 11 additions & 2 deletions drivers/net/e1000/e1000_ethdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

#ifndef _E1000_ETHDEV_H_
#define _E1000_ETHDEV_H_

#include <stdint.h>

#include <rte_flow.h>
#include <rte_time.h>
#include <rte_pci.h>

Expand All @@ -27,6 +31,7 @@
#define E1000_CTRL_EXT_EXTEND_VLAN (1<<26) /* EXTENDED VLAN */
#define IGB_VFTA_SIZE 128

#define IGB_HKEY_MAX_INDEX 10
#define IGB_MAX_RX_QUEUE_NUM 8
#define IGB_MAX_RX_QUEUE_NUM_82576 16

Expand Down Expand Up @@ -229,8 +234,8 @@ struct igb_ethertype_filter {
};

struct igb_rte_flow_rss_conf {
struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */
uint16_t num; /**< Number of entries in queue[]. */
struct rte_flow_action_rss conf; /**< RSS parameters. */
uint8_t key[IGB_HKEY_MAX_INDEX * sizeof(uint32_t)]; /* Hash key. */
uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices to use. */
};

Expand Down Expand Up @@ -501,6 +506,10 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev,
int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
struct rte_eth_flex_filter *filter,
bool add);
int igb_rss_conf_init(struct igb_rte_flow_rss_conf *out,
const struct rte_flow_action_rss *in);
int igb_action_rss_same(const struct rte_flow_action_rss *comp,
const struct rte_flow_action_rss *with);
int igb_config_rss_filter(struct rte_eth_dev *dev,
struct igb_rte_flow_rss_conf *conf,
bool add);
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/e1000/igb_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
#define IGB_DEFAULT_TX_HTHRESH 1
#define IGB_DEFAULT_TX_WTHRESH ((hw->mac.type == e1000_82576) ? 1 : 16)

#define IGB_HKEY_MAX_INDEX 10

/* Bit shift and mask */
#define IGB_4_BIT_WIDTH (CHAR_BIT / 2)
#define IGB_4_BIT_MASK RTE_LEN2MASK(IGB_4_BIT_WIDTH, uint8_t)
Expand Down Expand Up @@ -5662,7 +5660,7 @@ igb_rss_filter_restore(struct rte_eth_dev *dev)
struct e1000_filter_info *filter_info =
E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);

if (filter_info->rss_info.num)
if (filter_info->rss_info.conf.queue_num)
igb_config_rss_filter(dev, &filter_info->rss_info, TRUE);
}

Expand Down
31 changes: 17 additions & 14 deletions drivers/net/e1000/igb_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1292,15 +1292,15 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,

rss = (const struct rte_flow_action_rss *)act->conf;

if (!rss || !rss->num) {
if (!rss || !rss->queue_num) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
act,
"no valid queues");
return -rte_errno;
}

for (n = 0; n < rss->num; n++) {
for (n = 0; n < rss->queue_num; n++) {
if (rss->queue[n] >= dev->data->nb_rx_queues) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
Expand All @@ -1310,14 +1310,18 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
}
}

if (rss->rss_conf)
rss_conf->rss_conf = *rss->rss_conf;
else
rss_conf->rss_conf.rss_hf = IGB_RSS_OFFLOAD_ALL;

for (n = 0; n < rss->num; ++n)
rss_conf->queue[n] = rss->queue[n];
rss_conf->num = rss->num;
if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key))
return rte_flow_error_set
(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
"RSS hash key must be exactly 40 bytes");
if (rss->queue_num > RTE_DIM(rss_conf->queue))
return rte_flow_error_set
(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act,
"too many queues for RSS context");
if (igb_rss_conf_init(rss_conf, rss))
return rte_flow_error_set
(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, act,
"RSS context initialization failure");

/* check if the next not void item is END */
index++;
Expand Down Expand Up @@ -1518,9 +1522,8 @@ igb_flow_create(struct rte_eth_dev *dev,
PMD_DRV_LOG(ERR, "failed to allocate memory");
goto out;
}
rte_memcpy(&rss_filter_ptr->filter_info,
&rss_conf,
sizeof(struct igb_rte_flow_rss_conf));
igb_rss_conf_init(&rss_filter_ptr->filter_info,
&rss_conf.conf);
TAILQ_INSERT_TAIL(&igb_filter_rss_list,
rss_filter_ptr, entries);
flow->rule = rss_filter_ptr;
Expand Down Expand Up @@ -1757,7 +1760,7 @@ igb_clear_rss_filter(struct rte_eth_dev *dev)
struct e1000_filter_info *filter =
E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);

if (filter->rss_info.num)
if (filter->rss_info.conf.queue_num)
igb_config_rss_filter(dev, &filter->rss_info, FALSE);
}

Expand Down
Loading

0 comments on commit ac8d22d

Please sign in to comment.