[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