From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pa0-f45.google.com (mail-pa0-f45.google.com [209.85.220.45]) by dpdk.org (Postfix) with ESMTP id DC5B25683 for ; Wed, 4 Mar 2015 04:12:20 +0100 (CET) Received: by pabli10 with SMTP id li10so29558640pab.13 for ; Tue, 03 Mar 2015 19:12:20 -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; bh=zfFVdJCM3BeechX7+Xw4WA0zyIUNfVyOpw6nAU3s2qU=; b=kGfX2ZsT/4QJzkEqofXjlB0S+74JDFWkRvaCMGfCvXOIPS8/yq+jCmsoKq0V80ZYjD UVpJs6wgCOzbHO88ky1POXOZvXLwyHZL+sK4tBg3qWsXPK+feS5mN2ogXwoohJRBg0p7 xpcBB22VfnbZrbh9IcWjD+jrXqn6nj24o7h8bRBH19XfG66pTuCCH1WED63Q7uav1Sm4 7S3jQmrZQdFzmMriN8lTNAMqAMD+gKaEnxZvVQ63OoWTXYRpfzI3gyXxNLtiBdqGMREq WWbP9uLSyqrFTwb/nbvCiGIoSe1hGZQduJkftxCvCOaVw0eO43fiFsTZ3cbncfcbC6LC pxbQ== X-Gm-Message-State: ALoCoQm5emAUUFlFpkvpfXVjDYsGO3I2a24suUS5rPLWjAWOndxiscGnPmh/fEcfPfrSlFHnbGEL X-Received: by 10.70.128.173 with SMTP id np13mr3062515pdb.33.1425438740193; Tue, 03 Mar 2015 19:12:20 -0800 (PST) Received: from localhost.localdomain (napt.igel.co.jp. [219.106.231.132]) by mx.google.com with ESMTPSA id om9sm2328474pbb.34.2015.03.03.19.12.18 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Mar 2015 19:12:19 -0800 (PST) From: Tetsuya Mukawa To: dev@dpdk.org Date: Wed, 4 Mar 2015 12:11:41 +0900 Message-Id: <1425438703-18895-1-git-send-email-mukawa@igel.co.jp> X-Mailer: git-send-email 1.9.1 Subject: [dpdk-dev] [PATCH 1/3] BSD: Support Port Hotplug function 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: , X-List-Received-Date: Wed, 04 Mar 2015 03:12:21 -0000 This patch adds Hotplug support to BSD. Signed-off-by: Tetsuya Mukawa --- lib/librte_eal/bsdapp/eal/eal_pci.c | 169 +++++++++++++++++++++++++- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 6 + lib/librte_eal/common/include/rte_pci.h | 1 + lib/librte_ether/rte_ethdev.c | 1 + 4 files changed, 174 insertions(+), 3 deletions(-) diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c index 9193f80..fc5a088 100644 --- a/lib/librte_eal/bsdapp/eal/eal_pci.c +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -156,6 +156,26 @@ fail: return NULL; } +/* unmap a particular resource */ +static int +pci_unmap_resource(void *requested_addr, size_t size) +{ + if (requested_addr == NULL) + return -EINVAL; + + /* Unmap the PCI memory resource of device */ + if (munmap(requested_addr, size)) { + RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n", + __func__, requested_addr, (unsigned long)size, + strerror(errno)); + } else { + RTE_LOG(DEBUG, EAL, " PCI memory unmapped at %p\n", + requested_addr); + return -EFAULT; + } + return 0; +} + static int pci_uio_map_secondary(struct rte_pci_device *dev) { @@ -270,6 +290,76 @@ pci_uio_map_resource(struct rte_pci_device *dev) return (0); } +static int +pci_uio_unmap(struct uio_resource *uio_res) +{ + int ret; + unsigned i; + + if (uio_res == NULL) + return -EINVAL; + + for (i = 0; i != uio_res->nb_maps; i++) { + ret = pci_unmap_resource(uio_res->maps[i].addr, + (size_t)uio_res->maps[i].size); + if (ret < 0) + return ret; + } + return 0; +} + +static struct uio_resource * +pci_uio_find_resource(struct rte_pci_device *dev) +{ + struct uio_resource *uio_res; + + if (dev == NULL) + return NULL; + + TAILQ_FOREACH(uio_res, uio_res_list, next) { + + /* skip this element if it doesn't match our PCI address */ + if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr)) + return uio_res; + } + return NULL; +} + +/* map the PCI resource of a PCI device in virtual memory */ +static int +pci_uio_unmap_resource(struct rte_pci_device *dev) +{ + struct uio_resource *uio_res; + + if (dev == NULL) + return -EINVAL; + + /* find an entry for the device */ + uio_res = pci_uio_find_resource(dev); + if (uio_res == NULL) + return -ENODEV; + + /* secondary processes - just free maps */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return pci_uio_unmap(uio_res); + + TAILQ_REMOVE(uio_res_list, uio_res, next); + + /* unmap all resources */ + pci_uio_unmap(uio_res); + + /* free_uio resource */ + rte_free(uio_res); + + /* close fd if in primary process */ + close(dev->intr_handle.fd); + + dev->intr_handle.fd = -1; + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + + return 0; +} + /* Scan one pci sysfs entry, and fill the devices list from it. */ static int pci_scan_one(int dev_pci_fd, struct pci_conf *conf) @@ -307,6 +397,9 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) /* FreeBSD has no NUMA support (yet) */ dev->numa_node = 0; + /* FreeBSD has only one pass through driver */ + dev->pt_driver = RTE_PT_NIC_UIO; + /* parse resources */ switch (conf->pc_hdr & PCIM_HDRTYPE) { case PCIM_HDRTYPE_NORMAL: @@ -376,8 +469,8 @@ skipdev: * Scan the content of the PCI bus, and add the devices in the devices * list. Call pci_scan_one() for each pci entry found. */ -static int -pci_scan(void) +int +rte_eal_pci_scan(void) { int fd = -1; unsigned dev_count = 0; @@ -487,6 +580,76 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d return 1; } +/* + * If vendor/device ID match, call the devuninit() function of the + * driver. + */ +int +rte_eal_pci_close_one_driver(struct rte_pci_driver *dr, + struct rte_pci_device *dev) +{ + struct rte_pci_id *id_table; + int ret; + + if ((dr == NULL) || (dev == NULL)) + return -EINVAL; + + for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) { + + /* check if device's identifiers match the driver's ones */ + if (id_table->vendor_id != dev->id.vendor_id && + id_table->vendor_id != PCI_ANY_ID) + continue; + if (id_table->device_id != dev->id.device_id && + id_table->device_id != PCI_ANY_ID) + continue; + if (id_table->subsystem_vendor_id != + dev->id.subsystem_vendor_id && + id_table->subsystem_vendor_id != PCI_ANY_ID) + continue; + if (id_table->subsystem_device_id != + dev->id.subsystem_device_id && + id_table->subsystem_device_id != PCI_ANY_ID) + continue; + + struct rte_pci_addr *loc = &dev->addr; + + RTE_LOG(DEBUG, EAL, + "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", + loc->domain, loc->bus, loc->devid, loc->function, + dev->numa_node); + + RTE_LOG(DEBUG, EAL, + " remove driver: %x:%x %s\n", dev->id.vendor_id, + dev->id.device_id, dr->name); + + /* no initialization when blacklisted, return without error */ + if (dev->devargs != NULL && + dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) { + + RTE_LOG(DEBUG, EAL, + " Device is blacklisted, not initializing\n"); + return 0; + } + + /* call the driver devuninit() function */ + if (dr->devuninit && (dr->devuninit(dev) < 0)) + return -1; /* negative value is an error */ + + /* clear driver structure */ + dev->driver = NULL; + + if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) { + /* map resources for devices that use igb_uio */ + ret = pci_uio_unmap_resource(dev); + if (ret != 0) + return ret; + } + } + /* return positive value if driver is not found */ + return 1; +} + /* Init the PCI EAL subsystem */ int rte_eal_pci_init(void) @@ -499,7 +662,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; } diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index d83524d..54f5ff1 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -37,9 +37,13 @@ DPDK_2.0 { rte_eal_lcore_role; rte_eal_mp_remote_launch; rte_eal_mp_wait_lcore; + rte_eal_parse_devargs_str; + rte_eal_pci_close_one; rte_eal_pci_dump; rte_eal_pci_probe; + rte_eal_pci_probe_one; rte_eal_pci_register; + rte_eal_pci_scan; rte_eal_pci_unregister; rte_eal_process_type; rte_eal_remote_launch; @@ -47,6 +51,8 @@ DPDK_2.0 { rte_eal_tailq_lookup_by_idx; rte_eal_tailq_reserve; rte_eal_tailq_reserve_by_idx; + rte_eal_vdev_init; + rte_eal_vdev_uninit; rte_eal_wait_lcore; rte_exit; rte_get_hpet_cycles; diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index b9cdf8b..dc74821 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -147,6 +147,7 @@ enum rte_pt_driver { RTE_PT_IGB_UIO = 1, RTE_PT_VFIO = 2, RTE_PT_UIO_GENERIC = 3, + RTE_PT_NIC_UIO = 4, /* Driver for BSD */ }; /** diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 6ea7a17..9687fab 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -516,6 +516,7 @@ rte_eth_dev_is_detachable(uint8_t port_id) switch (rte_eth_devices[port_id].pci_dev->pt_driver) { case RTE_PT_IGB_UIO: case RTE_PT_UIO_GENERIC: + case RTE_PT_NIC_UIO: break; case RTE_PT_VFIO: default: -- 1.9.1