From patchwork Fri May 1 14:36:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iremonger, Bernard" X-Patchwork-Id: 4599 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 E381CCD59; Fri, 1 May 2015 16:36:39 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 91F10CD0A for ; Fri, 1 May 2015 16:36:37 +0200 (CEST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 01 May 2015 07:36:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,350,1427785200"; d="scan'208";a="488118816" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by FMSMGA003.fm.intel.com with ESMTP; 01 May 2015 07:36:22 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t41EaLx1030547; Fri, 1 May 2015 15:36:21 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id t41EaLYp002071; Fri, 1 May 2015 15:36:21 +0100 Received: (from bairemon@localhost) by sivswdev01.ir.intel.com with id t41EaLr9002067; Fri, 1 May 2015 15:36:21 +0100 From: Bernard Iremonger To: dev@dpdk.org Date: Fri, 1 May 2015 15:36:19 +0100 Message-Id: <1430490979-1994-1-git-send-email-bernard.iremonger@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: References: Subject: [dpdk-dev] [RFC PATCH] librte_pmd_bond: add support for PCI Port Hotplug 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 patch depends on the Port Hotplug Framework. It implements the rte_dev_uninit_t() function for the link bonding pmd. Signed-off-by: Bernard Iremonger --- lib/librte_pmd_bond/rte_eth_bond.h | 13 ++++- lib/librte_pmd_bond/rte_eth_bond_api.c | 84 ++++++++++++++++++++-------- lib/librte_pmd_bond/rte_eth_bond_pmd.c | 23 +++++++- lib/librte_pmd_bond/rte_eth_bond_private.h | 5 +- 4 files changed, 97 insertions(+), 28 deletions(-) diff --git a/lib/librte_pmd_bond/rte_eth_bond.h b/lib/librte_pmd_bond/rte_eth_bond.h index d688fc3..8efbf07 100644 --- a/lib/librte_pmd_bond/rte_eth_bond.h +++ b/lib/librte_pmd_bond/rte_eth_bond.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -131,6 +131,17 @@ int rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id); /** + * Free a bonded rte_eth_dev device + * + * @param name Name of the link bonding device. + * + * @return + * 0 on success, negative value otherwise + */ +int +rte_eth_bond_free(const char *name); + +/** * Add a rte_eth_dev device as a slave to the bonded device * * @param bonded_port_id Port ID of bonded device. diff --git a/lib/librte_pmd_bond/rte_eth_bond_api.c b/lib/librte_pmd_bond/rte_eth_bond_api.c index e91a623..b91ef24 100644 --- a/lib/librte_pmd_bond/rte_eth_bond_api.c +++ b/lib/librte_pmd_bond/rte_eth_bond_api.c @@ -44,6 +44,13 @@ #define DEFAULT_POLLING_INTERVAL_10_MS (10) +static struct eth_driver rte_bond_pmd = { + .pci_drv = { + .name = "rte_bond_pmd", + .drv_flags = RTE_PCI_DRV_INTR_LSC | RTE_PCI_DRV_DETACHABLE, + }, +}; + int valid_bonded_ethdev(struct rte_eth_dev *eth_dev) { @@ -193,6 +200,7 @@ number_of_sockets(void) } const char *driver_name = "Link Bonding PMD"; +static struct rte_pci_id pci_id_table = {0}; int rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) @@ -200,9 +208,8 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) struct rte_pci_device *pci_dev = NULL; struct bond_dev_private *internals = NULL; struct rte_eth_dev *eth_dev = NULL; - struct eth_driver *eth_drv = NULL; struct rte_pci_driver *pci_drv = NULL; - struct rte_pci_id *pci_id_table = NULL; + /* now do all data allocation - for eth_dev structure, dummy pci driver * and internal (private) data */ @@ -224,26 +231,14 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) goto err; } - eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id); - if (eth_drv == NULL) { - RTE_BOND_LOG(ERR, "Unable to malloc eth_drv on socket"); - goto err; - } + pci_drv = &rte_bond_pmd.pci_drv; - pci_drv = ð_drv->pci_drv; + pci_id_table.device_id = PCI_ANY_ID; + pci_id_table.subsystem_device_id = PCI_ANY_ID; + pci_id_table.vendor_id = PCI_ANY_ID; + pci_id_table.subsystem_vendor_id = PCI_ANY_ID; - pci_id_table = rte_zmalloc_socket(name, sizeof(*pci_id_table), 0, socket_id); - if (pci_id_table == NULL) { - RTE_BOND_LOG(ERR, "Unable to malloc pci_id_table on socket"); - goto err; - } - pci_id_table->device_id = PCI_ANY_ID; - pci_id_table->subsystem_device_id = PCI_ANY_ID; - pci_id_table->vendor_id = PCI_ANY_ID; - pci_id_table->subsystem_vendor_id = PCI_ANY_ID; - - pci_drv->id_table = pci_id_table; - pci_drv->drv_flags = RTE_PCI_DRV_INTR_LSC; + pci_drv->id_table = &pci_id_table; internals = rte_zmalloc_socket(name, sizeof(*internals), 0, socket_id); if (internals == NULL) { @@ -260,8 +255,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) pci_dev->numa_node = socket_id; pci_drv->name = driver_name; - - eth_dev->driver = eth_drv; + eth_dev->driver = &rte_bond_pmd; eth_dev->data->dev_private = internals; eth_dev->data->nb_rx_queues = (uint16_t)1; eth_dev->data->nb_tx_queues = (uint16_t)1; @@ -317,13 +311,55 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) err: rte_free(pci_dev); - rte_free(pci_id_table); - rte_free(eth_drv); rte_free(internals); + rte_free(eth_dev->data->mac_addrs); return -1; } +int +rte_eth_bond_free(const char *name) +{ + struct rte_eth_dev *eth_dev = NULL; + struct bond_dev_private *internals = NULL; + + /* now free all data allocation - for eth_dev structure, + * dummy pci driver and internal (private) data + */ + + /* find an ethdev entry */ + eth_dev = rte_eth_dev_allocated(name); + if (eth_dev == NULL) + return -ENODEV; + + if (eth_dev->data->dev_started == 1) + bond_ethdev_stop(eth_dev); + + eth_dev->dev_ops = NULL; + eth_dev->rx_pkt_burst = NULL; + eth_dev->tx_pkt_burst = NULL; + + internals = eth_dev->data->dev_private; + rte_spinlock_lock(&internals->lock); + + if (internals->mode == BONDING_MODE_8023AD) { + bond_mode_8023ad_stop(eth_dev); + bond_mode_8023ad_deactivate_slave(eth_dev, internals->port_id); + } else if (internals->mode == BONDING_MODE_TLB + || internals->mode == BONDING_MODE_ALB) + bond_tlb_disable(internals); + + rte_spinlock_unlock(&internals->lock); + + rte_free(eth_dev->pci_dev); + rte_free(eth_dev->data->dev_private); + rte_free(eth_dev->data->mac_addrs); + + rte_eth_dev_release_port(eth_dev); + + return 0; +} + static int __eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id) { diff --git a/lib/librte_pmd_bond/rte_eth_bond_pmd.c b/lib/librte_pmd_bond/rte_eth_bond_pmd.c index c937e6b..45d5b89 100644 --- a/lib/librte_pmd_bond/rte_eth_bond_pmd.c +++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1503,7 +1503,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev) return 0; } -static void +void bond_ethdev_stop(struct rte_eth_dev *eth_dev) { struct bond_dev_private *internals = eth_dev->data->dev_private; @@ -2038,6 +2038,24 @@ parse_error: return -1; } +static int +bond_uninit(const char *name) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, EAL, "Uninitializing pmd_bond for %s\n", name); + + /* free link bonding eth device */ + ret = rte_eth_bond_free(name); + if (ret < 0) + RTE_LOG(ERR, EAL, "Failed to free %s\n", name); + + return ret; +} + /* this part will resolve the slave portids after all the other pdev and vdev * have been allocated */ static int @@ -2264,6 +2282,7 @@ static struct rte_driver bond_drv = { .name = "eth_bond", .type = PMD_VDEV, .init = bond_init, + .uninit = bond_uninit, }; PMD_REGISTER_DRIVER(bond_drv); diff --git a/lib/librte_pmd_bond/rte_eth_bond_private.h b/lib/librte_pmd_bond/rte_eth_bond_private.h index 45e5c65..8551ddd 100644 --- a/lib/librte_pmd_bond/rte_eth_bond_private.h +++ b/lib/librte_pmd_bond/rte_eth_bond_private.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -284,4 +284,7 @@ bond_tlb_enable(struct bond_dev_private *internals); void bond_tlb_activate_slave(struct bond_dev_private *internals); +void +bond_ethdev_stop(struct rte_eth_dev *eth_dev); + #endif