From patchwork Tue Dec 9 06:30:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tetsuya Mukawa X-Patchwork-Id: 1882 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id A061C80DA; Tue, 9 Dec 2014 07:31:56 +0100 (CET) Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com [209.85.220.54]) by dpdk.org (Postfix) with ESMTP id EF8C080BC for ; Tue, 9 Dec 2014 07:31:52 +0100 (CET) Received: by mail-pa0-f54.google.com with SMTP id fb1so6757291pad.41 for ; Mon, 08 Dec 2014 22:31:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R9XtRvU6DYm4tvBUkq9u4ySGnO6nLDUv9eQ6nXD3TaM=; b=choO3lJDXM1SdTpV4ym3+XMCYu5DBnb6yihFhzDVmqKeJ0QPuYA2SyZ8no6AJNxFmX az0e39VhcHgkNk8CyWe9sUPJhl99V/8vDrSA32KxCN1GgcofzID6AqNGY9XY5cHR2u1K +C6InGiEj3yX2GrplvNQKh+1vEyKleYzVPQnzk/ObfKUW5HQFHt2LWOAlACUrK70fI3K 87b5wMWN0Ca5mY5OT87AksUVKwGTub9lj1iwd080vy96CfrdSv3T0W3pxu4YktnQmc0W mJ2CcR0RscGwHMx+K5iTWjWx7jv77tri4IGt44DBMJnciJQxfIY0cNbmOnJf2K8HyFfH 9YLQ== X-Gm-Message-State: ALoCoQlmCxlhVBlv0b3Vpu6CPxBIldwUPCtV6KLfNa8FyLMULBsdXpAZM7T0XLi5gsy+52OVRTLK X-Received: by 10.70.62.98 with SMTP id x2mr28038197pdr.94.1418106712321; Mon, 08 Dec 2014 22:31:52 -0800 (PST) Received: from eris.hq.igel.co.jp (napt.igel.co.jp. [219.106.231.132]) by mx.google.com with ESMTPSA id f12sm403088pat.43.2014.12.08.22.31.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 08 Dec 2014 22:31:51 -0800 (PST) From: Tetsuya Mukawa To: dev@dpdk.org Date: Tue, 9 Dec 2014 15:30:27 +0900 Message-Id: <1418106629-22227-27-git-send-email-mukawa@igel.co.jp> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1418106629-22227-1-git-send-email-mukawa@igel.co.jp> References: <1416474399-16851-1-git-send-email-mukawa@igel.co.jp> <1418106629-22227-1-git-send-email-mukawa@igel.co.jp> Cc: nakajima.yoshihiro@lab.ntt.co.jp, menrigh@brocade.com, masutani.hitoshi@lab.ntt.co.jp Subject: [dpdk-dev] [PATCH v3 26/28] eal/pci: Add rte_eal_dev_attach/detach() functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This functions wraps attaching and detaching functions for physical and virtual device. 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 call rte_eal_dev_attach_pdev(). If not, calls rte_eal_dev_attach_vdev(). 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 rte_eal_dev_detach_pdev() or rte_eal_dev_detach_vdev() will be called. Signed-off-by: Tetsuya Mukawa --- app/test/virtual_pmd.c | 2 +- lib/librte_eal/common/eal_common_dev.c | 34 ++++++++++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 25 ++++++++++++++++++++ lib/librte_ether/rte_ethdev.c | 14 ++++++++++-- lib/librte_ether/rte_ethdev.h | 24 +++++++++++++++++++- lib/librte_pmd_af_packet/rte_eth_af_packet.c | 2 +- lib/librte_pmd_bond/rte_eth_bond_api.c | 2 +- lib/librte_pmd_pcap/rte_eth_pcap.c | 2 +- lib/librte_pmd_ring/rte_eth_ring.c | 2 +- lib/librte_pmd_xenvirt/rte_eth_xenvirt.c | 2 +- 10 files changed, 100 insertions(+), 9 deletions(-) diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c index ade6cb0..ff8f747 100644 --- a/app/test/virtual_pmd.c +++ b/app/test/virtual_pmd.c @@ -556,7 +556,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, goto err; /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(name); + eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_PHYSICAL); if (eth_dev == NULL) goto err; diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c index 9ff03ed..c9d4894 100644 --- a/lib/librte_eal/common/eal_common_dev.c +++ b/lib/librte_eal/common/eal_common_dev.c @@ -322,4 +322,38 @@ 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 (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 (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); +} #endif /* RTE_LIBRTE_EAL_HOTPLUG & RTE_LIBRTE_EAL_LINUXAPP */ diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index f0677cb..1f8f24a 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -151,6 +151,31 @@ int rte_eal_dev_detach_pdev(uint8_t port_id, struct rte_pci_addr *addr); */ int rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname); +/** + * Attach a new device. + * + * @param devargs + * A pointer to a strings array describing the new device + * to be attached. + * @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); + #endif /* RTE_LIBRTE_EAL_HOTPLUG & RTE_LIBRTE_EAL_LINUXAPP */ /** diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 86200e0..cd5ef67 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -232,7 +232,7 @@ rte_eth_dev_allocate_new_port(void) } struct rte_eth_dev * -rte_eth_dev_allocate(const char *name) +rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type) { uint8_t port_id; struct rte_eth_dev *eth_dev; @@ -256,6 +256,7 @@ rte_eth_dev_allocate(const char *name) snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); eth_dev->data->port_id = port_id; eth_dev->attached = DEV_CONNECTED; + eth_dev->dev_type = type; nb_ports++; return eth_dev; } @@ -273,6 +274,7 @@ rte_eth_dev_free(const char *name) } eth_dev->attached = 0; + eth_dev->dev_type = RTE_ETH_DEV_UNKNOWN; nb_ports--; return eth_dev; } @@ -293,7 +295,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv, snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d", pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); - eth_dev = rte_eth_dev_allocate(ethdev_name); + eth_dev = rte_eth_dev_allocate(ethdev_name, RTE_ETH_DEV_PHYSICAL); if (eth_dev == NULL) return -ENOMEM; @@ -416,6 +418,14 @@ rte_eth_dev_count(void) return (nb_ports); } +enum rte_eth_dev_type +rte_eth_dev_get_device_type(uint8_t port_id) +{ + if (rte_eth_dev_validate_port(port_id) == DEV_INVALID) + return -1; + return rte_eth_devices[port_id].dev_type; +} + void rte_eth_dev_save(struct rte_eth_dev *devs) { diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 47622a2..0d500eb 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -1548,6 +1548,16 @@ struct eth_dev_ops { }; /** + * The eth device type + */ +enum rte_eth_dev_type { + RTE_ETH_DEV_UNKNOWN, /**< unknown device type */ + RTE_ETH_DEV_PHYSICAL, /**< physical device type */ + RTE_ETH_DEV_VIRTUAL, /**< virtual device type */ + RTE_ETH_DEV_MAX /**< max value of this enum */ +}; + +/** * @internal * The generic data structure associated with each ethernet device. * @@ -1566,6 +1576,7 @@ struct rte_eth_dev { struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */ struct rte_eth_dev_cb_list callbacks; /**< User application callbacks */ uint8_t attached; /**< Flag indicating the port is attached */ + enum rte_eth_dev_type dev_type; /**< Flag indicating the device type */ }; struct rte_eth_dev_sriov { @@ -1643,6 +1654,15 @@ extern uint8_t rte_eth_dev_count(void); /** * Function for internal use by port hotplug functions. + * Get the device type to know whether the device is physical or virtual. + * + * @return + * - Device type. + */ +extern enum rte_eth_dev_type rte_eth_dev_get_device_type(uint8_t port_id); + +/** + * Function for internal use by port hotplug functions. * Copies current ethdev structures to the specified pointer. * * @param devs The pointer to the ethdev structures @@ -1728,10 +1748,12 @@ extern struct rte_eth_dev *rte_eth_dev_allocated(const char *name); * to that slot for the driver to use. * * @param name Unique identifier name for each Ethernet device + * @param type Device type of this Ethernet device * @return * - Slot in the rte_dev_devices array for a new device; */ -struct rte_eth_dev *rte_eth_dev_allocate(const char *name); +struct rte_eth_dev *rte_eth_dev_allocate(const char *name, + enum rte_eth_dev_type type); /** * Function for internal use by dummy drivers primarily, e.g. ring-based diff --git a/lib/librte_pmd_af_packet/rte_eth_af_packet.c b/lib/librte_pmd_af_packet/rte_eth_af_packet.c index d0fb3eb..1237903 100644 --- a/lib/librte_pmd_af_packet/rte_eth_af_packet.c +++ b/lib/librte_pmd_af_packet/rte_eth_af_packet.c @@ -642,7 +642,7 @@ rte_pmd_init_internals(const char *name, } /* reserve an ethdev entry */ - *eth_dev = rte_eth_dev_allocate(name); + *eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); if (*eth_dev == NULL) goto error; diff --git a/lib/librte_pmd_bond/rte_eth_bond_api.c b/lib/librte_pmd_bond/rte_eth_bond_api.c index ef5ddf4..a6986e3 100644 --- a/lib/librte_pmd_bond/rte_eth_bond_api.c +++ b/lib/librte_pmd_bond/rte_eth_bond_api.c @@ -231,7 +231,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) } /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(name); + eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); if (eth_dev == NULL) { RTE_BOND_LOG(ERR, "Unable to allocate rte_eth_dev"); goto err; diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c index f12d1e7..0f34f73 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap.c +++ b/lib/librte_pmd_pcap/rte_eth_pcap.c @@ -710,7 +710,7 @@ rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues, goto error; /* reserve an ethdev entry */ - *eth_dev = rte_eth_dev_allocate(name); + *eth_dev = rte_eth_dev_allocate(name, VIRTUAL); if (*eth_dev == NULL) goto error; diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c index 4f1b6ed..d901053 100644 --- a/lib/librte_pmd_ring/rte_eth_ring.c +++ b/lib/librte_pmd_ring/rte_eth_ring.c @@ -256,7 +256,7 @@ rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[], goto error; /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(name); + eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); if (eth_dev == NULL) goto error; diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c index 6555ec5..4f0eda5 100644 --- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c @@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params, goto err; /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(name); + eth_dev = rte_eth_dev_allocate(name, VIRTUAL); if (eth_dev == NULL) goto err;