Hi Hemant, Do you have any preference between the different approaches proposed below?
Regards, Maxime Leroy On Tue, Jun 30, 2026 at 2:39 PM Maxime Leroy <[email protected]> wrote: > > When RTE_ETH_RSS_LEVEL_INNERMOST is requested, the IP key extracts use > the innermost header index (HDR_INDEX_LAST). The hardware only resolves > that index when several IP headers are stacked: for a non-tunnelled > frame, which carries a single IP header, the extraction returns nothing. > The RSS hash is then constant and all such frames are steered to a > single Rx queue. > > Always also extract the outer IP (header index 0), which the hardware > resolves for any frame. Non-tunnelled frames are thus hashed on their > only IP header, while tunnelled frames keep being hashed on their inner > IP. > > This is a deliberate tradeoff: the ethdev API defines > RTE_ETH_RSS_LEVEL_INNERMOST as hashing the innermost header only, but the > hardware cannot do that without breaking RSS for plain traffic. As a > consequence, two tunnelled flows with the same inner header but > different outer IPs may hash to different queues. This limitation is > documented in the dpaa2 guide. > > Alternatives considered (feedback welcome, hence RFC): > > - Hash both outer and inner only under RTE_ETH_RSS_LEVEL_PMD_DEFAULT and > keep INNERMOST strictly inner-only. The ethdev API leaves the default > level to the PMD, so this stays API-compliant; it changes the default > hash for tunnelled traffic. > > - Add a generic RTE_ETH_RSS_LEVEL_OUTER_INNER value to the ethdev API so > applications can request hashing on both encapsulation levels > explicitly, instead of overloading INNERMOST. This needs an ethdev API > change and agreement from other PMDs. > > Fixes: 32f701671d2f ("net/dpaa2: support inner RSS level for tunnelled > traffic") > Signed-off-by: Maxime Leroy <[email protected]> > --- > doc/guides/nics/dpaa2.rst | 6 +++ > drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 64 +++++++++++--------------- > 2 files changed, 33 insertions(+), 37 deletions(-) > > diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst > index 2d70bd0ab9..b7b68f0cd5 100644 > --- a/doc/guides/nics/dpaa2.rst > +++ b/doc/guides/nics/dpaa2.rst > @@ -558,6 +558,12 @@ Other Limitations > > - RSS hash key cannot be modified. > - RSS RETA cannot be configured. > +- Under ``RTE_ETH_RSS_LEVEL_INNERMOST``, the IP hash also covers the > + outermost IP, not only the innermost one. The hardware extracts no IP > + at the innermost index for non-tunnelled frames, so the outer IP is > + added to keep RSS working on plain traffic. As a result, tunnelled > + flows with the same inner header but different outer IPs may be > + distributed to different queues. > > .. _dptmapi: > > diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c > b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c > index 07f4a3d414..b002dba171 100644 > --- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c > +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c > @@ -398,48 +398,38 @@ dpaa2_distset_to_dpkg_profile_cfg( > case RTE_ETH_RSS_IPV6: > case RTE_ETH_RSS_FRAG_IPV6: > case RTE_ETH_RSS_NONFRAG_IPV6_OTHER: > - case RTE_ETH_RSS_IPV6_EX: > + case RTE_ETH_RSS_IPV6_EX: { > + static const uint32_t ip_fields[] = { > + NH_FLD_IP_SRC, NH_FLD_IP_DST, > + NH_FLD_IP_PROTO }; > + static const uint8_t ip_hdr_index[] = { > + 0, DPAA2_DIST_HDR_INDEX_LAST }; > + unsigned int n_hdr, f, h; > > if (l3_configured) > break; > l3_configured = 1; > > - kg_cfg->extracts[i].extract.from_hdr.prot = > - NET_PROT_IP; > - > kg_cfg->extracts[i].extract.from_hdr.hdr_index = > - hdr_index; > - kg_cfg->extracts[i].extract.from_hdr.field = > - NH_FLD_IP_SRC; > - kg_cfg->extracts[i].type = > - DPKG_EXTRACT_FROM_HDR; > - kg_cfg->extracts[i].extract.from_hdr.type = > - DPKG_FULL_FIELD; > - i++; > - > - kg_cfg->extracts[i].extract.from_hdr.prot = > - NET_PROT_IP; > - > kg_cfg->extracts[i].extract.from_hdr.hdr_index = > - hdr_index; > - kg_cfg->extracts[i].extract.from_hdr.field = > - NH_FLD_IP_DST; > - kg_cfg->extracts[i].type = > - DPKG_EXTRACT_FROM_HDR; > - kg_cfg->extracts[i].extract.from_hdr.type = > - DPKG_FULL_FIELD; > - i++; > - > - kg_cfg->extracts[i].extract.from_hdr.prot = > - NET_PROT_IP; > - > kg_cfg->extracts[i].extract.from_hdr.hdr_index = > - hdr_index; > - kg_cfg->extracts[i].extract.from_hdr.field = > - NH_FLD_IP_PROTO; > - kg_cfg->extracts[i].type = > - DPKG_EXTRACT_FROM_HDR; > - kg_cfg->extracts[i].extract.from_hdr.type = > - DPKG_FULL_FIELD; > - i++; > - break; > + /* outer IP always; inner IP too for > INNERMOST */ > + n_hdr = (hdr_index == > DPAA2_DIST_HDR_INDEX_LAST) ? > + 2 : 1; > + > + for (h = 0; h < n_hdr; h++) > + for (f = 0; f < RTE_DIM(ip_fields); > f++) { > + > kg_cfg->extracts[i].extract.from_hdr.prot = > + NET_PROT_IP; > + > kg_cfg->extracts[i].extract.from_hdr.hdr_index = > + ip_hdr_index[h]; > + > kg_cfg->extracts[i].extract.from_hdr.field = > + ip_fields[f]; > + kg_cfg->extracts[i].type = > + DPKG_EXTRACT_FROM_HDR; > + > kg_cfg->extracts[i].extract.from_hdr.type = > + DPKG_FULL_FIELD; > + i++; > + } > + break; > + } > > case RTE_ETH_RSS_NONFRAG_IPV4_TCP: > case RTE_ETH_RSS_NONFRAG_IPV6_TCP: > -- > 2.43.0 > -- ------------------------------- Maxime Leroy [email protected]

