[dpdk-dev,v2,1/4] ethdev: modify callback process API

Message ID 1497280691-18641-2-git-send-email-bernard.iremonger@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Iremonger, Bernard June 12, 2017, 3:18 p.m. UTC
  From: "Bernard.Iremonger" <Bernard.iremonger@intel.com>

Change the rte_eth_dev_callback_process function to return int,
and add a void *ret_param parameter.

Modify the following PMD's for rte_eth_dev_callback_process
API changes:

net/bonding
net/nfp
net/enic
net/vhost
net/virtio
net/thunderx
net/e1000: e1000 and igb
net/sfc
net/ixgbe
net/i40e
net/mlx4
net/mlx5
net/bnxt

Modify testpmd for rte_eth_dev_callback_process API changes
app/testpmd

Signed-off-by: Bernard.Iremonger <Bernard.iremonger@intel.com>
---
 app/test-pmd/testpmd.c                     | 13 +++++++-----
 drivers/net/bnxt/rte_pmd_bnxt.c            |  2 +-
 drivers/net/bonding/rte_eth_bond_pmd.c     | 34 ++++++++++++++++++------------
 drivers/net/bonding/rte_eth_bond_private.h |  4 ++--
 drivers/net/e1000/em_ethdev.c              |  2 +-
 drivers/net/e1000/igb_ethdev.c             |  6 ++++--
 drivers/net/enic/enic_main.c               |  2 +-
 drivers/net/i40e/i40e_ethdev.c             |  2 +-
 drivers/net/i40e/i40e_ethdev_vf.c          |  3 ++-
 drivers/net/i40e/i40e_pf.c                 | 19 +++++++++--------
 drivers/net/ixgbe/ixgbe_ethdev.c           |  8 ++++---
 drivers/net/ixgbe/ixgbe_pf.c               | 22 ++++++++++---------
 drivers/net/mlx4/mlx4.c                    |  6 ++++--
 drivers/net/mlx5/mlx5_ethdev.c             |  6 ++++--
 drivers/net/nfp/nfp_net.c                  |  2 +-
 drivers/net/sfc/sfc_intr.c                 |  6 ++++--
 drivers/net/thunderx/nicvf_ethdev.c        |  3 ++-
 drivers/net/vhost/rte_eth_vhost.c          |  9 +++++---
 drivers/net/virtio/virtio_ethdev.c         |  3 ++-
 lib/librte_ether/rte_ethdev.c              | 15 ++++++++-----
 lib/librte_ether/rte_ethdev.h              | 21 ++++++++----------
 lib/librte_ether/rte_ether_version.map     |  7 ++++++
 22 files changed, 116 insertions(+), 79 deletions(-)
  

Comments

Thomas Monjalon June 14, 2017, 9:22 p.m. UTC | #1
Hi,

12/06/2017 17:18, Bernard Iremonger:
> Change the rte_eth_dev_callback_process function to return int,
> and add a void *ret_param parameter.

You should squash tests and examples changes in this change to avoid
breaking compilation.
Doc patch can also be squashed.

> --- a/lib/librte_ether/rte_ether_version.map
> +++ b/lib/librte_ether/rte_ether_version.map
> +DPDK_17.08 {
> +	global:
> +
> +	_rte_eth_dev_callback_process;
> +
> +} DPDK_17.05;

You should remove the original function from 2.2 ABI block.
  
Iremonger, Bernard June 15, 2017, 10:56 a.m. UTC | #2
Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Wednesday, June 14, 2017 10:22 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/4] ethdev: modify callback process API
> 
> Hi,
> 
> 12/06/2017 17:18, Bernard Iremonger:
> > Change the rte_eth_dev_callback_process function to return int, and
> > add a void *ret_param parameter.
> 
> You should squash tests and examples changes in this change to avoid
> breaking compilation.
> Doc patch can also be squashed.
> 

I will squash patches into one patch.

> > --- a/lib/librte_ether/rte_ether_version.map
> > +++ b/lib/librte_ether/rte_ether_version.map
> > +DPDK_17.08 {
> > +	global:
> > +
> > +	_rte_eth_dev_callback_process;
> > +
> > +} DPDK_17.05;
> 
> You should remove the original function from 2.2 ABI block.

I will remove from 2.2 ABI block.

