From patchwork Mon Mar 12 13:43:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?N=C3=A9lio_Laranjeiro?= X-Patchwork-Id: 35981 X-Patchwork-Delegate: shahafs@mellanox.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 6189E5F35; Mon, 12 Mar 2018 14:44:44 +0100 (CET) Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by dpdk.org (Postfix) with ESMTP id AB51B5F1C for ; Mon, 12 Mar 2018 14:44:41 +0100 (CET) Received: by mail-wm0-f65.google.com with SMTP id z9so16176151wmb.3 for ; Mon, 12 Mar 2018 06:44:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=qP3hLccxQ0ojHhv5PxoRvxSsPTLEsjO+8OXYKKWk2oM=; b=uMfSdjGcem5TlsqsrQF8RFeydBLiwM5kpK15dkA4rl3KbZY03sJY1oG9EIcIM7P+Gj vqAen8PZFsw8DrLYZayIXD/UEeLCOU1DyD2RiDVWInMzN9h9xpBNTKKb1TIvAKcY0hLH X8a1LKTJ3QB9gtZeYaewQwT6usIZInOjiUFKmbp8DHT8Y4OPmReXo5qknCNVmnwKr4nv uXrQawMQbG/YKOoVgJI6ntpHKfN5yMz2N77wUlqVgT3YJVSRvRFpy2YrcFZCghbXmmKX Wmg198KGUNolupOxwXwmEXQ3h47260m3KEN7XuD1aM1JZfts1jNL2uaWeeoj8C3L8+fR 5sWA== 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:in-reply-to :references:in-reply-to:references; bh=qP3hLccxQ0ojHhv5PxoRvxSsPTLEsjO+8OXYKKWk2oM=; b=j/GUHvUuzMhlf5S9dZpqp8+vkh2j8wSce/m0FeI/hEXa0S/w3cI5e80yxU/xcj+Lql IPFt0R8dOwbw/DjuTdr8cCktLfxl1KPt6+opDYH1KkCrlq7g8PxvRukKtoOMSvXX33Zr pDwyxVgxpI4QDErSWx1SRJgVBHR+Z7ejKzg2i7t7Zv0xn1YNoiYJb8YuC80mgGF2OTX4 nLmIQHyGpmWpahSukUQlLKzdUX6UHXQf+NSxe4cYm/il0FRcqr5Wqk7+0aeXkNhlqxAn oVMOf7dF37z2Q3N5S8vci03etmBOCFFDYbGR1McQG6AB69DwIbYR9WgS/CanFQcEYQtV sZpg== X-Gm-Message-State: AElRT7FNDnxHxUu9aYr77kCCquaKh2GwFy+BztHzSAu7QDZ63yc8DP2z wSZ10nlHxiY1iyu5m8mltulEgh7Vig== X-Google-Smtp-Source: AG47ELufmDCL3bdzyUWX19reBN1NW1HxU79O1t+w+avxwKiDWTygrQpx2KeeWA01VmKO2oPKKWGreQ== X-Received: by 10.28.40.195 with SMTP id o186mr5532998wmo.134.1520862281233; Mon, 12 Mar 2018 06:44:41 -0700 (PDT) Received: from laranjeiro-vm.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id y1sm6569198wrh.80.2018.03.12.06.44.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Mar 2018 06:44:40 -0700 (PDT) From: Nelio Laranjeiro To: dev@dpdk.org Cc: Adrien Mazarguil , Yongseok Koh , shahafs@mellanox.com, stable@dpdk.org Date: Mon, 12 Mar 2018 14:43:19 +0100 Message-Id: X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: <21fb91002768a627d9c7f3d81e0c8a12fbf6811f.1518684427.git.nelio.laranjeiro@6wind.com> Subject: [dpdk-dev] [PATCH v2 3/3] net/mlx5: fix link status to use wait to complete 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" Wait to complete is present to let the application get a correct status when it requires it, it should not be ignored. Fixes: e313ef4c2fe8 ("net/mlx5: fix link state on device start") Fixes: cb8faed7dde8 ("mlx5: support link status update") Cc: shahafs@mellanox.com Cc: adrien.mazarguil@6wind.com Cc: stable@dpdk.org Signed-off-by: Nelio Laranjeiro Acked-by: Adrien Mazarguil --- drivers/net/mlx5/mlx5.h | 1 - drivers/net/mlx5/mlx5_defs.h | 4 +- drivers/net/mlx5/mlx5_ethdev.c | 147 ++++++++++++++++------------------------- 3 files changed, 58 insertions(+), 94 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 86310404a..faacfd9d6 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -124,7 +124,6 @@ struct priv { /* Device properties. */ uint16_t mtu; /* Configured MTU. */ uint8_t port; /* Physical port number. */ - unsigned int pending_alarm:1; /* An alarm is pending. */ unsigned int isolated:1; /* Whether isolated mode is enabled. */ /* RX/TX queues. */ unsigned int rxqs_n; /* RX queues array size. */ diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h index c3334ca30..6401588ee 100644 --- a/drivers/net/mlx5/mlx5_defs.h +++ b/drivers/net/mlx5/mlx5_defs.h @@ -82,8 +82,8 @@ /* Supported RSS */ #define MLX5_RSS_HF_MASK (~(ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP)) -/* Maximum number of attempts to query link status before giving up. */ -#define MLX5_MAX_LINK_QUERY_ATTEMPTS 5 +/* Timeout in seconds to get a valid link status. */ +#define MLX5_LINK_STATUS_TIMEOUT 10 /* Reserved address space for UAR mapping. */ #define MLX5_UAR_SIZE (1ULL << 32) diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 10ba27c79..f219f2ccd 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -31,7 +32,6 @@ #include #include #include -#include #include #include "mlx5.h" @@ -473,12 +473,15 @@ mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev) * * @param dev * Pointer to Ethernet device structure. + * @param[out] link + * Storage for current link status. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev) +mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, + struct rte_eth_link *link) { struct priv *priv = dev->data->dev_private; struct ethtool_cmd edata = { @@ -528,14 +531,13 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev) ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX); dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); - if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) { - /* Link status changed. */ - dev->data->dev_link = dev_link; - return 0; + if ((dev_link.link_speed && !dev_link.link_status) || + (!dev_link.link_speed && dev_link.link_status)) { + rte_errno = EAGAIN; + return -rte_errno; } - /* Link status is still the same. */ - rte_errno = EAGAIN; - return -rte_errno; + *link = dev_link; + return 0; } /** @@ -543,12 +545,16 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev) * * @param dev * Pointer to Ethernet device structure. + * @param[out] link + * Storage for current link status. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev) +mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, + struct rte_eth_link *link) + { struct priv *priv = dev->data->dev_private; struct ethtool_link_settings gcmd = { .cmd = ETHTOOL_GLINKSETTINGS }; @@ -634,14 +640,13 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev) ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX); dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED); - if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) { - /* Link status changed. */ - dev->data->dev_link = dev_link; - return 0; + if ((dev_link.link_speed && !dev_link.link_status) || + (!dev_link.link_speed && dev_link.link_status)) { + rte_errno = EAGAIN; + return -rte_errno; } - /* Link status is still the same. */ - rte_errno = EAGAIN; - return -rte_errno; + *link = dev_link; + return 0; } /** @@ -650,20 +655,43 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev) * @param dev * Pointer to Ethernet device structure. * @param wait_to_complete - * Wait for request completion (ignored). + * Wait for request completion. * * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. + * 0 if link status was not updated, positive if it was, a negative errno + * value otherwise and rte_errno is set.* */ int -mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) +mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) { int ret; + struct rte_eth_link dev_link; + time_t start_time = time(NULL); - ret = mlx5_link_update_unlocked_gset(dev); - if (ret) - ret = mlx5_link_update_unlocked_gs(dev); - return 0; + do { + ret = mlx5_link_update_unlocked_gset(dev, &dev_link); + if (ret) + ret = mlx5_link_update_unlocked_gs(dev, &dev_link); + if (ret == 0) + break; + /* Handle wait to complete situation. */ + if (wait_to_complete && ret == -EAGAIN) { + if (abs((int)difftime(time(NULL), start_time)) < + MLX5_LINK_STATUS_TIMEOUT) { + usleep(0); + continue; + } else { + rte_errno = EBUSY; + return -rte_errno; + } + } else if (ret < 0) { + return ret; + } + } while (wait_to_complete); + ret = !!memcmp(&dev->data->dev_link, &dev_link, + sizeof(struct rte_eth_link)); + dev->data->dev_link = dev_link; + return ret; } /** @@ -842,47 +870,6 @@ mlx5_ibv_device_to_pci_addr(const struct ibv_device *device, } /** - * Update the link status. - * - * @param dev - * Pointer to Ethernet device. - * - * @return - * Zero if the callback process can be called immediately, negative errno - * value otherwise and rte_errno is set. - */ -static int -mlx5_link_status_update(struct rte_eth_dev *dev) -{ - struct priv *priv = dev->data->dev_private; - struct rte_eth_link *link = &dev->data->dev_link; - int ret; - - ret = mlx5_link_update(dev, 0); - if (ret) - return ret; - if (((link->link_speed == 0) && link->link_status) || - ((link->link_speed != 0) && !link->link_status)) { - /* - * Inconsistent status. Event likely occurred before the - * kernel netdevice exposes the new status. - */ - if (!priv->pending_alarm) { - priv->pending_alarm = 1; - rte_eal_alarm_set(MLX5_ALARM_TIMEOUT_US, - mlx5_dev_link_status_handler, - priv->dev); - } - return 1; - } else if (unlikely(priv->pending_alarm)) { - /* Link interrupt occurred while alarm is already scheduled. */ - priv->pending_alarm = 0; - rte_eal_alarm_cancel(mlx5_dev_link_status_handler, priv->dev); - } - return 0; -} - -/** * Device status handler. * * @param dev @@ -900,6 +887,10 @@ mlx5_dev_status_handler(struct rte_eth_dev *dev) struct ibv_async_event event; uint32_t ret = 0; + if (mlx5_link_update(dev, 0) == -EAGAIN) { + usleep(0); + return 0; + } /* Read all message and acknowledge them. */ for (;;) { if (mlx5_glue->get_async_event(priv->ctx, &event)) @@ -917,32 +908,10 @@ mlx5_dev_status_handler(struct rte_eth_dev *dev) dev->data->port_id, event.event_type); mlx5_glue->ack_async_event(&event); } - if (ret & (1 << RTE_ETH_EVENT_INTR_LSC)) - if (mlx5_link_status_update(dev)) - ret &= ~(1 << RTE_ETH_EVENT_INTR_LSC); return ret; } /** - * Handle delayed link status event. - * - * @param arg - * Registered argument. - */ -void -mlx5_dev_link_status_handler(void *arg) -{ - struct rte_eth_dev *dev = arg; - struct priv *priv = dev->data->dev_private; - int ret; - - priv->pending_alarm = 0; - ret = mlx5_link_status_update(dev); - if (!ret) - _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); -} - -/** * Handle interrupts from the NIC. * * @param[in] intr_handle @@ -995,10 +964,6 @@ mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev) if (priv->primary_socket) rte_intr_callback_unregister(&priv->intr_handle_socket, mlx5_dev_handler_socket, dev); - if (priv->pending_alarm) { - priv->pending_alarm = 0; - rte_eal_alarm_cancel(mlx5_dev_link_status_handler, dev); - } priv->intr_handle.fd = 0; priv->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; priv->intr_handle_socket.fd = 0;