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 C0F747CC3 for ; Sun, 3 Sep 2017 17:49:08 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Sep 2017 08:49:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,469,1498546800"; d="scan'208";a="307495750" Received: from jeffguo-s2600wt2.sh.intel.com (HELO localhost.localdomain) ([10.67.110.10]) by fmsmga004.fm.intel.com with ESMTP; 03 Sep 2017 08:49:06 -0700 From: Jeff Guo To: stephen@networkplumber.org, bruce.richardson@intel.com Cc: dev@dpdk.org, gaetan.rivet@6wind.com, shreyansh.jain@nxp.com, jblunck@infradead.org, helin.zhang@intel.com, ferruh.yigit@intel.com, konstantin.ananyev@intel.com, thomas@monjalon.net, jingjing.wu@intel.com, jia.guo@intel.com Date: Sun, 3 Sep 2017 23:49:45 +0800 Message-Id: <1504453785-15735-3-git-send-email-jia.guo@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1504453785-15735-1-git-send-email-jia.guo@intel.com> References: <1498712510-44217-2-git-send-email-jia.guo@intel.com> <1504453785-15735-1-git-send-email-jia.guo@intel.com> Subject: [dpdk-dev] [PATCH v4 2/2] app/testpmd: use uevent to monitor hot removal 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: Sun, 03 Sep 2017 15:49:09 -0000 use testpmd for example, to show app how to request and use uevent monitoring to handle an event of device hot removal. Signed-off-by: Jeff Guo --- app/test-pmd/testpmd.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 9a36e66..b5ff7d7 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -393,6 +393,10 @@ static void check_all_ports_link_status(uint32_t port_mask); static int eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param, void *ret_param); +static int eth_uevent_callback(struct rte_device *dev, + enum rte_eal_uevent_type type, + void *param, void *ret_param); + /* * Check if all the ports are started. @@ -1413,6 +1417,7 @@ start_port(portid_t pid) struct rte_port *port; struct ether_addr mac_addr; enum rte_eth_event_type event_type; + enum rte_eal_uevent_type uevent_type; if (port_id_is_invalid(pid, ENABLED_WARN)) return 0; @@ -1548,6 +1553,18 @@ start_port(portid_t pid) } } + for (uevent_type = RTE_EAL_UEVENT_UNKNOWN; + uevent_type < RTE_EAL_UEVENT_MAX; + uevent_type++) { + diag = rte_eal_uev_callback_register(&port->dev_info.pci_dev->device,uevent_type, + eth_uevent_callback, NULL); + if (diag) { + printf("Failed to setup uevent callback for uevent %d\n", + uevent_type); + return -1; + } + } + /* start port */ if (rte_eth_dev_start(pi) < 0) { printf("Fail to start port %d\n", pi); @@ -1842,6 +1859,16 @@ rmv_event_callback(void *arg) dev->device->name); } +static void +rmv_uevent_callback(void *arg) +{ + struct rte_device *dev = (struct rte_device *)arg; + printf("removing device %s\n", dev->name); + if (rte_eal_dev_detach(dev)) + RTE_LOG(ERR, USER1, "Failed to detach device %s\n", + dev->name); +} + /* This function is used by the interrupt thread */ static int eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param, @@ -1883,6 +1910,41 @@ eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param, return 0; } +/* This function is used by the interrupt thread */ +static int +eth_uevent_callback(struct rte_device *dev, enum rte_eal_uevent_type type, void *param, + void *ret_param) +{ + static const char * const event_desc[] = { + [RTE_EAL_UEVENT_UNKNOWN] = "Unknown", + [RTE_EAL_UEVENT_REMOVE] = "remove", + }; + + RTE_SET_USED(param); + RTE_SET_USED(ret_param); + + if (type >= RTE_EAL_UEVENT_MAX) { + fprintf(stderr, "%s called upon invalid event %d\n", + __func__, type); + fflush(stderr); + } else if (event_print_mask & (UINT32_C(1) << type)) { + printf("%s event\n", + event_desc[type]); + fflush(stdout); + } + + switch (type) { + case RTE_EAL_UEVENT_REMOVE: + if (rte_eal_alarm_set(100000, + rmv_uevent_callback, (void *)dev)) + fprintf(stderr, "Could not set up deferred device removal\n"); + break; + default: + break; + } + return 0; +} + static int set_tx_queue_stats_mapping_registers(uint8_t port_id, struct rte_port *port) { -- 2.7.4