Thanks for the review.

Regards,

Bernard.
  
Stephen Hemminger June 15, 2017, 3:43 p.m. UTC | #3
On Mon, 12 Jun 2017 16:18:08 +0100
Bernard Iremonger <bernard.iremonger@intel.com> wrote:

> From: "Bernard.Iremonger" <Bernard.iremonger@intel.com>
> 
> Change the rte_eth_dev_callback_process function to return int,
> and add a void *ret_param parameter.

What is the motivation for this? What is return value used for?
  
Iremonger, Bernard June 21, 2017, 9:22 a.m. UTC | #4
Hi Stephen,

> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, June 15, 2017 4:43 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>
> Cc: dev@dpdk.org; thomas@monjalon.net
> Subject: Re: [dpdk-dev] [PATCH v2 1/4] ethdev: modify callback process API
> 
> On Mon, 12 Jun 2017 16:18:08 +0100
> Bernard Iremonger <bernard.iremonger@intel.com> wrote:
> 
> > From: "Bernard.Iremonger" <Bernard.iremonger@intel.com>
> >
> > Change the rte_eth_dev_callback_process function to return int, and
> > add a void *ret_param parameter.
> 
> What is the motivation for this? What is return value used for?

Since DPDK 16.11 the i40e and ixgbe PMD's have been returning data to the calling process using the "void *cb_arg"  parameter of the callback_process API

void _rte_eth_dev_callback_process(struct rte_eth_dev *dev, enum rte_eth_event_type event, void *cb_arg);

This was not considered to be ideal by Thomas who suggested adding a "void *ret_param"   parameter to API to return data to the calling process and at the same time to change the return value from void to int to allow returning an error code if required.  

Regards,

Bernard.
  

Patch

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 17ae446..300140d 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -381,9 +381,9 @@  struct rte_fdir_conf fdir_conf = {
 /* Forward function declarations */
 static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port);
 static void check_all_ports_link_status(uint32_t port_mask);
-static void eth_event_callback(uint8_t port_id,
-			       enum rte_eth_event_type type,
-			       void *param);
+static int eth_event_callback(uint8_t port_id,
+			      enum rte_eth_event_type type,
+			      void *param, void *ret_param);
 
 /*
  * Check if all the ports are started.
@@ -1829,8 +1829,9 @@  struct pmd_test_command {
 }
 
 /* This function is used by the interrupt thread */
-static void
-eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param)
+static int
+eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param,
+		  void *ret_param)
 {
 	static const char * const event_desc[] = {
 		[RTE_ETH_EVENT_UNKNOWN] = "Unknown",
@@ -1844,6 +1845,7 @@  struct pmd_test_command {
 	};
 
 	RTE_SET_USED(param);
+	RTE_SET_USED(ret_param);
 
 	if (type >= RTE_ETH_EVENT_MAX) {
 		fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n",
@@ -1864,6 +1866,7 @@  struct pmd_test_command {
 	default:
 		break;
 	}
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index faeb6f4..fa11d1c 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -57,7 +57,7 @@  int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
 	cb_param.msg = msg;
 
 	_rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
-			&cb_param);
+			&cb_param, NULL);
 
 	/* Default to approve */
 	if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 82959ab..e89a28c 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1438,7 +1438,8 @@  struct bwg_slave {
 	if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
 		slave_eth_dev->dev_ops->link_update(slave_eth_dev, 0);
 		bond_ethdev_lsc_event_callback(slave_eth_dev->data->port_id,
-			RTE_ETH_EVENT_INTR_LSC, &bonded_eth_dev->data->port_id);
+			RTE_ETH_EVENT_INTR_LSC, &bonded_eth_dev->data->port_id,
+			NULL);
 	}
 
 	return 0;
@@ -1849,7 +1850,8 @@  struct bwg_slave {
 
 				bond_ethdev_lsc_event_callback(internals->slaves[i].port_id,
 						RTE_ETH_EVENT_INTR_LSC,
-						&bonded_ethdev->data->port_id);
+						&bonded_ethdev->data->port_id,
+						NULL);
 			}
 		}
 		rte_spinlock_unlock(&internals->lock);
@@ -1995,35 +1997,36 @@  struct bwg_slave {
 		return;
 
 	_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
-			RTE_ETH_EVENT_INTR_LSC, NULL);
+			RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
 }
 
