From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 484141B3BB for ; Wed, 28 Nov 2018 18:28:54 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Nov 2018 09:28:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,291,1539673200"; d="scan'208";a="93600173" Received: from fyigit-mobl.ger.corp.intel.com (HELO [10.237.221.75]) ([10.237.221.75]) by orsmga007.jf.intel.com with ESMTP; 28 Nov 2018 09:28:50 -0800 To: Alejandro Lucero , dev@dpdk.org References: <20181128113220.19840-1-alejandro.lucero@netronome.com> Cc: Thomas Monjalon , Andrew Rybchenko , Anatoly Burakov , Bruce Richardson , John Daley , Shahaf Shuler , Adrien Mazarguil , Konstantin Ananyev , Stephen Hemminger , Qi Zhang , Jerin Jacob From: Ferruh Yigit Openpgp: preference=signencrypt Autocrypt: addr=ferruh.yigit@intel.com; prefer-encrypt=mutual; keydata= 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 vM8= Message-ID: <56a0dbab-20e1-9a46-bbfe-3081dea0744d@intel.com> Date: Wed, 28 Nov 2018 17:28:48 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 In-Reply-To: <20181128113220.19840-1-alejandro.lucero@netronome.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Subject: Re: [dpdk-dev] [PATCH] net/nfp: add multiprocess support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Nov 2018 17:28:55 -0000 On 11/28/2018 11:32 AM, Alejandro Lucero wrote: > This patch introduces changes for supporting multiprocess support. > This is trivial for VFs but comes with some limitations for the PF. > > Due to restrictions when using NFP CPP interface, just one secondary > process is supported by now for the PF. Hi Alejandro, I think we needs to clarify first what is the multiprocess support required in PMD level, there are a few different implementations. cc'ed a few more folks for helping clarification. According my understanding, Only *one* DPDK application (primary or secondary) should control a device. There is no restriction in DPDK for it, this responsibility is pushed to application, application should manage it. Device initialization (probe()) done only by primary application. Because of above two items, we only need RTE_PROC_PRIMARY check in driver probe() but not in other eth_dev_ops. If we need eth_dev_ops should be protected, I believe that should be done in ethdev layer for all PMDs instead of each (some) PMD does it itself. Following should be possible: 1) - Primary starts with 5 ports and configures them - Start 5 secondary apps in a way each control a specific port data path 2) - Primary start with N ports - A secondary per port configure the port and control data path Thanks, ferruh > > Signed-off-by: Alejandro Lucero > --- > doc/guides/nics/features/nfp.ini | 1 + > doc/guides/nics/features/nfp_vf.ini | 1 + > drivers/net/nfp/nfp_net.c | 133 +++++++++++++-------- > drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c | 103 ++++++++++++++-- > 4 files changed, 177 insertions(+), 61 deletions(-) > > diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini > index d2899e7fb..70297b090 100644 > --- a/doc/guides/nics/features/nfp.ini > +++ b/doc/guides/nics/features/nfp.ini > @@ -24,5 +24,6 @@ Basic stats = Y > Stats per queue = Y > Linux UIO = Y > Linux VFIO = Y > +Multiprocess aware = Y > x86-64 = Y > Usage doc = Y > diff --git a/doc/guides/nics/features/nfp_vf.ini b/doc/guides/nics/features/nfp_vf.ini > index d2899e7fb..70297b090 100644 > --- a/doc/guides/nics/features/nfp_vf.ini > +++ b/doc/guides/nics/features/nfp_vf.ini > @@ -24,5 +24,6 @@ Basic stats = Y > Stats per queue = Y > Linux UIO = Y > Linux VFIO = Y > +Multiprocess aware = Y > x86-64 = Y > Usage doc = Y > diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c > index 54c6da924..ffef97d80 100644 > --- a/drivers/net/nfp/nfp_net.c > +++ b/drivers/net/nfp/nfp_net.c > @@ -766,9 +766,12 @@ nfp_net_start(struct rte_eth_dev *dev) > goto error; > } > > - if (hw->is_pf) > + if (hw->is_pf && rte_eal_process_type() == RTE_PROC_PRIMARY) > /* Configure the physical port up */ > nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 1); > + else > + nfp_eth_set_configured(dev->process_private, > + hw->pf_port_idx, 1); > > hw->ctrl = new_ctrl; > > @@ -817,9 +820,12 @@ nfp_net_stop(struct rte_eth_dev *dev) > (struct nfp_net_rxq *)dev->data->rx_queues[i]); > } > > - if (hw->is_pf) > + if (hw->is_pf && rte_eal_process_type() == RTE_PROC_PRIMARY) > /* Configure the physical port down */ > nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 0); > + else > + nfp_eth_set_configured(dev->process_private, > + hw->pf_port_idx, 0); > } > > /* Reset and stop device. The device can not be restarted. */ > @@ -2918,16 +2924,16 @@ nfp_net_init(struct rte_eth_dev *eth_dev) > hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2], > hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]); > > - /* Registering LSC interrupt handler */ > - rte_intr_callback_register(&pci_dev->intr_handle, > - nfp_net_dev_interrupt_handler, > - (void *)eth_dev); > - > - /* Telling the firmware about the LSC interrupt entry */ > - nn_cfg_writeb(hw, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX); > - > - /* Recording current stats counters values */ > - nfp_net_stats_reset(eth_dev); > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + /* Registering LSC interrupt handler */ > + rte_intr_callback_register(&pci_dev->intr_handle, > + nfp_net_dev_interrupt_handler, > + (void *)eth_dev); > + /* Telling the firmware about the LSC interrupt entry */ > + nn_cfg_writeb(hw, NFP_NET_CFG_LSC, NFP_NET_IRQ_LSC_IDX); > + /* Recording current stats counters values */ > + nfp_net_stats_reset(eth_dev); > + } > > return 0; > > @@ -2947,7 +2953,7 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports, > struct rte_eth_dev *eth_dev; > struct nfp_net_hw *hw; > char *port_name; > - int ret; > + int retval; > > port_name = rte_zmalloc("nfp_pf_port_name", 100, 0); > if (!port_name) > @@ -2958,51 +2964,76 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports, > else > sprintf(port_name, "%s", dev->device.name); > > - eth_dev = rte_eth_dev_allocate(port_name); > - if (!eth_dev) > - return -ENOMEM; > > - if (port == 0) { > - *priv = rte_zmalloc(port_name, > - sizeof(struct nfp_net_adapter) * ports, > - RTE_CACHE_LINE_SIZE); > - if (!*priv) { > - rte_eth_dev_release_port(eth_dev); > - return -ENOMEM; > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + eth_dev = rte_eth_dev_allocate(port_name); > + if (!eth_dev) { > + rte_free(port_name); > + return -ENODEV; > } > - } > - > - eth_dev->data->dev_private = *priv; > - > - /* > - * dev_private pointing to port0 dev_private because we need > - * to configure vNIC bars based on port0 at nfp_net_init. > - * Then dev_private is adjusted per port. > - */ > - hw = (struct nfp_net_hw *)(eth_dev->data->dev_private) + port; > - hw->cpp = cpp; > - hw->hwinfo = hwinfo; > - hw->sym_tbl = sym_tbl; > - hw->pf_port_idx = phys_port; > - hw->is_pf = 1; > - if (ports > 1) > - hw->pf_multiport_enabled = 1; > + if (port == 0) { > + *priv = rte_zmalloc(port_name, > + sizeof(struct nfp_net_adapter) * > + ports, RTE_CACHE_LINE_SIZE); > + if (!*priv) { > + rte_free(port_name); > + rte_eth_dev_release_port(eth_dev); > + return -ENOMEM; > + } > + } > + eth_dev->data->dev_private = *priv; > > - hw->total_ports = ports; > + /* > + * dev_private pointing to port0 dev_private because we need > + * to configure vNIC bars based on port0 at nfp_net_init. > + * Then dev_private is adjusted per port. > + */ > + hw = (struct nfp_net_hw *)(eth_dev->data->dev_private) + port; > + hw->cpp = cpp; > + hw->hwinfo = hwinfo; > + hw->sym_tbl = sym_tbl; > + hw->pf_port_idx = phys_port; > + hw->is_pf = 1; > + if (ports > 1) > + hw->pf_multiport_enabled = 1; > + > + hw->total_ports = ports; > + } else { > + eth_dev = rte_eth_dev_attach_secondary(port_name); > + if (!eth_dev) { > + RTE_LOG(ERR, EAL, "secondary process attach failed, " > + "ethdev doesn't exist"); > + rte_free(port_name); > + return -ENODEV; > + } > + eth_dev->process_private = cpp; > + } > > eth_dev->device = &dev->device; > rte_eth_copy_pci_info(eth_dev, dev); > > - ret = nfp_net_init(eth_dev); > + retval = nfp_net_init(eth_dev); > > - if (ret) > - rte_eth_dev_release_port(eth_dev); > - else > + if (retval) { > + retval = -ENODEV; > + goto probe_failed; > + } else { > rte_eth_dev_probing_finish(eth_dev); > + } > > rte_free(port_name); > > - return ret; > + return retval; > + > +probe_failed: > + rte_free(port_name); > + /* free ports private data if primary process */ > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) > + rte_free(eth_dev->data->dev_private); > + > + rte_eth_dev_release_port(eth_dev); > + > + return retval; > } > > #define DEFAULT_FW_PATH "/lib/firmware/netronome" > @@ -3180,10 +3211,12 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, > return -EIO; > } > > - if (nfp_fw_setup(dev, cpp, nfp_eth_table, hwinfo)) { > - PMD_DRV_LOG(INFO, "Error when uploading firmware"); > - ret = -EIO; > - goto error; > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + if (nfp_fw_setup(dev, cpp, nfp_eth_table, hwinfo)) { > + PMD_DRV_LOG(INFO, "Error when uploading firmware"); > + ret = -EIO; > + goto error; > + } > } > > /* Now the symbol table should be there */ > diff --git a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c > index c68d9400f..39bd48a83 100644 > --- a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c > +++ b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c > @@ -112,6 +112,7 @@ struct nfp_pcie_user { > > int device; > int lock; > + int secondary_lock; > char busdev[BUSDEV_SZ]; > int barsz; > char *cfg; > @@ -290,14 +291,32 @@ nfp_reconfigure_bar(struct nfp_pcie_user *nfp, struct nfp_bar *bar, int tgt, > * already mapped. > * > * BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM) > + * > + * Halving PCItoCPPBars for primary and secondary processes. > + * NFP PMD just requires two fixed slots, one for configuration BAR, > + * and another for accessing the hw queues. Another slot is needed > + * for setting the link up or down. Secondary processes do not need > + * to map the first two slots again, but it requires one slot for > + * accessing the link, even if it is not likely the secondary process > + * starting the port. This implies a limit of secondary processes > + * supported. Due to this requirement and future extensions requiring > + * new slots per process, only one secondary process is supported by > + * now. > */ > static int > nfp_enable_bars(struct nfp_pcie_user *nfp) > { > struct nfp_bar *bar; > - int x; > + int x, start, end; > > - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + start = 4; > + end = 1; > + } else { > + start = 7; > + end = 4; > + } > + for (x = start; x > end; x--) { > bar = &nfp->bar[x - 1]; > bar->barcfg = 0; > bar->nfp = nfp; > @@ -320,9 +339,16 @@ static struct nfp_bar * > nfp_alloc_bar(struct nfp_pcie_user *nfp) > { > struct nfp_bar *bar; > - int x; > + int x, start, end; > > - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + start = 4; > + end = 1; > + } else { > + start = 7; > + end = 4; > + } > + for (x = start; x > end; x--) { > bar = &nfp->bar[x - 1]; > if (!bar->lock) { > bar->lock = 1; > @@ -336,9 +362,17 @@ static void > nfp_disable_bars(struct nfp_pcie_user *nfp) > { > struct nfp_bar *bar; > - int x; > + int x, start, end; > + > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { > + start = 4; > + end = 1; > + } else { > + start = 7; > + end = 4; > + } > > - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { > + for (x = start; x > end; x--) { > bar = &nfp->bar[x - 1]; > if (bar->iomem) { > bar->iomem = NULL; > @@ -633,6 +667,47 @@ nfp_acquire_process_lock(struct nfp_pcie_user *desc) > return 0; > } > > +static int > +nfp_acquire_secondary_process_lock(struct nfp_pcie_user *desc) > +{ > + int rc; > + struct flock lock; > + const char *lockname = "/.lock_nfp_secondary"; > + char *home_path; > + char *lockfile; > + > + memset(&lock, 0, sizeof(lock)); > + > + /* > + * Using user's home directory. Note this can be called in a DPDK app > + * being executed as non-root. This is not the case for the previous > + * function nfp_acquire_process_lock which is invoked only when UIO > + * driver is used because that implies root user. > + */ > + home_path = getenv("HOME"); > + lockfile = calloc(strlen(home_path) + strlen(lockname) + 1, > + sizeof(char)); > + > + strcat(lockfile, home_path); > + strcat(lockfile, "/.lock_nfp_secondary"); > + desc->secondary_lock = open(lockfile, O_RDWR | O_CREAT | O_NONBLOCK, > + 0666); > + if (desc->secondary_lock < 0) { > + RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n"); > + return desc->secondary_lock; > + } > + > + lock.l_type = F_WRLCK; > + lock.l_whence = SEEK_SET; > + rc = fcntl(desc->secondary_lock, F_SETLK, &lock); > + if (rc < 0) { > + RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n"); > + close(desc->secondary_lock); > + } > + > + return rc; > +} > + > static int > nfp6000_set_model(struct rte_pci_device *dev, struct nfp_cpp *cpp) > { > @@ -774,7 +849,6 @@ static int > nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) > { > int ret = 0; > - uint32_t model; > struct nfp_pcie_user *desc; > > desc = malloc(sizeof(*desc)); > @@ -785,12 +859,20 @@ nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) > memset(desc->busdev, 0, BUSDEV_SZ); > strlcpy(desc->busdev, dev->device.name, sizeof(desc->busdev)); > > - if (cpp->driver_lock_needed) { > + if (rte_eal_process_type() == RTE_PROC_PRIMARY && > + cpp->driver_lock_needed) { > ret = nfp_acquire_process_lock(desc); > if (ret) > return -1; > } > > + /* Just support for one secondary process */ > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { > + ret = nfp_acquire_secondary_process_lock(desc); > + if (ret) > + return -1; > + } > + > if (nfp6000_set_model(dev, cpp) < 0) > return -1; > if (nfp6000_set_interface(dev, cpp) < 0) > @@ -806,9 +888,6 @@ nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) > > nfp_cpp_priv_set(cpp, desc); > > - model = __nfp_cpp_model_autodetect(cpp); > - nfp_cpp_model_set(cpp, model); > - > return ret; > } > > @@ -820,6 +899,8 @@ nfp6000_free(struct nfp_cpp *cpp) > nfp_disable_bars(desc); > if (cpp->driver_lock_needed) > close(desc->lock); > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) > + close(desc->secondary_lock); > close(desc->device); > free(desc); > } >