[dpdk-dev] [PATCH v6 12/13] eal/pci: Add rte_eal_dev_attach/detach() functions

Tetsuya Mukawa mukawa at igel.co.jp
Tue Feb 3 02:28:00 CET 2015


On 2015/02/02 15:22, Qiu, Michael wrote:
> On 2/2/2015 1:43 PM, Qiu, Michael wrote:
>> On 2/1/2015 12:02 PM, Tetsuya Mukawa wrote:
>>> These functions are used for attaching or detaching a port.
>>> When rte_eal_dev_attach() is called, the function tries to realize the
>>> device name as pci address. If this is done successfully,
>>> rte_eal_dev_attach() will attach physical device port. If not, attaches
>>> virtual devive port.
>>> When rte_eal_dev_detach() is called, the function gets the device type
>>> of this port to know whether the port is came from physical or virtual.
>>> And then specific detaching function will be called.
>>>
>>> v5:
>>> - Change function names like below.
>>>   rte_eal_dev_find_and_invoke() to rte_eal_vdev_find_and_invoke().
>>>   rte_eal_dev_invoke() to rte_eal_vdev_invoke().
>>> - Add code to handle a return value of rte_eal_devargs_remove().
>>> - Fix pci address format in rte_eal_dev_detach().
>>> v4:
>>> - Fix comment.
>>> - Add error checking.
>>> - Fix indent of 'if' statement.
>>> - Change function name.
>>>
> [...]
>
>>> +/* attach the new virtual device, then store port_id of the device */
>>> +static int
>>> +rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id)
>>> +{
>>> +	char *args;
>>> +	uint8_t new_port_id;
>>> +	struct rte_eth_dev devs[RTE_MAX_ETHPORTS];
>>> +
>>> +	if ((vdevargs == NULL) || (port_id == NULL))
>>> +		goto err0;
>>> +
>>> +	args = strdup(vdevargs);
>>> +	if (args == NULL)
>>> +		goto err0;
>>> +
>>> +	/* save current port status */
>>> +	rte_eth_dev_save(devs);
>>> +	/* add the vdevargs to devargs_list */
>>> +	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, args))
>>> +		goto err1;
>>> +	/* parse vdevargs, then retrieve device name */
>>> +	get_vdev_name(args);
>>> +	/* walk around dev_driver_list to find the driver of the device,
>>> +	 * then invoke probe function o the driver */
>>> +	if (rte_eal_vdev_find_and_invoke(args, RTE_EAL_INVOKE_TYPE_PROBE))
>>> +		goto err2;
>>> +	/* get port_id enabled by above procedures */
>>> +	if (rte_eth_dev_get_changed_port(devs, &new_port_id))
>>> +		goto err2;
>>> +
>>> +	free(args);
>>> +	*port_id = new_port_id;
>>> +	return 0;
>>> +err2:
>>> +	rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, args);
>>> +err1:
>>> +	free(args);
>>> +err0:
>>> +	RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
> Here "cannot detach the device\n" should be "cannot attach the device" I
> think.

Hi Michael,

Thanks, I will fix above error message.
Also I will fix my "Drver" typos.

Tetsuya