-void
+int
 bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
-		void *param)
+		void *param, void *ret_param __rte_unused)
 {
 	struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
 	struct bond_dev_private *internals;
 	struct rte_eth_link link;
+	int rc = -1;
 
 	int i, valid_slave = 0;
 	uint8_t active_pos;
 	uint8_t lsc_flag = 0;
 
 	if (type != RTE_ETH_EVENT_INTR_LSC || param == NULL)
-		return;
+		return rc;
 
 	bonded_eth_dev = &rte_eth_devices[*(uint8_t *)param];
 	slave_eth_dev = &rte_eth_devices[port_id];
 
 	if (check_for_bonded_ethdev(bonded_eth_dev))
-		return;
+		return rc;
 
 	internals = bonded_eth_dev->data->dev_private;
 
 	/* If the device isn't started don't handle interrupts */
 	if (!bonded_eth_dev->data->dev_started)
-		return;
+		return rc;
 
 	/* verify that port_id is a valid slave of bonded port */
 	for (i = 0; i < internals->slave_count; i++) {
@@ -2034,7 +2037,7 @@  struct bwg_slave {
 	}
 
 	if (!valid_slave)
-		return;
+		return rc;
 
 	/* Search for port in active port list */
 	active_pos = find_slave_by_id(internals->active_slaves,
@@ -2043,7 +2046,7 @@  struct bwg_slave {
 	rte_eth_link_get_nowait(port_id, &link);
 	if (link.link_status) {
 		if (active_pos < internals->active_slave_count)
-			return;
+			return rc;
 
 		/* if no active slave ports then set this port to be primary port */
 		if (internals->active_slave_count < 1) {
@@ -2065,7 +2068,7 @@  struct bwg_slave {
 				RTE_LOG(ERR, PMD,
 					"port %u invalid speed/duplex\n",
 					port_id);
-				return;
+				return rc;
 			}
 		}
 
@@ -2077,7 +2080,7 @@  struct bwg_slave {
 			bond_ethdev_primary_set(internals, port_id);
 	} else {
 		if (active_pos == internals->active_slave_count)
-			return;
+			return rc;
 
 		/* Remove from active slave list */
 		deactivate_slave(bonded_eth_dev, port_id);
@@ -2116,7 +2119,8 @@  struct bwg_slave {
 						(void *)bonded_eth_dev);
 			else
 				_rte_eth_dev_callback_process(bonded_eth_dev,
-						RTE_ETH_EVENT_INTR_LSC, NULL);
+						RTE_ETH_EVENT_INTR_LSC,
+						NULL, NULL);
 
 		} else {
 			if (internals->link_down_delay_ms > 0)
@@ -2125,9 +2129,11 @@  struct bwg_slave {
 						(void *)bonded_eth_dev);
 			else
 				_rte_eth_dev_callback_process(bonded_eth_dev,
-						RTE_ETH_EVENT_INTR_LSC, NULL);
+						RTE_ETH_EVENT_INTR_LSC,
+						NULL, NULL);
 		}
 	}
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h
index b76385f..6c77d20 100644
--- a/drivers/net/bonding/rte_eth_bond_private.h
+++ b/drivers/net/bonding/rte_eth_bond_private.h
@@ -263,9 +263,9 @@  struct bond_dev_private {
 bond_ethdev_primary_set(struct bond_dev_private *internals,
 		uint8_t slave_port_id);
 
-void
+int
 bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
-		void *param);
+		void *param, void *ret_param);
 
 int
 bond_ethdev_parse_slave_port_kvarg(const char *key,
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index ba505e7..3d4ab93 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1670,7 +1670,7 @@  static int eth_em_pci_remove(struct rte_pci_device *pci_dev)
 
 	eth_em_interrupt_get_status(dev);
 	eth_em_interrupt_action(dev, dev->intr_handle);
-	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
 }
 
 static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a0da9d5..da03d9b 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2898,7 +2898,8 @@  static int eth_igb_rxq_interrupt_setup(struct rte_eth_dev *dev)
 		E1000_WRITE_REG(hw, E1000_TCTL, tctl);
 		E1000_WRITE_REG(hw, E1000_RCTL, rctl);
 		E1000_WRITE_FLUSH(hw);
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 	}
 
 	return 0;
