[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