>> Here also "Drver",
>>
>>
>> Thanks,
>> Michael
>>> +	return -1;
>>> +}
>>> +
>>> +/* detach the new virtual device, then store the name of the device */
>>> +static int
>>> +rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname)
>>> +{
>>> +	char name[RTE_ETH_NAME_MAX_LEN];
>>> +
>>> +	if (vdevname == NULL)
>>> +		goto err;
>>> +
>>> +	/* check whether the driver supports detach feature, or not */
>>> +	if (rte_eth_dev_check_detachable(port_id))
>>> +		goto err;
>>> +
>>> +	/* get device name by port id */
>>> +	if (rte_eth_dev_get_name_by_port(port_id, name))
>>> +		goto err;
>>> +	/* walk around dev_driver_list to find the driver of the device,
>>> +	 * then invoke close function o the driver */
>>> +	if (rte_eal_vdev_find_and_invoke(name, RTE_EAL_INVOKE_TYPE_CLOSE))
>>> +		goto err;
>>> +	/* remove the vdevname from devargs_list */
>>> +	if (rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, name))
>>> +		goto err;
>>> +
>>> +	strncpy(vdevname, name, sizeof(name));
>>> +	return 0;
>>> +err:
>>> +	RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
>>> +	return -1;
>>> +}
>>> +
>>> +/* attach the new device, then store port_id of the device */
>>> +int
>>> +rte_eal_dev_attach(const char *devargs, uint8_t *port_id)
>>> +{
>>> +	struct rte_pci_addr addr;
>>> +
>>> +	if ((devargs == NULL) || (port_id == NULL))
>>> +		return -EINVAL;
>>> +
>>> +	if (eal_parse_pci_DomBDF(devargs, &addr) == 0)
>>> +		return rte_eal_dev_attach_pdev(&addr, port_id);
>>> +	else
>>> +		return rte_eal_dev_attach_vdev(devargs, port_id);
>>> +}
>>> +
>>> +/* detach the device, then store the name of the device */
>>> +int
>>> +rte_eal_dev_detach(uint8_t port_id, char *name)
>>> +{
>>> +	struct rte_pci_addr addr;
>>> +	int ret;
>>> +
>>> +	if (name == NULL)
>>> +		return -EINVAL;
>>> +
>>> +	if (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PHYSICAL) {
>>> +		ret = rte_eth_dev_get_addr_by_port(port_id, &addr);
>>> +		if (ret < 0)
>>> +			return ret;
>>> +
>>> +		ret = rte_eal_dev_detach_pdev(port_id, &addr);
>>> +		if (ret == 0)
>>> +			snprintf(name, RTE_ETH_NAME_MAX_LEN,
>>> +				"%04x:%02x:%02x.%d",
>>> +				addr.domain, addr.bus,
>>> +				addr.devid, addr.function);
>>> +
>>> +		return ret;
>>> +	} else
>>> +		return rte_eal_dev_detach_vdev(port_id, name);
>>> +}
>>> +#else /* ENABLE_HOTPLUG */
>>> +int
>>> +rte_eal_dev_attach(const char *devargs __rte_unused,
>>> +			uint8_t *port_id __rte_unused)
>>> +{
>>> +	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
>>> +	return -1;
>>> +}
>>> +
>>> +/* detach the device, then store the name of the device */
>>> +int
>>> +rte_eal_dev_detach(uint8_t port_id __rte_unused,
>>> +			char *name __rte_unused)
>>> +{
>>> +	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
>>> +	return -1;
>>> +}
>>> +#endif /* ENABLE_HOTPLUG */
>>> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
>>> index 1a362ab..8168a7a 100644
>>> --- a/lib/librte_eal/common/eal_private.h
>>> +++ b/lib/librte_eal/common/eal_private.h
>>> @@ -163,6 +163,17 @@ enum rte_eal_invoke_type {
>>>  };
>>>  
>>>  /**
>>> + * Scan the content of the PCI bus, and the devices in the devices
>>> + * list
>>> + *
>>> + * This function is private to EAL.
>>> + *
>>> + * @return
>>> + *  0 on success, negative on error
>>> + */
>>> +int rte_eal_pci_scan(void);
>>> +
>>> +/**
>>>   * Mmap memory for single PCI device
>>>   *
>>>   * This function is private to EAL.
>>> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
>>> index f7e3a10..e63dd1c 100644
>>> --- a/lib/librte_eal/common/include/rte_dev.h
>>> +++ b/lib/librte_eal/common/include/rte_dev.h
>>> @@ -47,6 +47,7 @@ extern "C" {
>>>  #endif
>>>  
>>>  #include <sys/queue.h>
>>> +#include <rte_pci.h>
>>>  
>>>  /** Double linked list of device drivers. */
>>>  TAILQ_HEAD(rte_driver_list, rte_driver);
>>> @@ -57,6 +58,11 @@ TAILQ_HEAD(rte_driver_list, rte_driver);
>>>  typedef int (rte_dev_init_t)(const char *name, const char *args);
>>>  
>>>  /**
>>> + * Uninitilization function called for each device driver once.
>>> + */
>>> +typedef int (rte_dev_uninit_t)(const char *name, const char *args);
>>> +
>>> +/**
>>>   * Driver type enumeration
>>>   */
>>>  enum pmd_type {
>>> @@ -72,6 +78,7 @@ struct rte_driver {
>>>  	enum pmd_type type;		   /**< PMD Driver type */
>>>  	const char *name;                   /**< Driver name. */
>>>  	rte_dev_init_t *init;              /**< Device init. function. */
>>> +	rte_dev_uninit_t *uninit;          /**< Device uninit. function. */
>>>  };
>>>  
>>>  /**
>>> @@ -93,6 +100,32 @@ void rte_eal_driver_register(struct rte_driver *driver);
>>>  void rte_eal_driver_unregister(struct rte_driver *driver);
>>>  
>>>  /**
>>> + * Attach a new device.
>>> + *
>>> + * @param devargs
>>> + *   A pointer to a strings array describing the new device
>>> + *   to be attached. The strings should be a pci address like
>>> + *   '0000:01:00.0' or virtual device name like 'eth_pcap0'.
>>> + * @param port_id
>>> + *  A pointer to a port identifier actually attached.
>>> + * @return
>>> + *  0 on success and port_id is filled, negative on error
>>> + */
>>> +int rte_eal_dev_attach(const char *devargs, uint8_t *port_id);
>>> +
>>> +/**
>>> + * Detach a device.
>>> + *
>>> + * @param port_id
>>> + *   The port identifier of the device to detach.
>>> + * @param addr
>>> + *  A pointer to a device name actually detached.
>>> + * @return
>>> + *  0 on success and devname is filled, negative on error
>>> + */
>>> +int rte_eal_dev_detach(uint8_t port_id, char *devname);
>>> +
>>> +/**
>>>   * Initalize all the registered drivers in this process
>>>   */
>>>  int rte_eal_dev_init(void);
>>> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
>>> index 72ecf3a..0ec83b5 100644
>>> --- a/lib/librte_eal/linuxapp/eal/Makefile
>>> +++ b/lib/librte_eal/linuxapp/eal/Makefile
>>> @@ -41,6 +41,7 @@ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ring
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_malloc
>>> +CFLAGS += -I$(RTE_SDK)/lib/librte_mbuf
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ether
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem
>>>  CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_ring
>>> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
>>> index 831422e..1f43688 100644
>>> --- a/lib/librte_eal/linuxapp/eal/eal_pci.c
>>> +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
>>> @@ -431,8 +431,8 @@ error:
>>>   * Scan the content of the PCI bus, and the devices in the devices
>>>   * list
>>>   */
>>> -static int
>>> -pci_scan(void)
>>> +int
>>> +rte_eal_pci_scan(void)
>>>  {
>>>  	struct dirent *e;
>>>  	DIR *dir;
>>> @@ -764,7 +764,7 @@ rte_eal_pci_init(void)
>>>  	if (internal_config.no_pci)
>>>  		return 0;
>>>  
>>> -	if (pci_scan() < 0) {
>>> +	if (rte_eal_pci_scan() < 0) {
>>>  		RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
>>>  		return -1;
>>>  	}



More information about the dev mailing list