On Tue, Sep 08, 2026 at 11:58:57PM +0800, Zhang Tengfei wrote:
> Flow Director table memory is taken from the Rx packet buffer according
> to fdir_conf.pballoc. After the legacy rte_eth_conf.fdir_conf API was
> removed, pballoc stayed at the zero-initialized 64K default.
> 
> Parse fdir_pballoc=<64k|128k|256k> at probe time so applications that
> need a larger table can opt in. The default remains 64K.
> 
> Signed-off-by: Zhang Tengfei <[email protected]>
> ---

Using a devarg seems reasonable enough for this.

>  doc/guides/nics/ixgbe.rst              | 26 ++++++++++++
>  doc/guides/rel_notes/release_26_11.rst |  5 +++
>  drivers/net/intel/ixgbe/ixgbe_ethdev.c | 56 ++++++++++++++++++++++----
>  3 files changed, 80 insertions(+), 7 deletions(-)
> 
> diff --git a/doc/guides/nics/ixgbe.rst b/doc/guides/nics/ixgbe.rst
> index f075ef6f6f..18b685f441 100644
> --- a/doc/guides/nics/ixgbe.rst
> +++ b/doc/guides/nics/ixgbe.rst
> @@ -164,6 +164,32 @@ be passed as part of EAL arguments. For example,
>    This option informs the driver that in this case, SDP3 is not to be
>    used as a check for link up by testing for laser on/off.
>  
> +PF Runtime Options
> +^^^^^^^^^^^^^^^^^^
> +
> +The following ``devargs`` option can be enabled at probe time.
> +It must be passed as part of EAL arguments. For example,
> +
> +.. code-block:: console
> +
> +   dpdk-testpmd -a 81:00.0,fdir_pballoc=256k -- -i

We aren't particularly limited in the length of devargs names. Therefore, I
think a bit less cryptic name for the parameter might be better. How about
"fdir_buffer_size", for example.

> +
> +- ``fdir_pballoc`` (default **64k**)
> +
> +  Memory allocated from the Rx packet buffer for Flow Director filters.
> +  Valid values are ``64k``, ``128k`` and ``256k``.
> +
> +  Larger values increase the number of hardware filter entries
> +  (perfect mode: 2K / 4K / 8K; signature mode: 8K / 16K / 32K)
> +  and reduce Rx packet buffer space by the same amount.
> +  On 82599 the Rx packet buffer is 512KB, so ``256k`` takes half of it.
> +
> +  This value is read only at probe time. Changing it requires restarting
> +  the process with a new EAL argument.
> +
> +  Using Flow Director together with DCB is not supported:
> +  Flow Director rewrites Rx packet buffer sizing after DCB configuration.
> +

This last two lines might be better highlighted as an explicit note. Is
this limitation enforced in the code?

>  VF Runtime Options
>  ^^^^^^^^^^^^^^^^^^
>  
> diff --git a/doc/guides/rel_notes/release_26_11.rst 
> b/doc/guides/rel_notes/release_26_11.rst
> index 87c7e81bde..ba3669b9da 100644
> --- a/doc/guides/rel_notes/release_26_11.rst
> +++ b/doc/guides/rel_notes/release_26_11.rst
> @@ -55,6 +55,11 @@ New Features
>       Also, make sure to start the actual text at the margin.
>       =======================================================
>  
> +* **Updated Intel ixgbe driver.**
> +
> +  Added ``fdir_pballoc`` devarg to select the Flow Director table size
> +  (``64k``, ``128k`` or ``256k``) at probe time. The default remains ``64k``.
> +
>  
>  Removed Items
>  -------------
> diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c 
> b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> index c5010f623c..fef596460c 100644
> --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> @@ -128,9 +128,11 @@
>  #define IXGBE_DMATXCTL_VT_MASK                 0xFFFF0000
>  
>  #define IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE       
> "fiber_sdp3_no_tx_disable"
> +#define IXGBE_DEVARG_FDIR_PBALLOC            "fdir_pballoc"
>  
>  static const char * const ixgbe_valid_arguments[] = {
>       IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE,
> +     IXGBE_DEVARG_FDIR_PBALLOC,
>       NULL
>  };
>  
> @@ -1054,19 +1056,45 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
>       ixgbe_release_swfw_semaphore(hw, mask);
>  }
>  
> -static void
> +static int
> +devarg_handle_fdir_pballoc(const char *key, const char *value, void 
> *extra_args)
> +{
> +     enum rte_eth_fdir_pballoc_type *pballoc = extra_args;
> +
> +     if (value == NULL || extra_args == NULL)
> +             return -EINVAL;
> +
> +     if (strcmp(value, "64k") == 0)
> +             *pballoc = RTE_ETH_FDIR_PBALLOC_64K;
> +     else if (strcmp(value, "128k") == 0)
> +             *pballoc = RTE_ETH_FDIR_PBALLOC_128K;
> +     else if (strcmp(value, "256k") == 0)
> +             *pballoc = RTE_ETH_FDIR_PBALLOC_256K;
> +     else {
> +             PMD_INIT_LOG(ERR,
> +                          "invalid %s='%s', use 64k, 128k or 256k",
> +                          key, value);

Don't think this needs wrapping, should fit on one line.

> +             return -EINVAL;
> +     }
> +
> +     return 0;
> +}
> +
> +static int
>  ixgbe_parse_devargs(struct ixgbe_adapter *adapter,
> -                   struct rte_devargs *devargs)
> +                 struct rte_devargs *devargs)