@@ -2957,7 +2958,8 @@  void igbvf_mbx_process(struct rte_eth_dev *dev)
 
 	/* PF reset VF event */
 	if (in_msg == E1000_PF_CONTROL_MSG)
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+					      NULL, NULL);
 }
 
 static int
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index b4c6264..27a42fc 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -430,7 +430,7 @@  int enic_link_update(struct enic *enic)
 	vnic_intr_return_all_credits(&enic->intr);
 
 	enic_link_update(enic);
-	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
 	enic_log_q_error(enic);
 }
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f614949..0e1f556 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5804,7 +5804,7 @@  struct i40e_vsi *
 			ret = i40e_dev_link_update(dev, 0);
 			if (!ret)
 				_rte_eth_dev_callback_process(dev,
-					RTE_ETH_EVENT_INTR_LSC, NULL);
+					RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
 			break;
 		default:
 			PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 2d5a9b5..91c1c0f 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1328,7 +1328,8 @@  static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
 	switch (pf_msg->event) {
 	case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+					      NULL, NULL);
 		break;
 	case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 0758503..a21fae1 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -1231,7 +1231,7 @@ 
 	struct i40e_pf_vf *vf;
 	/* AdminQ will pass absolute VF id, transfer to internal vf id */
 	uint16_t vf_id = abs_vf_id - hw->func_caps.vf_base_id;
-	struct rte_pmd_i40e_mb_event_param cb_param;
+	struct rte_pmd_i40e_mb_event_param ret_param;
 	bool b_op = TRUE;
 
 	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
@@ -1251,22 +1251,23 @@ 
 	 * initialise structure to send to user application
 	 * will return response from user in retval field
 	 */
-	cb_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED;
-	cb_param.vfid = vf_id;
-	cb_param.msg_type = opcode;
-	cb_param.msg = (void *)msg;
-	cb_param.msglen = msglen;
+	ret_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED;
+	ret_param.vfid = vf_id;
+	ret_param.msg_type = opcode;
+	ret_param.msg = (void *)msg;
+	ret_param.msglen = msglen;
 
 	/**
 	 * Ask user application if we're allowed to perform those functions.
-	 * If we get cb_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED,
+	 * If we get ret_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED,
 	 * then business as usual.
 	 * If RTE_PMD_I40E_MB_EVENT_NOOP_ACK or RTE_PMD_I40E_MB_EVENT_NOOP_NACK,
 	 * do nothing and send not_supported to VF. As PF must send a response
 	 * to VF and ACK/NACK is not defined.
 	 */
-	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
-	if (cb_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) {
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX,
+				      NULL, &ret_param);
+	if (ret_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) {
 		PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!",
 			    opcode);
 		b_op = FALSE;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 504e951..a7ec651 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4155,12 +4155,13 @@  static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 		ixgbe_dev_link_update(dev, 0);
 		intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
 		ixgbe_dev_link_status_print(dev);
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 	}
 
 	if (intr->flags & IXGBE_FLAG_MACSEC) {
 		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_MACSEC,
-					      NULL);
+					      NULL, NULL);
 		intr->flags &= ~IXGBE_FLAG_MACSEC;
 	}
 
@@ -7868,7 +7869,8 @@  static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
 
 	/* PF reset VF event */
 	if (in_msg == IXGBE_PF_CONTROL_MSG)
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+					      NULL, NULL);
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index a56b270..c0d86c7 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -683,7 +683,7 @@  int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
-	struct rte_pmd_ixgbe_mb_event_param cb_param;
+	struct rte_pmd_ixgbe_mb_event_param ret_param;
 
 	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
 	if (retval) {
@@ -702,10 +702,10 @@  int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 	 * initialise structure to send to user application
 	 * will return response from user in retval field
 	 */
-	cb_param.retval = RTE_PMD_IXGBE_MB_EVENT_PROCEED;
-	cb_param.vfid = vf;
-	cb_param.msg_type = msgbuf[0] & 0xFFFF;
-	cb_param.msg = (void *)msgbuf;
+	ret_param.retval = RTE_PMD_IXGBE_MB_EVENT_PROCEED;
+	ret_param.vfid = vf;
+	ret_param.msg_type = msgbuf[0] & 0xFFFF;
+	ret_param.msg = (void *)msgbuf;
 
 	/* perform VF reset */
 	if (msgbuf[0] == IXGBE_VF_RESET) {
@@ -714,20 +714,22 @@  int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 		vfinfo[vf].clear_to_send = true;
 
 		/* notify application about VF reset */
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX,
+					      NULL, &ret_param);
 		return ret;
 	}
 
 	/**
 	 * ask user application if we allowed to perform those functions
-	 * if we get cb_param.retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED
+	 * if we get ret_param.retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED
 	 * then business as usual,
 	 * if 0, do nothing and send ACK to VF
-	 * if cb_param.retval > 1, do nothing and send NAK to VF
+	 * if ret_param.retval > 1, do nothing and send NAK to VF
 	 */
