On Fri, Dec 19, 2025 at 6:50 PM <[email protected]> wrote:
>
> From: Numan Siddique <[email protected]>
>
> netdev-offload-tc when offloading a flow to tc, uses the flow's
> recirc_id as flower chain id.  recirc_id is of type 'uint32_t'.
> Kernel tc reserves the upper nibble (4 bits) of the tc flower's
> chain index for extended action opcode [1].  If a flow's recirc_id
> value is greater than 268,435,455 (2^28), kernel returns
> EINVAL when ovs-vswitchd tries to offload the flow.
>
> This commit fixes this offload issue by setting the maximum
> value of recirc id to 2^28. 2^28 is a fairly big number and
> we should not have that many active datapath flows at a time.
>
> Reported-at: 
> https://mail.openvswitch.org/pipermail/ovs-dev/2025-November/427485.html
> Suggested-by: Ilya Maximets <[email protected]>
> Suggested-by: Eelco Chaudron <[email protected]>
> Signed-off-by: Numan Siddique <[email protected]>

Recheck-request: cirrus-robot


> ---
>  ofproto/ofproto-dpif-rid.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-rid.c b/ofproto/ofproto-dpif-rid.c
> index f01468025..09f8a84f1 100644
> --- a/ofproto/ofproto-dpif-rid.c
> +++ b/ofproto/ofproto-dpif-rid.c
> @@ -38,6 +38,13 @@ static uint32_t next_id OVS_GUARDED_BY(mutex) = 1; /* 
> Possible next free id. */
>
>  #define RECIRC_POOL_STATIC_IDS 1024
>
> +/* Limit the recirc_ic maximum value to 268435455 (which is 2^^28).
> + * When kernel tc offload is enabled, we use the recirc_id as
> + * the chain id and kernel limits the chain id maximum value
> + * to 2^^28.
> + */
> +#define RECIRC_ID_MAX_VALUE 268435455
> +
>  static void recirc_id_node_free(struct recirc_id_node *);
>
>  /* This should be called by the revalidator once at each round (every 500ms 
> or
> @@ -227,8 +234,8 @@ frozen_state_free(struct frozen_state *state)
>  }
>
>  /* Allocate a unique recirculation id for the given set of flow metadata.
> - * The ID space is 2^^32, so there should never be a situation in which all
> - * the IDs are used up.  We loop until we find a free one. */
> + * The ID space is limited to 2^^28, so there should never be a situation
> + * in which all the IDs are used up.  We loop until we find a free one. */
>  static struct recirc_id_node *
>  recirc_alloc_id__(const struct frozen_state *state, uint32_t hash)
>  {
> @@ -247,7 +254,7 @@ recirc_alloc_id__(const struct frozen_state *state, 
> uint32_t hash)
>             RECIRC_POOL_STATIC_IDS IDs on the later rounds, though, as some of
>             the initial allocations may be for long term uses (like bonds). */
>          node->id = next_id++;
> -        if (OVS_UNLIKELY(!node->id)) {
> +        if (OVS_UNLIKELY(!node->id || node->id > RECIRC_ID_MAX_VALUE)) {
>              next_id = RECIRC_POOL_STATIC_IDS + 1;
>              node->id = next_id++;
>          }
> --
> 2.52.0
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to