[dpdk-dev] [PATCH v6 3/8] ethdev: add generic create/destroy ethdev APIs

Shahaf Shuler shahafs at mellanox.com
Thu Mar 29 08:13:55 CEST 2018


Wednesday, March 28, 2018 4:54 PM, Declan Doherty:
> Subject: [dpdk-dev][PATCH v6 3/8] ethdev: add generic create/destroy
> ethdev APIs
> 
> Add new bus generic ethdev create/destroy APIs which are bus independent
> and provide hooks for bus specific initialisation.
> 
> Signed-off-by: Declan Doherty <declan.doherty at intel.com>
> ---
>  lib/librte_ether/Makefile                 |  1 +
>  lib/librte_ether/meson.build              |  1 +
>  lib/librte_ether/rte_ethdev.c             | 96
> ++++++++++++++++++++++++++++++-
>  lib/librte_ether/rte_ethdev_driver.h      | 57 ++++++++++++++++++
>  lib/librte_ether/rte_ethdev_pci.h         | 12 ++++
>  lib/librte_ether/rte_ethdev_representor.h | 28 +++++++++
>  lib/librte_ether/rte_ethdev_version.map   |  8 +++
>  7 files changed, 202 insertions(+), 1 deletion(-)  create mode 100644
> lib/librte_ether/rte_ethdev_representor.h
> 
> diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile index
> 3ca5782bb..5698cd47b 100644
> --- a/lib/librte_ether/Makefile
> +++ b/lib/librte_ether/Makefile
> @@ -32,6 +32,7 @@ SYMLINK-y-include += rte_ethdev_driver.h  SYMLINK-y-
> include += rte_ethdev_core.h  SYMLINK-y-include += rte_ethdev_pci.h
> SYMLINK-y-include += rte_ethdev_vdev.h
> +SYMLINK-y-include += rte_ethdev_representor.h
>  SYMLINK-y-include += rte_eth_ctrl.h
>  SYMLINK-y-include += rte_dev_info.h
>  SYMLINK-y-include += rte_flow.h
> diff --git a/lib/librte_ether/meson.build b/lib/librte_ether/meson.build
> index 7fed86056..163891556 100644
> --- a/lib/librte_ether/meson.build
> +++ b/lib/librte_ether/meson.build
> @@ -15,6 +15,7 @@ headers = files('rte_ethdev.h',
>  	'rte_ethdev_core.h',
>  	'rte_ethdev_pci.h',
>  	'rte_ethdev_vdev.h',
> +	'rte_ethdev_representor.h',
>  	'rte_eth_ctrl.h',
>  	'rte_dev_info.h',
>  	'rte_flow.h',
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f32d18cad..c719f84a3 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -345,7 +345,8 @@ rte_eth_dev_release_port(struct rte_eth_dev
> *eth_dev)
>  	rte_eth_dev_shared_data_prepare();
> 
>  	rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
> -
> +	eth_dev->device = NULL;
> +	eth_dev->intr_handle = NULL;
>  	eth_dev->state = RTE_ETH_DEV_UNUSED;
> 
>  	memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data)); @@ -
> 3403,6 +3404,99 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev
> *dev, const char *ring_name,
>  	return rte_memzone_reserve_aligned(z_name, size, socket_id, 0,
> align);  }
> 
> +int __rte_experimental
> +rte_eth_dev_create(struct rte_device *device, const char *name,
> +	size_t priv_data_size,
> +	ethdev_bus_specific_init ethdev_bus_specific_init,
> +	void *bus_init_params,
> +	ethdev_init_t ethdev_init, void *init_params) {
> +	struct rte_eth_dev *ethdev;
> +	int retval;
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> +		ethdev = rte_eth_dev_allocate(name);
> +		if (!ethdev) {
> +			retval = -ENODEV;
> +			goto probe_failed;
> +		}
> +
> +		if (priv_data_size) {
> +			ethdev->data->dev_private = rte_zmalloc_socket(
> +				name, priv_data_size,
> RTE_CACHE_LINE_SIZE,
> +				device->numa_node);
> +
> +			if (!ethdev->data->dev_private) {
> +				RTE_LOG(ERR, EAL, "failed to allocate private
> data");
> +				retval = -ENOMEM;
> +				goto probe_failed;
> +			}
> +		}
> +	} else {
> +		ethdev = rte_eth_dev_attach_secondary(name);
> +		if (!ethdev) {
> +			RTE_LOG(ERR, EAL, "secondary process attach failed,
> "
> +				"ethdev doesn't exist");
> +			retval = -ENODEV;
> +			goto probe_failed;
> +		}
> +	}
> +
> +	ethdev->device = device;
> +
> +	if (ethdev_bus_specific_init) {
> +		retval = ethdev_bus_specific_init(ethdev, bus_init_params);
> +		if (retval) {
> +			RTE_LOG(ERR, EAL,
> +				"ethdev bus specific initialisation failed");
> +			goto probe_failed;
> +		}
> +	}
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
> +	retval = ethdev_init(ethdev, init_params);
> +	if (retval) {
> +		RTE_LOG(ERR, EAL, "ethdev initialisation failed");
> +		goto probe_failed;
> +	}
> +
> +	return retval;
> +probe_failed:
> +	/* free ports private data if primary process */
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> +		rte_free(ethdev->data->dev_private);
> +
> +	rte_eth_dev_release_port(ethdev);
> +
> +	return retval;
> +}
> +
> +int  __rte_experimental
> +rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
> +	ethdev_uninit_t ethdev_uninit)
> +{
> +	int ret;
> +
> +	ethdev = rte_eth_dev_allocated(ethdev->data->name);
> +	if (!ethdev)
> +		return -ENODEV;
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_uninit, -EINVAL);
> +	if (ethdev_uninit) {
> +		ret = ethdev_uninit(ethdev);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> +		rte_free(ethdev->data->dev_private);
> +
> +	ethdev->data->dev_private = NULL;
> +
> +	return rte_eth_dev_release_port(ethdev); }
> +
> +
>  int
>  rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
>  			  int epfd, int op, void *data)
> diff --git a/lib/librte_ether/rte_ethdev_driver.h
> b/lib/librte_ether/rte_ethdev_driver.h
> index 45f08c65e..4896cea93 100644
> --- a/lib/librte_ether/rte_ethdev_driver.h
> +++ b/lib/librte_ether/rte_ethdev_driver.h
> @@ -125,6 +125,63 @@ rte_eth_dma_zone_reserve(const struct
> rte_eth_dev *eth_dev, const char *name,
>  			 uint16_t queue_id, size_t size,
>  			 unsigned align, int socket_id);
> 
> +
> +typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void
> +*init_params); typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev
> *ethdev,
> +	void *bus_specific_init_params);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * PMD helper function for the creation of a new ethdev ports.
> + *
> + * @param device
> + *  rte_device handle.
> + * @param	name
> + *  port name.
> + * @param priv_data_size
> + *  size of private data required for port.
> + * @param bus_specific_init
> + *  port bus specific initialisation callback function
> + * @param bus_init_params
> + *  port bus specific initialisation parameters
> + * @param ethdev_init
> + *  device specific port initialization callback function
> + * @param init_params
> + *  port initialisation parameters
> + *
> + * @return
> + *   Negative errno value on error, 0 on success.
> + */
> +int __rte_experimental
> +rte_eth_dev_create(struct rte_device *device, const char *name,
> +	size_t priv_data_size,
> +	ethdev_bus_specific_init bus_specific_init, void *bus_init_params,
> +	ethdev_init_t ethdev_init, void *init_params);
> +
> +
> +typedef int (*ethdev_uninit_t)(struct rte_eth_dev *ethdev);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * PMD helper function for cleaing up the resources of a ethdev port on
> +it's
> + * destruction.
> + *
> + * @param ethdev
> + *   ethdev handle of port.
> + * @param ethdev
> + *   device specific port un-initialise callback function
> + *
> + * @return
> + *   Negative errno value on error, 0 on success.
> + */
> +int __rte_experimental
> +rte_eth_dev_destroy(struct rte_eth_dev *ethdev,
> +	ethdev_uninit_t ethdev_uninit);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/librte_ether/rte_ethdev_pci.h
> b/lib/librte_ether/rte_ethdev_pci.h
> index 897ce5b41..8604a0474 100644
> --- a/lib/librte_ether/rte_ethdev_pci.h
> +++ b/lib/librte_ether/rte_ethdev_pci.h
> @@ -70,6 +70,18 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
>  	eth_dev->data->numa_node = pci_dev->device.numa_node;  }
> 
> +static inline int
> +eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device)
> {
> +	struct rte_pci_device *pci_dev = bus_device;
> +
> +	if (!pci_dev)
> +		return -ENODEV;
> +
> +	rte_eth_copy_pci_info(eth_dev, pci_dev);
> +
> +	return 0;
> +}
> +
>  /**
>   * @internal
>   * Allocates a new ethdev slot for an ethernet device and returns the pointer
> diff --git a/lib/librte_ether/rte_ethdev_representor.h
> b/lib/librte_ether/rte_ethdev_representor.h
> new file mode 100644
> index 000000000..cbc1f2855
> --- /dev/null
> +++ b/lib/librte_ether/rte_ethdev_representor.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Intel Corporation.
> + */
> +
> +
> +#ifndef _RTE_ETHDEV_REPRESENTOR_H_
> +#define _RTE_ETHDEV_REPRESENTOR_H_
> +
> +#include <rte_ethdev_driver.h>
> +
> +static int
> +eth_dev_representor_port_init(struct rte_eth_dev *ethdev, void
> +*init_params) {
> +	struct rte_eth_dev *base_ethdev = init_params;
> +
> +	if (!ethdev || !base_ethdev)
> +		return -ENODEV;
> +
> +	/** representor shares same driver as it's base device */
> +	ethdev->device->driver = base_ethdev->device->driver;
> +
> +	/** representor inherits the switch id of it's base device */
> +	ethdev->data->switch_id = base_ethdev->data->switch_id;

Why not let the PMD to set it? 

The PMD knows the specific port is a represntor port and to which switch it belongs. 
Doing it on ethdev layer will block us in the future from having more complex model were, for example, there are multiple switch domain for a set of PF + representors. 

> +
> +	return 0;
> +}
> +
> +#endif /* _RTE_ETHDEV_REPRESENTOR_H_ */
> diff --git a/lib/librte_ether/rte_ethdev_version.map
> b/lib/librte_ether/rte_ethdev_version.map
> index 87f02fb74..48b08bc36 100644
> --- a/lib/librte_ether/rte_ethdev_version.map
> +++ b/lib/librte_ether/rte_ethdev_version.map
> @@ -230,3 +230,11 @@ EXPERIMENTAL {
>  	rte_mtr_stats_update;
> 
>  } DPDK_17.11;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_eth_dev_create;
> +	rte_eth_dev_destroy;
> +
> +} DPDK_18.05;
> --
> 2.14.3



More information about the dev mailing list