From patchwork Wed May 9 12:47:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Krawczyk X-Patchwork-Id: 39583 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 143D31B634; Wed, 9 May 2018 14:47:26 +0200 (CEST) Received: from mail-lf0-f68.google.com (mail-lf0-f68.google.com [209.85.215.68]) by dpdk.org (Postfix) with ESMTP id 5B60E1B3EB for ; Wed, 9 May 2018 14:47:24 +0200 (CEST) Received: by mail-lf0-f68.google.com with SMTP id z142-v6so7489208lff.5 for ; Wed, 09 May 2018 05:47:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=ETxn2hoom61GeJ0IUbJVQurBeftvu7AsOa1oQrlKdjE=; b=bSjwMFy7CGymGauJ/Hk4jtXKEtz+4Qw+ekVIXX9J7oqG7gQKCVqqH7F8/bvr/bA6zU kQAjK5+cEejCc1/7r2Y7rcFA8eL97YeE0IJ6oklg6sGbuySt1BrzSqdHT5YhHgXJZisr 3wmUrVVG7HmV/w26gt4cGEDqKERtERvP4pu2QhOzQYy8QvNnV7T7Iulw529R43S0aY/O Z/fst9n2nIW2+opA49IR/PqYETCvewfT9fF5QLa70PFmFDTHdEbRKKEze6Xky668E/h1 uBcDwLCMsaB9vimGD8I+7EIHyXs7kwpqgDeiedxbTvWymkrLf+kpnwvPEg4Z0P9uOKX5 PWOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ETxn2hoom61GeJ0IUbJVQurBeftvu7AsOa1oQrlKdjE=; b=ppEUDZ6ypKeIbJd/KsiXVaK0I8LQAehRFJ4tlo0ueCxCw+Bglusq6YU4qSwKD6e5SO KAoC+GfbK0BGHFrvVJboIhHYfO1j+VRb/RAgxIoroRufZ8N9pAvUEBR/tHBmsy/+MAZ9 Hy6lv+/JmAMZeJDymHH6tuD+yTNjQKnUEg5lZja1jnzJtkf5ssS9D7qLZB3vlKaodD57 dM7WhhSQiifazXpkRbqjtZWr3wDBGLzl7kk/gNQfAOTM6VXTrFg5BR8yRrLUnaJpl9i4 vH4AqB9VJISfLwKROl3UrzPQ17QPXS5Mfs581CVhAggGrbgqQIICsNLf3L0Ugr8VWSro QGLA== X-Gm-Message-State: ALQs6tCZWbMoE11Tw5KOjW6HuU7DyV6CVYfI7A9KRJBzhBHfu1qrgzw8 kFOjeHJJXXVEOd/V5kSFbD3hrQ== X-Google-Smtp-Source: AB8JxZoxb1nAy/8TXN7fPj8Ejdm66xrZ97XboFT2jNt01tWO29f4O2wSprmAPQoL5j3WCBPenDT97A== X-Received: by 2002:a19:9389:: with SMTP id w9-v6mr27937000lfk.75.1525870043983; Wed, 09 May 2018 05:47:23 -0700 (PDT) Received: from mkPC.semihalf.local (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id l10-v6sm5149258lja.62.2018.05.09.05.47.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 May 2018 05:47:23 -0700 (PDT) From: Michal Krawczyk To: Marcin Wojtas , Michal Krawczyk , Guy Tzalik , Evgeny Schemeilin Cc: dev@dpdk.org, matua@amazon.com Date: Wed, 9 May 2018 14:47:00 +0200 Message-Id: <20180509124714.23305-1-mk@semihalf.com> X-Mailer: git-send-email 2.14.1 Subject: [dpdk-dev] [PATCH v1 10/24] net/ena: add watchdog and keep alive AENQ handler 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Keep alive is executing AENQ interrupt periodically. It allows to check health of the device and trigger reset event if the device will stop responding. To check for the state of the device, the DPDK application must call rte_timer_manage(). Signed-off-by: Michal Krawczyk --- drivers/net/ena/ena_ethdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++-- drivers/net/ena/ena_ethdev.h | 9 +++++++ 2 files changed, 65 insertions(+), 2 deletions(-) -- 2.14.1 diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c index 160fcf04a..3956ec379 100644 --- a/drivers/net/ena/ena_ethdev.c +++ b/drivers/net/ena/ena_ethdev.c @@ -253,6 +253,7 @@ static bool ena_are_tx_queue_offloads_allowed(struct ena_adapter *adapter, static bool ena_are_rx_queue_offloads_allowed(struct ena_adapter *adapter, uint64_t offloads); static void ena_interrupt_handler_rte(void *cb_arg); +static void ena_timer_wd_callback(struct rte_timer *timer, void *arg); static const struct eth_dev_ops ena_dev_ops = { .dev_configure = ena_dev_configure, @@ -983,6 +984,7 @@ static int ena_start(struct rte_eth_dev *dev) { struct ena_adapter *adapter = (struct ena_adapter *)(dev->data->dev_private); + uint64_t ticks; int rc = 0; rc = ena_check_valid_conf(adapter); @@ -1006,6 +1008,13 @@ static int ena_start(struct rte_eth_dev *dev) ena_stats_restart(dev); + adapter->timestamp_wd = rte_get_timer_cycles(); + adapter->keep_alive_timeout = ENA_DEVICE_KALIVE_TIMEOUT; + + ticks = rte_get_timer_hz(); + rte_timer_reset(&adapter->timer_wd, ticks, PERIODICAL, rte_lcore_id(), + ena_timer_wd_callback, adapter); + adapter->state = ENA_ADAPTER_STATE_RUNNING; return 0; @@ -1016,6 +1025,8 @@ static void ena_stop(struct rte_eth_dev *dev) struct ena_adapter *adapter = (struct ena_adapter *)(dev->data->dev_private); + rte_timer_stop_sync(&adapter->timer_wd); + adapter->state = ENA_ADAPTER_STATE_STOPPED; } @@ -1377,7 +1388,8 @@ static int ena_device_init(struct ena_com_dev *ena_dev, } aenq_groups = BIT(ENA_ADMIN_LINK_CHANGE) | - BIT(ENA_ADMIN_NOTIFICATION); + BIT(ENA_ADMIN_NOTIFICATION) | + BIT(ENA_ADMIN_KEEP_ALIVE); aenq_groups &= get_feat_ctx->aenq.supported_groups; rc = ena_com_set_aenq_config(ena_dev, aenq_groups); @@ -1407,6 +1419,26 @@ static void ena_interrupt_handler_rte(void *cb_arg) ena_com_aenq_intr_handler(ena_dev, adapter); } +static void ena_timer_wd_callback(__rte_unused struct rte_timer *timer, + void *arg) +{ + struct ena_adapter *adapter = (struct ena_adapter *)arg; + struct rte_eth_dev *dev = adapter->rte_dev; + + if (adapter->keep_alive_timeout == ENA_HW_HINTS_NO_TIMEOUT) + return; + + /* Within reasonable timing range no memory barriers are needed */ + if ((rte_get_timer_cycles() - adapter->timestamp_wd) >= + adapter->keep_alive_timeout) { + RTE_LOG(ERR, PMD, "The ENA device is not responding - " + "performing device reset..."); + adapter->reset_reason = ENA_REGS_RESET_KEEP_ALIVE_TO; + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, + NULL); + } +} + static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev; @@ -1509,6 +1541,10 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) ena_com_set_admin_polling_mode(ena_dev, false); ena_com_admin_aenq_enable(ena_dev); + if (adapters_found == 0) + rte_timer_subsystem_init(); + rte_timer_init(&adapter->timer_wd); + adapters_found++; adapter->state = ENA_ADAPTER_STATE_INIT; @@ -1864,6 +1900,16 @@ static void ena_update_hints(struct ena_adapter *adapter, /* convert to usec */ adapter->ena_dev.mmio_read.reg_read_to = hints->mmio_read_timeout * 1000; + + if (hints->driver_watchdog_timeout) { + if (hints->driver_watchdog_timeout == ENA_HW_HINTS_NO_TIMEOUT) + adapter->keep_alive_timeout = ENA_HW_HINTS_NO_TIMEOUT; + else + // Convert msecs to ticks + adapter->keep_alive_timeout = + (hints->driver_watchdog_timeout * + rte_get_timer_hz()) / 1000; + } } static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, @@ -2084,6 +2130,14 @@ static void ena_notification(void *data, } } +static void ena_keep_alive(void *adapter_data, + __rte_unused struct ena_admin_aenq_entry *aenq_e) +{ + struct ena_adapter *adapter = (struct ena_adapter *)adapter_data; + + adapter->timestamp_wd = rte_get_timer_cycles(); +} + /** * This handler will called for unknown event group or unimplemented handlers **/ @@ -2097,7 +2151,7 @@ static struct ena_aenq_handlers aenq_handlers = { .handlers = { [ENA_ADMIN_LINK_CHANGE] = ena_update_on_link_change, [ENA_ADMIN_NOTIFICATION] = ena_notification, - [ENA_ADMIN_KEEP_ALIVE] = unimplemented_aenq_handler + [ENA_ADMIN_KEEP_ALIVE] = ena_keep_alive }, .unimplemented_handler = unimplemented_aenq_handler }; diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h index 79e9e655d..b44cca23e 100644 --- a/drivers/net/ena/ena_ethdev.h +++ b/drivers/net/ena/ena_ethdev.h @@ -34,8 +34,10 @@ #ifndef _ENA_ETHDEV_H_ #define _ENA_ETHDEV_H_ +#include #include #include +#include #include "ena_com.h" @@ -50,6 +52,9 @@ #define ENA_MMIO_DISABLE_REG_READ BIT(0) +#define ENA_WD_TIMEOUT_SEC 3 +#define ENA_DEVICE_KALIVE_TIMEOUT (ENA_WD_TIMEOUT_SEC * rte_get_timer_hz()) + struct ena_adapter; enum ena_ring_type { @@ -185,6 +190,10 @@ struct ena_adapter { bool link_status; enum ena_regs_reset_reason_types reset_reason; + + struct rte_timer timer_wd; + uint64_t timestamp_wd; + uint64_t keep_alive_timeout; }; #endif /* _ENA_ETHDEV_H_ */