From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeff Guo Subject: [PATCH v5 2/2] app/testpmd: use uevent to monitor hot removal Date: Wed, 20 Sep 2017 12:12:12 +0800 Message-ID: <1505880732-16539-3-git-send-email-jia.guo@intel.com> References: <1504453785-15735-3-git-send-email-jia.guo@intel.com> <1505880732-16539-1-git-send-email-jia.guo@intel.com> Cc: konstantin.ananyev@intel.com, jblunck@infradead.org, shreyansh.jain@nxp.com, jingjing.wu@intel.com, dev@dpdk.org, jia.guo@intel.com, thomas@monjalon.net, helin.zhang@intel.com To: stephen@networkplumber.org, bruce.richardson@intel.com, ferruh.yigit@intel.com, gaetan.rivet@6wind.com Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 357D04BE1 for ; Tue, 19 Sep 2017 14:12:32 +0200 (CEST) In-Reply-To: <1505880732-16539-1-git-send-email-jia.guo@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" use testpmd for example, to show app how to request and use uevent monitoring to handle the hot removal event and the hot insertion event. Signed-off-by: Jeff Guo --- v5->v4: add new callback to process hot insertion --- app/test-pmd/testpmd.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index e097ee0..df2bb48 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -393,6 +393,9 @@ 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(enum rte_eal_dev_event_type type, + void *param, void *ret_param); + /* * Check if all the ports are started. @@ -1413,6 +1416,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_dev_event_type dev_event_type; if (port_id_is_invalid(pid, ENABLED_WARN)) return 0; @@ -1547,6 +1551,21 @@ start_port(portid_t pid) return -1; } } + rte_eal_dev_monitor_enable(); + + for (dev_event_type = RTE_EAL_DEV_EVENT_UNKNOWN; + dev_event_type < RTE_EAL_DEV_EVENT_MAX; + dev_event_type++) { + diag = rte_dev_callback_register(dev_event_type, + eth_uevent_callback, + &pi); + if (diag) { + printf("Failed to setup uevent callback for" + " device event %d\n", + dev_event_type); + return -1; + } + } /* start port */ if (rte_eth_dev_start(pi) < 0) { @@ -1883,6 +1902,35 @@ rmv_event_callback(void *arg) dev->device->name); } +static void +rmv_uevent_callback(void *arg) +{ + char name[RTE_ETH_NAME_MAX_LEN]; + + uint8_t port_id = *(uint8_t *)arg; + + printf("removing device port_id:%u\n", port_id); + + if (rte_eth_dev_detach(port_id, name)) { + RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name); + return; + } + + nb_ports = rte_eth_dev_count(); + + printf("Port '%s' is detached. Now total ports is %d\n", + name, nb_ports); +} + +static void +add_uevent_callback(void *arg) +{ + char *dev_name = (char *)arg; + + printf("adding device %s\n", dev_name); + attach_port(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, @@ -1924,6 +1972,48 @@ 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(enum rte_eal_dev_event_type type, void *arg, + void *ret_param) +{ + static const char * const event_desc[] = { + [RTE_EAL_DEV_EVENT_UNKNOWN] = "Unknown", + [RTE_EAL_DEV_EVENT_ADD] = "add", + [RTE_EAL_DEV_EVENT_REMOVE] = "remove", + }; + + RTE_SET_USED(ret_param); + + if (type >= RTE_EAL_DEV_EVENT_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_DEV_EVENT_ADD: + if (rte_eal_alarm_set(2000000, + add_uevent_callback, (void *)arg)) + fprintf(stderr, "Could not set up deferred " + "device removal\n"); + break; + case RTE_EAL_DEV_EVENT_REMOVE: + if (rte_eal_alarm_set(100000, + rmv_uevent_callback, (void *)arg)) + 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