-	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX,
+				      NULL, &ret_param);
 
-	retval = cb_param.retval;
+	retval = ret_param.retval;
 
 	/* check & process VF to PF mailbox message */
 	switch ((msgbuf[0] & 0xFFFF)) {
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 5bc2a50..16cafae 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5411,7 +5411,8 @@  struct txq_mp2mr_mbuf_check_data {
 	ret = priv_dev_status_handler(priv, dev, &events);
 	priv_unlock(priv);
 	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL,
+					      NULL);
 }
 
 /**
@@ -5440,7 +5441,8 @@  struct txq_mp2mr_mbuf_check_data {
 		     i++) {
 			if (ev & (1 << i)) {
 				ev &= ~(1 << i);
-				_rte_eth_dev_callback_process(dev, i, NULL);
+				_rte_eth_dev_callback_process(dev, i, NULL,
+							      NULL);
 				ret--;
 			}
 		}
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index eadf452..96bccd5 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1262,7 +1262,8 @@  struct priv *
 	ret = priv_dev_link_status_handler(priv, dev);
 	priv_unlock(priv);
 	if (ret)
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL,
+					      NULL);
 }
 
 /**
@@ -1284,7 +1285,8 @@  struct priv *
 	ret = priv_dev_link_status_handler(priv, dev);
 	priv_unlock(priv);
 	if (ret)
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL,
+					      NULL);
 }
 
 /**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index ffd0f10..986c2ee 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1334,7 +1334,7 @@  static void nfp_net_read_mac(struct nfp_net_hw *hw)
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 
 	nfp_net_link_update(dev, 0);
-	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
 
 	nfp_net_dev_link_status_print(dev);
 
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index dfa453a..ee59cb1 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -111,7 +111,8 @@ 
 			 sa->eth_dev->data->dev_link.link_status ?
 			 "UP" : "DOWN");
 		_rte_eth_dev_callback_process(sa->eth_dev,
-					      RTE_ETH_EVENT_INTR_LSC, NULL);
+					      RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 	}
 }
 
@@ -152,7 +153,8 @@ 
 	if (lsc_seq != sa->port.lsc_seq) {
 		sfc_info(sa, "link status change event");
 		_rte_eth_dev_callback_process(sa->eth_dev,
-					      RTE_ETH_EVENT_INTR_LSC, NULL);
+					      RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 	}
 }
 
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 520ccc6..6aa798f 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -111,7 +111,8 @@  static void nicvf_vf_stop(struct rte_eth_dev *dev, struct nicvf *nic,
 	if (nicvf_reg_poll_interrupts(nic) == NIC_MBOX_MSG_BGX_LINK_CHANGE) {
 		if (dev->data->dev_conf.intr_conf.lsc)
 			nicvf_set_eth_link_status(nic, &dev->data->dev_link);
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 	}
 
 	rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 257bf6d..98b3675 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -607,7 +607,8 @@  struct vhost_xstats_name_off {
 
 	RTE_LOG(INFO, PMD, "New connection established\n");
 
-	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
+				      NULL, NULL);
 
 	return 0;
 }
@@ -661,7 +662,8 @@  struct vhost_xstats_name_off {
 
 	RTE_LOG(INFO, PMD, "Connection closed\n");
 
-	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC,
+				      NULL, NULL);
 }
 
 static int
@@ -690,7 +692,8 @@  struct vhost_xstats_name_off {
 	RTE_LOG(INFO, PMD, "vring%u is %s\n",
 			vring, enable ? "enabled" : "disabled");
 
-	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE, NULL);
+	_rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE,
+				      NULL, NULL);
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 4fcda80..f0d59a8 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1229,7 +1229,8 @@  static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev,
 	if (isr & VIRTIO_PCI_ISR_CONFIG) {
 		if (virtio_dev_link_update(dev, 0) == 0)
 			_rte_eth_dev_callback_process(dev,
-						      RTE_ETH_EVENT_INTR_LSC, NULL);
+						      RTE_ETH_EVENT_INTR_LSC,
+						      NULL, NULL);
 	}
 
 }
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9227ecc..e983d78 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1,7 +1,7 @@ 
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -129,6 +129,7 @@  struct rte_eth_dev_callback {
 	TAILQ_ENTRY(rte_eth_dev_callback) next; /**< Callbacks list */
 	rte_eth_dev_cb_fn cb_fn;                /**< Callback address */
 	void *cb_arg;                           /**< Parameter for callback */
