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 <[email protected]> > --- > 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

