[PATCH v2] net/iavf: support pre and post reset callbacks
Bruce Richardson
bruce.richardson at intel.com
Tue Jan 20 19:01:39 CET 2026
On Wed, Jan 14, 2026 at 01:21:59PM +0000, Ciara Loftus wrote:
> The user may want to perform some actions before and/or after a VF
> reset, for example storing settings that may be lost during the reset
> and restoring them after the reset. To facilitate this, introduce two
> new functions which allow the user to register either a pre or post
> reset callback, which will be executed before or after the VF has been
> reset. To unregister the callback, simply use the register functions
> with a NULL callback and argument.
>
> Signed-off-by: Ciara Loftus <ciara.loftus at intel.com>
> ---
> v2:
> * Changed the function parameters of each cb
> * Created separate register functions for each type of cb
> * Use typedefs for the callbacks
> * Fixed some style issues
> * Permit NULL cb args when registering, application may just want to be
> notified of the event and not require further processing.
> ---
> doc/guides/rel_notes/release_26_03.rst | 4 ++
> drivers/net/intel/iavf/iavf.h | 8 +++
> drivers/net/intel/iavf/iavf_ethdev.c | 80 ++++++++++++++++++++++++++
> drivers/net/intel/iavf/rte_pmd_iavf.h | 42 ++++++++++++++
> 4 files changed, 134 insertions(+)
>
> diff --git a/doc/guides/rel_notes/release_26_03.rst b/doc/guides/rel_notes/release_26_03.rst
> index 15dabee7a1..770f9933ee 100644
> --- a/doc/guides/rel_notes/release_26_03.rst
> +++ b/doc/guides/rel_notes/release_26_03.rst
> @@ -55,6 +55,10 @@ New Features
> Also, make sure to start the actual text at the margin.
> =======================================================
>
> +* **Updated Intel iavf driver.**
> +
> + * Added support for pre and post VF reset callbacks.
> +
>
> Removed Items
> -------------
> diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
> index d78582e05c..50ca14e41c 100644
> --- a/drivers/net/intel/iavf/iavf.h
> +++ b/drivers/net/intel/iavf/iavf.h
> @@ -100,6 +100,10 @@ struct iavf_adapter;
> struct ci_rx_queue;
> struct ci_tx_queue;
>
> +/** Callback function pointer for pre VF reset event */
> +typedef void (*iavf_pre_reset_cb_t)(uint16_t port_id, void *arg);
> +/** Callback function pointer for post VF reset event */
> +typedef void (*iavf_post_reset_cb_t)(uint16_t port_id, int reset_state, void *arg);
>
> struct iavf_ipsec_crypto_stats {
> uint64_t icount;
> @@ -257,6 +261,10 @@ struct iavf_info {
>
> struct iavf_vsi vsi;
> bool vf_reset; /* true for VF reset pending, false for no VF reset */
> + iavf_pre_reset_cb_t pre_reset_cb; /* Pre reset callback function ptr */
> + iavf_post_reset_cb_t post_reset_cb; /* Post reset callback function ptr */
> + void *pre_reset_cb_arg; /* Pre reset callback argument */
> + void *post_reset_cb_arg; /* Post reset callback argument */
> uint64_t flags;
>
> uint8_t *rss_lut;
> diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
> index 15e49fe248..83e3486572 100644
> --- a/drivers/net/intel/iavf/iavf_ethdev.c
> +++ b/drivers/net/intel/iavf/iavf_ethdev.c
> @@ -3120,6 +3120,10 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev, bool vf_initiated_reset)
> vf->in_reset_recovery = true;
> iavf_set_no_poll(adapter, false);
>
> + /* Call the pre reset callback */
> + if (vf->pre_reset_cb != NULL)
> + vf->pre_reset_cb(dev->data->port_id, vf->pre_reset_cb_arg);
> +
> ret = iavf_dev_reset(dev);
> if (ret)
> goto error;
> @@ -3144,6 +3148,10 @@ iavf_handle_hw_reset(struct rte_eth_dev *dev, bool vf_initiated_reset)
> error:
> PMD_DRV_LOG(DEBUG, "RESET recover with error code=%dn", ret);
> exit:
> + /* Call the post reset callback */
> + if (vf->post_reset_cb != NULL)
> + vf->post_reset_cb(dev->data->port_id, ret, vf->post_reset_cb_arg);
> +
> vf->in_reset_recovery = false;
> iavf_set_no_poll(adapter, false);
>
> @@ -3183,6 +3191,78 @@ rte_pmd_iavf_reinit(uint16_t port)
> return 0;
> }
>
> +static int
> +iavf_validate_reset_cb(uint16_t port, void *cb, void *cb_arg)
> +{
> + struct rte_eth_dev *dev;
> + struct iavf_info *vf;
> +
> + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> + if (cb == NULL && cb_arg != NULL) {
> + PMD_DRV_LOG(ERR, "Cannot unregister reset cb on port %u, arg must be NULL.", port);
> + return -EINVAL;
> + }
> +
> + dev = &rte_eth_devices[port];
> + if (!is_iavf_supported(dev)) {
> + PMD_DRV_LOG(ERR, "Cannot modify reset cb, port %u not an IAVF device.", port);
> + return -ENOTSUP;
> + }
> +
> + vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
> + if (vf->in_reset_recovery) {
> + PMD_DRV_LOG(ERR, "Cannot modify reset cb on port %u, VF is resetting.", port);
> + return -EBUSY;
> + }
> +
> + return 0;
> +}
> +
> +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_iavf_register_pre_reset_cb, 26.03)
> +int
> +rte_pmd_iavf_register_pre_reset_cb(uint16_t port,
> + iavf_pre_reset_cb_t pre_reset_cb,
> + void *pre_reset_cb_arg)
> +{
> + struct rte_eth_dev *dev;
> + struct iavf_info *vf;
> + int ret;
> +
> + ret = iavf_validate_reset_cb(port, pre_reset_cb, pre_reset_cb_arg);
> + if (ret)
> + return ret;
> +
> + dev = &rte_eth_devices[port];
> + vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
> + vf->pre_reset_cb = pre_reset_cb;
> + vf->pre_reset_cb_arg = pre_reset_cb_arg;
> +
> + return 0;
> +}
> +
> +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_iavf_register_post_reset_cb, 26.03)
> +int
> +rte_pmd_iavf_register_post_reset_cb(uint16_t port,
> + iavf_post_reset_cb_t post_reset_cb,
> + void *post_reset_cb_arg)
> +{
> + struct rte_eth_dev *dev;
> + struct iavf_info *vf;
> + int ret;
> +
> + ret = iavf_validate_reset_cb(port, post_reset_cb, post_reset_cb_arg);
> + if (ret)
> + return ret;
> +
> + dev = &rte_eth_devices[port];
> + vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
> + vf->post_reset_cb = post_reset_cb;
> + vf->post_reset_cb_arg = post_reset_cb_arg;
> +
> + return 0;
> +}
> +
> void
> iavf_set_no_poll(struct iavf_adapter *adapter, bool link_change)
> {
> diff --git a/drivers/net/intel/iavf/rte_pmd_iavf.h b/drivers/net/intel/iavf/rte_pmd_iavf.h
> index dea1bd2789..d13417eb08 100644
> --- a/drivers/net/intel/iavf/rte_pmd_iavf.h
> +++ b/drivers/net/intel/iavf/rte_pmd_iavf.h
> @@ -20,6 +20,8 @@
> #include <rte_mbuf.h>
> #include <rte_mbuf_dyn.h>
>
> +#include "iavf.h"
> +
This include is an issue, because it's an exported i.e. installed, header
including a private header that will not be installed as part of DPDK. This
gets picked up by running chkincs from test-meson-builds.sh script. [I'm
surprised this wasn't caught in the CI].
I think you may need to invert the dependency, the private iavf.h can
instead depend on the public rte_pmd_iavf.h header file.
/Bruce
More information about the dev
mailing list