From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id C9BD5AABB for ; Wed, 21 Mar 2018 07:12:38 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Mar 2018 23:12:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,338,1517904000"; d="scan'208";a="40803466" Received: from jeffguo-z170x-ud5.sh.intel.com (HELO localhost.localdomain) ([10.67.104.10]) by orsmga001.jf.intel.com with ESMTP; 20 Mar 2018 23:12:31 -0700 From: Jeff Guo To: stephen@networkplumber.org, bruce.richardson@intel.com, ferruh.yigit@intel.com, konstantin.ananyev@intel.com, gaetan.rivet@6wind.com, jingjing.wu@intel.com, thomas@monjalon.net, motih@mellanox.com, harry.van.haaren@intel.com, jianfeng.tan@intel.com Cc: jblunck@infradead.org, shreyansh.jain@nxp.com, dev@dpdk.org, jia.guo@intel.com, helin.zhang@intel.com Date: Wed, 21 Mar 2018 14:11:33 +0800 Message-Id: <1521612693-13378-2-git-send-email-jia.guo@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521612693-13378-1-git-send-email-jia.guo@intel.com> References: <1515575544-2141-6-git-send-email-jia.guo@intel.com> <1521612693-13378-1-git-send-email-jia.guo@intel.com> Subject: [dpdk-dev] [PATCH V15 2/2] pci: add driver auto bind for hot insertion 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, 21 Mar 2018 06:12:39 -0000 Normally we use drivectl or dpdk-devbind.py to bind kernel driver before application running, so if we want to automatically driver binding after application run, need to implement a auto bind function, that would benefit for hot insertion case, when detect hot insertion uevent of device, user could auto bind the driver according some user policy and then attach device, let app running smoothly when hotplug behavior occur. Signed-off-by: Jeff Guo --- v15->v14: delete bind_driver in bus ops, replace to add bind_driver api in eal dev to let app directly call --- app/test-pmd/testpmd.c | 17 ++++++++++++ lib/librte_eal/bsdapp/eal/eal_dev.c | 7 +++++ lib/librte_eal/common/include/rte_dev.h | 15 ++++++++++ lib/librte_eal/linuxapp/eal/eal_dev.c | 49 +++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 1c4afea..7eb9c48 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -2174,6 +2174,18 @@ in_hotplug_list(const char *dev_name) return false; } +static enum rte_kernel_driver +get_hotplug_driver(const char *dev_name) +{ + struct hotplug_request *hp_request = NULL; + + TAILQ_FOREACH(hp_request, &hp_list, next) { + if (!strcmp(hp_request->dev_name, dev_name)) + return hp_request->dev_kdrv; + } + return -1; +} + static int hotplug_list_add(struct rte_device *device, enum rte_kernel_driver device_kdrv) { @@ -2226,6 +2238,11 @@ eth_uevent_callback(char *device_name, enum rte_dev_event_type type, void *arg) "device removal\n"); break; case RTE_DEV_EVENT_ADD: + /** + * bind the driver to the device + * before process of hot plug adding device + */ + rte_dev_bind_driver(dev_name, get_hotplug_driver(dev_name)); if (rte_eal_alarm_set(100000, add_uevent_callback, dev_name)) fprintf(stderr, "Could not set up deferred " diff --git a/lib/librte_eal/bsdapp/eal/eal_dev.c b/lib/librte_eal/bsdapp/eal/eal_dev.c index a076ec7..7f8175b 100644 --- a/lib/librte_eal/bsdapp/eal/eal_dev.c +++ b/lib/librte_eal/bsdapp/eal/eal_dev.c @@ -33,6 +33,13 @@ rte_dev_event_monitor_stop(void) } int __rte_experimental +rte_dev_bind_driver(const char *dev_name, enum rte_kernel_driver kdrv_type) +{ + RTE_LOG(ERR, EAL, "Not support device bind driver for FreeBSD\n"); + return -1; +} + +int __rte_experimental rte_dev_failure_handler(struct rte_device *dev, enum rte_kernel_driver kdrv_type) { diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index 10a5fcf..e87639f 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -408,6 +408,21 @@ int __rte_experimental rte_dev_event_monitor_stop(void); /** + * It can be used to bind a device to a specific type of driver. + * + * @param dev_name + * The device name. + * @param kdrv_type + * The specific kernel driver's type. + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +int __rte_experimental +rte_dev_bind_driver(const char *dev_name, enum rte_kernel_driver kdrv_type); + +/** * It can be used to do device failure handler to avoid * system core dump when failure occur. * diff --git a/lib/librte_eal/linuxapp/eal/eal_dev.c b/lib/librte_eal/linuxapp/eal/eal_dev.c index fa63105..9b4adc6 100644 --- a/lib/librte_eal/linuxapp/eal/eal_dev.c +++ b/lib/librte_eal/linuxapp/eal/eal_dev.c @@ -227,6 +227,55 @@ rte_dev_event_monitor_stop(void) } int __rte_experimental +rte_dev_bind_driver(const char *dev_name, enum rte_kernel_driver kdrv_type) +{ + const char *kdrv_name; + char drv_override_path[1024]; + int drv_override_fd; + + if (!dev_name || !kdrv_type) + return -1; + + switch (kdrv_type) { + case RTE_KDRV_IGB_UIO: + kdrv_name = "igb_uio"; + break; + case RTE_KDRV_VFIO: + kdrv_name = "vfio-pci"; + break; + case RTE_KDRV_UIO_GENERIC: + kdrv_name = "uio_pci_generic"; + break; + default: + break; + } + + snprintf(drv_override_path, sizeof(drv_override_path), + "/sys/bus/pci/devices/%s/driver_override", dev_name); + + /* specify the driver for a device by writing to driver_override */ + drv_override_fd = open(drv_override_path, O_WRONLY); + if (drv_override_fd < 0) { + RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", + drv_override_path, strerror(errno)); + goto err; + } + + if (write(drv_override_fd, kdrv_name, sizeof(kdrv_name)) < 0) { + RTE_LOG(ERR, EAL, + "Error: bind failed - Cannot write " + "driver %s to device %s\n", kdrv_name, dev_name); + goto err; + } + + close(drv_override_fd); + return 0; +err: + close(drv_override_fd); + return -1; +} + +int __rte_experimental rte_dev_failure_handler(struct rte_device *dev, enum rte_kernel_driver kdrv_type) { -- 2.7.4