Nit: you don't need to edit the whitespace indent here.

>  {
>       struct rte_kvargs *kvlist;
>       uint16_t sdp3_no_tx_disable;
> +     enum rte_eth_fdir_pballoc_type pballoc;
> +     int ret = 0;
>  
>       if (devargs == NULL)
> -             return;
> +             return 0;
>  
>       kvlist = rte_kvargs_parse(devargs->args, ixgbe_valid_arguments);
>       if (kvlist == NULL)
> -             return;
> +             return 0;
>  
>       if (rte_kvargs_count(kvlist, IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE) == 
> 1 &&
>           rte_kvargs_process(kvlist, IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE,
> @@ -1074,7 +1102,17 @@ ixgbe_parse_devargs(struct ixgbe_adapter *adapter,
>           sdp3_no_tx_disable == 1)
>               adapter->sdp3_no_tx_disable = 1;
>  
> +     if (rte_kvargs_count(kvlist, IXGBE_DEVARG_FDIR_PBALLOC) != 0) {
> +             if (rte_kvargs_process(kvlist, IXGBE_DEVARG_FDIR_PBALLOC,
> +                                    devarg_handle_fdir_pballoc,
> +                                    &pballoc) != 0)
> +                     ret = -EINVAL;
> +             else
> +                     adapter->fdir_conf.pballoc = pballoc;
> +     }
> +
>       rte_kvargs_free(kvlist);
> +     return ret;
>  }
>  
>  /*
> @@ -1141,8 +1179,11 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void 
> *init_params __rte_unused)
>  
>       /* NOTE: review for potential ordering optimization */
>       rte_atomic_store_explicit(&ad->link_thread_running, 0, 
> rte_memory_order_seq_cst);
> -     ixgbe_parse_devargs(eth_dev->data->dev_private,
> -                         pci_dev->device.devargs);
> +     ret = ixgbe_parse_devargs(eth_dev->data->dev_private,
> +                               pci_dev->device.devargs);
> +     if (ret != 0)
> +             return ret;
> +
>       rte_eth_copy_pci_info(eth_dev, pci_dev);
>       eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
>  
> @@ -8665,7 +8706,8 @@ RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd);
>  RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map);
>  RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | 
> vfio-pci");
>  RTE_PMD_REGISTER_PARAM_STRING(net_ixgbe,
> -                           IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE "=<0|1>");
> +                           IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE "=<0|1>"
> +                           IXGBE_DEVARG_FDIR_PBALLOC "=<64k|128k|256k>");
>  RTE_PMD_REGISTER_PCI(net_ixgbe_vf, rte_ixgbevf_pmd);
>  RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe_vf, pci_id_ixgbevf_map);
>  RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe_vf, "* igb_uio | vfio-pci");
> -- 

Overall, looks reasonable, but I think it would be good to have the DCB
limitation enforced in the code, rather than just putting it in the docs.

/Bruce

Reply via email to