+	void *ret_param;                        /**< Return parameter */
 	enum rte_eth_event_type event;          /**< Interrupt event type */
 	uint32_t active;                        /**< Callback is executing */
 };
@@ -2717,12 +2718,13 @@  int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 	return ret;
 }
 
-void
+int
 _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
-	enum rte_eth_event_type event, void *cb_arg)
+	enum rte_eth_event_type event, void *cb_arg, void *ret_param)
 {
 	struct rte_eth_dev_callback *cb_lst;
 	struct rte_eth_dev_callback dev_cb;
+	int rc = 0;
 
 	rte_spinlock_lock(&rte_eth_dev_cb_lock);
 	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
@@ -2732,14 +2734,17 @@  int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 		cb_lst->active = 1;
 		if (cb_arg != NULL)
 			dev_cb.cb_arg = cb_arg;
+		if (ret_param != NULL)
+			dev_cb.ret_param = ret_param;
 
 		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
-		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
-						dev_cb.cb_arg);
+		rc = dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
+				dev_cb.cb_arg, dev_cb.ret_param);
 		rte_spinlock_lock(&rte_eth_dev_cb_lock);
 		cb_lst->active = 0;
 	}
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
+	return rc;
 }
 
 int
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b0d2353..63f0e06 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1,7 +1,7 @@ 
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -3338,8 +3338,8 @@  enum rte_eth_event_type {
 	RTE_ETH_EVENT_MAX       /**< max value of this enum */
 };
 
-typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
-		enum rte_eth_event_type event, void *cb_arg);
+typedef int (*rte_eth_dev_cb_fn)(uint8_t port_id,
+		enum rte_eth_event_type event, void *cb_arg, void *ret_param);
 /**< user application callback to be registered for interrupts */
 
 
@@ -3356,11 +3356,6 @@  typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
  * @param cb_arg
  *  Pointer to the parameters for the registered callback.
  *
- *  The user data is overwritten in the case of RTE_ETH_EVENT_VF_MBOX.
- *	This even occurs when a message from the VF is received by the PF.
- *	The user data is overwritten with struct rte_pmd_ixgbe_mb_event_param.
- *	This struct is defined in rte_pmd_ixgbe.h.
- *
  * @return
  *  - On success, zero.
  *  - On failure, a negative value.
@@ -3400,15 +3395,17 @@  int rte_eth_dev_callback_unregister(uint8_t port_id,
  * @param event
  *  Eth device interrupt event type.
  * @param cb_arg
- *  Update callback parameter to pass data back to user application.
+ *  callback parameter.
+ * @param ret_param
+ *  To pass data back to user application.
  *  This allows the user application to decide if a particular function
  *  is permitted or not.
  *
  * @return
- *  void
+ *  int
  */
-void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
-				enum rte_eth_event_type event, void *cb_arg);
+int _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event, void *cb_arg, void *ret_param);
 
 /**
  * When there is no rx packet coming in Rx Queue for a long time, we can
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 1d22434..aefc826 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -147,3 +147,10 @@  DPDK_17.05 {
 	rte_eth_xstats_get_names_by_id;
 
 } DPDK_17.02;
+
+DPDK_17.08 {
+	global:
+
+	_rte_eth_dev_callback_process;
+
+} DPDK_17.05;