From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A1A07A0518 for ; Fri, 24 Jul 2020 14:01:17 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 97B401C02A; Fri, 24 Jul 2020 14:01:17 +0200 (CEST) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by dpdk.org (Postfix) with ESMTP id 950971C044 for ; Fri, 24 Jul 2020 14:01:16 +0200 (CEST) Received: by mail-wr1-f68.google.com with SMTP id r4so5107655wrx.9 for ; Fri, 24 Jul 2020 05:01:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I/TvXHHWEYeXVB0RKj/I27Iz5Cm+QO1vzCVvw/rUHHk=; b=oUf+sDA65rVezsHT7g9tIDTxaY4kAMyx8KtSt22dQmLsGtELRR3KuEkQCbzxhvZC3A YJsv8KhPqbPlzvS0r44hayDasB8hAlKnAcI+lnc1DE0NJuExvwWCdk7g71GUJyXj/HMo QJqziwPLfntgTMauhPllxUIya1d0yZaKRplQlY6XyYhRuTS6Azv3jlb+LmgDrgRX7ZCC LcEQoLtVL5ukRSPz0KcasHwhtkwxyWd3j+jkaiC/zII7Hr+Djw47pCqUczqxYv2OIqEe t0xqn5EPMPjkV7gskRWIqau2f3c027yKqq5/BvBmWMhtMir0Yl6tjuCgwTIacgMHYh35 qOQQ== 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:mime-version:content-transfer-encoding; bh=I/TvXHHWEYeXVB0RKj/I27Iz5Cm+QO1vzCVvw/rUHHk=; b=Vz4sF8QZ4zKImSQkM98IwO317LNcOXugELwSXdB+41OehPcgtlLvuvmF/oqcPG1mXG 7zGjV6sHgKNz/sGhxRvSWmjPn9aQ+ncEgvroxi7RCpPnORLjMVpLEnAXklPLe8TSlO9S wY2LfGAoEv5EBa2WyEGQSfoX+EJXHTxF+UL6c8TgNGmUL9gm+xsNt1wLd0Fee7B8FUBX t40ZZnR3sfsyPfrWfGdk+E7F+MrAZFdafLKHC5MevZ8wLugTxk0t4AhpvM9KJqSNivNi 412WFuksBkdfmbhqFl2UaBCil8syYwjg7N5MQ3dGVre2HAAjC1FNYuIxHblcy782hCEx kbVQ== X-Gm-Message-State: AOAM533rViAu0h2Kfx7Fb0UJdjHaTbLNMNLmGIeZ7UN8tXp8IH/Mftqw LSnyqyXzcDKlJ24ji69LUmwQBIk62XA= X-Google-Smtp-Source: ABdhPJzI+tI0xJhRy91bE/34ULWNB8wtcWHdRKWfhI1yz8aEvPmfuWs0ss/rKYHoaxQsJe6yuZ4ibQ== X-Received: by 2002:a5d:6692:: with SMTP id l18mr8235113wru.211.1595592076198; Fri, 24 Jul 2020 05:01:16 -0700 (PDT) Received: from localhost ([88.98.246.218]) by smtp.gmail.com with ESMTPSA id p17sm6575891wma.47.2020.07.24.05.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2020 05:01:15 -0700 (PDT) From: luca.boccassi@gmail.com To: Suanming Mou Cc: Matan Azrad , dpdk stable Date: Fri, 24 Jul 2020 12:57:33 +0100 Message-Id: <20200724120030.1863487-15-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200724120030.1863487-1-luca.boccassi@gmail.com> References: <20200724120030.1863487-1-luca.boccassi@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-stable] patch 'net/mlx5: fix interrupt installation timing' has been queued to stable release 19.11.4 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Hi, FYI, your patch has been queued to stable release 19.11.4 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 07/26/20. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasing (ie: not only metadata diffs), please double check that the rebase was correctly done. Thanks. Luca Boccassi --- >From 5da51166d7493f5a99724d8c424c4a9c2eb5b760 Mon Sep 17 00:00:00 2001 From: Suanming Mou Date: Thu, 28 May 2020 17:22:09 +0800 Subject: [PATCH] net/mlx5: fix interrupt installation timing [ upstream commit 33860cfab62ed9a3673b1077899c1c527b09e385 ] Currently, the DevX counter query works asynchronously with Devx interrupt handler return the query result. When port closes, the interrupt handler will be uninstalled and the Devx comp obj will also be destroyed. Meanwhile the query is still not cancelled. In this case, counter query may use the invalid Devx comp which has been destroyed, and query failure with invalid FD will be reported. Adjust the shared interrupt install and uninstall timing to make the counter asynchronous query stop before interrupt uninstall. Fixes: f15db67df09c ("net/mlx5: accelerate DV flow counter query") Signed-off-by: Suanming Mou Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5.c | 101 ++++++++++--- drivers/net/mlx5/mlx5.h | 5 - drivers/net/mlx5/mlx5_ethdev.c | 243 -------------------------------- drivers/net/mlx5/mlx5_trigger.c | 16 ++- 4 files changed, 96 insertions(+), 269 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 1e34f6263..bb718f27f 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -470,6 +471,85 @@ mlx5_restore_doorbell_mapping_env(int value) setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1); } +/** + * Install shared asynchronous device events handler. + * This function is implemented to support event sharing + * between multiple ports of single IB device. + * + * @param sh + * Pointer to mlx5_ibv_shared object. + */ +static void +mlx5_dev_shared_handler_install(struct mlx5_ibv_shared *sh) +{ + int ret; + int flags; + + sh->intr_handle.fd = -1; + flags = fcntl(sh->ctx->async_fd, F_GETFL); + ret = fcntl(sh->ctx->async_fd, F_SETFL, flags | O_NONBLOCK); + if (ret) { + DRV_LOG(INFO, "failed to change file descriptor async event" + " queue"); + } else { + sh->intr_handle.fd = sh->ctx->async_fd; + sh->intr_handle.type = RTE_INTR_HANDLE_EXT; + if (rte_intr_callback_register(&sh->intr_handle, + mlx5_dev_interrupt_handler, sh)) { + DRV_LOG(INFO, "Fail to install the shared interrupt."); + sh->intr_handle.fd = -1; + } + } + if (sh->devx) { +#ifdef HAVE_IBV_DEVX_ASYNC + sh->intr_handle_devx.fd = -1; + sh->devx_comp = mlx5_glue->devx_create_cmd_comp(sh->ctx); + if (!sh->devx_comp) { + DRV_LOG(INFO, "failed to allocate devx_comp."); + return; + } + flags = fcntl(sh->devx_comp->fd, F_GETFL); + ret = fcntl(sh->devx_comp->fd, F_SETFL, flags | O_NONBLOCK); + if (ret) { + DRV_LOG(INFO, "failed to change file descriptor" + " devx comp"); + return; + } + sh->intr_handle_devx.fd = sh->devx_comp->fd; + sh->intr_handle_devx.type = RTE_INTR_HANDLE_EXT; + if (rte_intr_callback_register(&sh->intr_handle_devx, + mlx5_dev_interrupt_handler_devx, sh)) { + DRV_LOG(INFO, "Fail to install the devx shared" + " interrupt."); + sh->intr_handle_devx.fd = -1; + } +#endif /* HAVE_IBV_DEVX_ASYNC */ + } +} + +/** + * Uninstall shared asynchronous device events handler. + * This function is implemented to support event sharing + * between multiple ports of single IB device. + * + * @param dev + * Pointer to mlx5_ibv_shared object. + */ +static void +mlx5_dev_shared_handler_uninstall(struct mlx5_ibv_shared *sh) +{ + if (sh->intr_handle.fd >= 0) + mlx5_intr_callback_unregister(&sh->intr_handle, + mlx5_dev_interrupt_handler, sh); +#ifdef HAVE_IBV_DEVX_ASYNC + if (sh->intr_handle_devx.fd >= 0) + rte_intr_callback_unregister(&sh->intr_handle_devx, + mlx5_dev_interrupt_handler_devx, sh); + if (sh->devx_comp) + mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp); +#endif +} + /** * Allocate shared IB device context. If there is multiport device the * master and representors will share this context, if there is single @@ -564,7 +644,6 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, sizeof(sh->ibdev_name)); strncpy(sh->ibdev_path, sh->ctx->device->ibdev_path, sizeof(sh->ibdev_path)); - pthread_mutex_init(&sh->intr_mutex, NULL); /* * Setting port_id to max unallowed value means * there is no interrupt subhandler installed for @@ -624,6 +703,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, err = rte_errno; goto error; } + mlx5_dev_shared_handler_install(sh); mlx5_flow_counters_mng_init(sh); /* Add device to memory callback list. */ rte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock); @@ -697,20 +777,7 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) * Only primary process handles async device events. **/ mlx5_flow_counters_mng_close(sh); - assert(!sh->intr_cnt); - if (sh->intr_cnt) - mlx5_intr_callback_unregister - (&sh->intr_handle, mlx5_dev_interrupt_handler, sh); -#ifdef HAVE_MLX5_DEVX_ASYNC_SUPPORT - if (sh->devx_intr_cnt) { - if (sh->intr_handle_devx.fd) - rte_intr_callback_unregister(&sh->intr_handle_devx, - mlx5_dev_interrupt_handler_devx, sh); - if (sh->devx_comp) - mlx5dv_devx_destroy_cmd_comp(sh->devx_comp); - } -#endif - pthread_mutex_destroy(&sh->intr_mutex); + mlx5_dev_shared_handler_uninstall(sh); if (sh->pd) claim_zero(mlx5_glue->dealloc_pd(sh->pd)); if (sh->tis) @@ -1248,9 +1315,6 @@ mlx5_dev_close(struct rte_eth_dev *dev) DRV_LOG(DEBUG, "port %u closing device \"%s\"", dev->data->port_id, ((priv->sh->ctx != NULL) ? priv->sh->ctx->device->name : "")); - /* In case mlx5_dev_stop() has not been called. */ - mlx5_dev_interrupt_handler_uninstall(dev); - mlx5_dev_interrupt_handler_devx_uninstall(dev); mlx5_traffic_disable(dev); mlx5_flow_flush(dev, NULL); mlx5_flow_meter_flush(dev, NULL); @@ -3362,7 +3426,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, rte_eth_copy_pci_info(list[i].eth_dev, pci_dev); /* Restore non-PCI flags cleared by the above call. */ list[i].eth_dev->data->dev_flags |= restore; - mlx5_dev_interrupt_handler_devx_install(list[i].eth_dev); rte_eth_dev_probing_finish(list[i].eth_dev); } if (i != ns) { diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index e4af5d40d..e53934d45 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -682,10 +682,7 @@ struct mlx5_ibv_shared { push_vlan_action_list; /* List of push VLAN actions. */ struct mlx5_flow_counter_mng cmng; /* Counters management structure. */ /* Shared interrupt handler section. */ - pthread_mutex_t intr_mutex; /* Interrupt config mutex. */ - uint32_t intr_cnt; /* Interrupt handler reference counter. */ struct rte_intr_handle intr_handle; /* Interrupt handler for device. */ - uint32_t devx_intr_cnt; /* Devx interrupt handler reference counter. */ struct rte_intr_handle intr_handle_devx; /* DEVX interrupt handler. */ struct mlx5dv_devx_cmd_comp *devx_comp; /* DEVX async comp obj. */ struct mlx5_devx_obj *tis; /* TIS object. */ @@ -838,8 +835,6 @@ void mlx5_dev_interrupt_handler(void *arg); void mlx5_dev_interrupt_handler_devx(void *arg); void mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev); void mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev); -void mlx5_dev_interrupt_handler_devx_uninstall(struct rte_eth_dev *dev); -void mlx5_dev_interrupt_handler_devx_install(struct rte_eth_dev *dev); int mlx5_set_link_down(struct rte_eth_dev *dev); int mlx5_set_link_up(struct rte_eth_dev *dev); int mlx5_is_removed(struct rte_eth_dev *dev); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 3b4c5dbe7..3b1f18b3f 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -1475,249 +1475,6 @@ mlx5_dev_interrupt_handler_devx(void *cb_arg) #endif /* HAVE_IBV_DEVX_ASYNC */ } -/** - * Uninstall shared asynchronous device events handler. - * This function is implemented to support event sharing - * between multiple ports of single IB device. - * - * @param dev - * Pointer to Ethernet device. - */ -static void -mlx5_dev_shared_handler_uninstall(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_ibv_shared *sh = priv->sh; - - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); - assert(priv->ibv_port); - assert(priv->ibv_port <= sh->max_port); - assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].ih_port_id >= RTE_MAX_ETHPORTS) - goto exit; - assert(sh->port[priv->ibv_port - 1].ih_port_id == - (uint32_t)dev->data->port_id); - assert(sh->intr_cnt); - sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; - if (!sh->intr_cnt || --sh->intr_cnt) - goto exit; - mlx5_intr_callback_unregister(&sh->intr_handle, - mlx5_dev_interrupt_handler, sh); - sh->intr_handle.fd = 0; - sh->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; -exit: - pthread_mutex_unlock(&sh->intr_mutex); -} - -/** - * Uninstall devx shared asynchronous device events handler. - * This function is implemeted to support event sharing - * between multiple ports of single IB device. - * - * @param dev - * Pointer to Ethernet device. - */ -static void -mlx5_dev_shared_handler_devx_uninstall(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_ibv_shared *sh = priv->sh; - - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); - assert(priv->ibv_port); - assert(priv->ibv_port <= sh->max_port); - assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].devx_ih_port_id >= RTE_MAX_ETHPORTS) - goto exit; - assert(sh->port[priv->ibv_port - 1].devx_ih_port_id == - (uint32_t)dev->data->port_id); - sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS; - if (!sh->devx_intr_cnt || --sh->devx_intr_cnt) - goto exit; - if (sh->intr_handle_devx.fd) { - rte_intr_callback_unregister(&sh->intr_handle_devx, - mlx5_dev_interrupt_handler_devx, - sh); - sh->intr_handle_devx.fd = 0; - sh->intr_handle_devx.type = RTE_INTR_HANDLE_UNKNOWN; - } - if (sh->devx_comp) { - mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp); - sh->devx_comp = NULL; - } -exit: - pthread_mutex_unlock(&sh->intr_mutex); -} - -/** - * Install shared asynchronous device events handler. - * This function is implemented to support event sharing - * between multiple ports of single IB device. - * - * @param dev - * Pointer to Ethernet device. - */ -static void -mlx5_dev_shared_handler_install(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_ibv_shared *sh = priv->sh; - int ret; - int flags; - - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); - assert(priv->ibv_port); - assert(priv->ibv_port <= sh->max_port); - assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].ih_port_id < RTE_MAX_ETHPORTS) { - /* The handler is already installed for this port. */ - assert(sh->intr_cnt); - goto exit; - } - if (sh->intr_cnt) { - sh->port[priv->ibv_port - 1].ih_port_id = - (uint32_t)dev->data->port_id; - sh->intr_cnt++; - goto exit; - } - /* No shared handler installed. */ - assert(sh->ctx->async_fd > 0); - flags = fcntl(sh->ctx->async_fd, F_GETFL); - ret = fcntl(sh->ctx->async_fd, F_SETFL, flags | O_NONBLOCK); - if (ret) { - DRV_LOG(INFO, "failed to change file descriptor async event" - " queue"); - /* Indicate there will be no interrupts. */ - dev->data->dev_conf.intr_conf.lsc = 0; - dev->data->dev_conf.intr_conf.rmv = 0; - } else { - sh->intr_handle.fd = sh->ctx->async_fd; - sh->intr_handle.type = RTE_INTR_HANDLE_EXT; - rte_intr_callback_register(&sh->intr_handle, - mlx5_dev_interrupt_handler, sh); - sh->intr_cnt++; - sh->port[priv->ibv_port - 1].ih_port_id = - (uint32_t)dev->data->port_id; - } -exit: - pthread_mutex_unlock(&sh->intr_mutex); -} - -/** - * Install devx shared asyncronous device events handler. - * This function is implemeted to support event sharing - * between multiple ports of single IB device. - * - * @param dev - * Pointer to Ethernet device. - */ -static void -mlx5_dev_shared_handler_devx_install(struct rte_eth_dev *dev) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_ibv_shared *sh = priv->sh; - - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); - assert(priv->ibv_port); - assert(priv->ibv_port <= sh->max_port); - assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].devx_ih_port_id < RTE_MAX_ETHPORTS) { - /* The handler is already installed for this port. */ - assert(sh->devx_intr_cnt); - goto exit; - } - if (sh->devx_intr_cnt) { - sh->devx_intr_cnt++; - sh->port[priv->ibv_port - 1].devx_ih_port_id = - (uint32_t)dev->data->port_id; - goto exit; - } - if (priv->config.devx) { -#ifndef HAVE_IBV_DEVX_ASYNC - goto exit; -#else - sh->devx_comp = mlx5_glue->devx_create_cmd_comp(sh->ctx); - if (sh->devx_comp) { - int flags = fcntl(sh->devx_comp->fd, F_GETFL); - int ret = fcntl(sh->devx_comp->fd, F_SETFL, - flags | O_NONBLOCK); - - if (ret) { - DRV_LOG(INFO, "failed to change file descriptor" - " devx async event queue"); - } else { - sh->intr_handle_devx.fd = sh->devx_comp->fd; - sh->intr_handle_devx.type = RTE_INTR_HANDLE_EXT; - rte_intr_callback_register - (&sh->intr_handle_devx, - mlx5_dev_interrupt_handler_devx, sh); - sh->devx_intr_cnt++; - sh->port[priv->ibv_port - 1].devx_ih_port_id = - (uint32_t)dev->data->port_id; - } - } -#endif /* HAVE_IBV_DEVX_ASYNC */ - } -exit: - pthread_mutex_unlock(&sh->intr_mutex); -} - -/** - * Uninstall interrupt handler. - * - * @param dev - * Pointer to Ethernet device. - */ -void -mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev) -{ - mlx5_dev_shared_handler_uninstall(dev); -} - -/** - * Install interrupt handler. - * - * @param dev - * Pointer to Ethernet device. - */ -void -mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev) -{ - mlx5_dev_shared_handler_install(dev); -} - -/** - * Devx uninstall interrupt handler. - * - * @param dev - * Pointer to Ethernet device. - */ -void -mlx5_dev_interrupt_handler_devx_uninstall(struct rte_eth_dev *dev) -{ - mlx5_dev_shared_handler_devx_uninstall(dev); -} - -/** - * Devx install interrupt handler. - * - * @param dev - * Pointer to Ethernet device. - */ -void -mlx5_dev_interrupt_handler_devx_install(struct rte_eth_dev *dev) -{ - mlx5_dev_shared_handler_devx_install(dev); -} - /** * DPDK callback to bring the link DOWN. * diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index 6fc4190f4..04b06e11d 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -327,7 +327,18 @@ mlx5_dev_start(struct rte_eth_dev *dev) dev->rx_pkt_burst = mlx5_select_rx_function(dev); /* Enable datapath on secondary process. */ mlx5_mp_req_start_rxtx(dev); - mlx5_dev_interrupt_handler_install(dev); + if (priv->sh->intr_handle.fd >= 0) { + priv->sh->port[priv->ibv_port - 1].ih_port_id = + (uint32_t)dev->data->port_id; + } else { + DRV_LOG(INFO, "port %u starts without LSC and RMV interrupts.", + dev->data->port_id); + dev->data->dev_conf.intr_conf.lsc = 0; + dev->data->dev_conf.intr_conf.rmv = 0; + } + if (priv->sh->intr_handle_devx.fd >= 0) + priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = + (uint32_t)dev->data->port_id; return 0; error: ret = rte_errno; /* Save rte_errno before cleanup. */ @@ -366,7 +377,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev) mlx5_flow_stop(dev, &priv->flows); mlx5_traffic_disable(dev); mlx5_rx_intr_vec_disable(dev); - mlx5_dev_interrupt_handler_uninstall(dev); + priv->sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; + priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS; mlx5_txq_stop(dev); mlx5_rxq_stop(dev); } -- 2.20.1 --- Diff of the applied patch vs upstream commit (please double-check if non-empty: --- --- - 2020-07-24 12:53:49.183945780 +0100 +++ 0015-net-mlx5-fix-interrupt-installation-timing.patch 2020-07-24 12:53:48.183004522 +0100 @@ -1,8 +1,10 @@ -From 33860cfab62ed9a3673b1077899c1c527b09e385 Mon Sep 17 00:00:00 2001 +From 5da51166d7493f5a99724d8c424c4a9c2eb5b760 Mon Sep 17 00:00:00 2001 From: Suanming Mou Date: Thu, 28 May 2020 17:22:09 +0800 Subject: [PATCH] net/mlx5: fix interrupt installation timing +[ upstream commit 33860cfab62ed9a3673b1077899c1c527b09e385 ] + Currently, the DevX counter query works asynchronously with Devx interrupt handler return the query result. When port closes, the interrupt handler will be uninstalled and the Devx comp obj will @@ -16,7 +18,6 @@ the counter asynchronous query stop before interrupt uninstall. Fixes: f15db67df09c ("net/mlx5: accelerate DV flow counter query") -Cc: stable@dpdk.org Signed-off-by: Suanming Mou Acked-by: Matan Azrad @@ -24,14 +25,14 @@ drivers/net/mlx5/mlx5.c | 101 ++++++++++--- drivers/net/mlx5/mlx5.h | 5 - drivers/net/mlx5/mlx5_ethdev.c | 243 -------------------------------- - drivers/net/mlx5/mlx5_trigger.c | 17 ++- - 4 files changed, 97 insertions(+), 269 deletions(-) + drivers/net/mlx5/mlx5_trigger.c | 16 ++- + 4 files changed, 96 insertions(+), 269 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c -index 81102631a..469ff7368 100644 +index 1e34f6263..bb718f27f 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c -@@ -10,6 +10,7 @@ +@@ -12,6 +12,7 @@ #include #include #include @@ -39,7 +40,7 @@ #include #include -@@ -655,6 +656,85 @@ mlx5_restore_doorbell_mapping_env(int value) +@@ -470,6 +471,85 @@ mlx5_restore_doorbell_mapping_env(int value) setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1); } @@ -125,7 +126,7 @@ /** * Allocate shared IB device context. If there is multiport device the * master and representors will share this context, if there is single -@@ -749,7 +829,6 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, +@@ -564,7 +644,6 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, sizeof(sh->ibdev_name)); strncpy(sh->ibdev_path, sh->ctx->device->ibdev_path, sizeof(sh->ibdev_path)); @@ -133,19 +134,19 @@ /* * Setting port_id to max unallowed value means * there is no interrupt subhandler installed for -@@ -810,6 +889,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, +@@ -624,6 +703,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, err = rte_errno; goto error; } + mlx5_dev_shared_handler_install(sh); - mlx5_flow_aging_init(sh); mlx5_flow_counters_mng_init(sh); - mlx5_flow_ipool_create(sh, config); -@@ -886,20 +966,7 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) + /* Add device to memory callback list. */ + rte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock); +@@ -697,20 +777,7 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) + * Only primary process handles async device events. **/ mlx5_flow_counters_mng_close(sh); - mlx5_flow_ipool_destroy(sh); -- MLX5_ASSERT(!sh->intr_cnt); +- assert(!sh->intr_cnt); - if (sh->intr_cnt) - mlx5_intr_callback_unregister - (&sh->intr_handle, mlx5_dev_interrupt_handler, sh); @@ -163,17 +164,17 @@ if (sh->pd) claim_zero(mlx5_glue->dealloc_pd(sh->pd)); if (sh->tis) -@@ -1437,9 +1504,6 @@ mlx5_dev_close(struct rte_eth_dev *dev) +@@ -1248,9 +1315,6 @@ mlx5_dev_close(struct rte_eth_dev *dev) DRV_LOG(DEBUG, "port %u closing device \"%s\"", dev->data->port_id, ((priv->sh->ctx != NULL) ? priv->sh->ctx->device->name : "")); - /* In case mlx5_dev_stop() has not been called. */ - mlx5_dev_interrupt_handler_uninstall(dev); - mlx5_dev_interrupt_handler_devx_uninstall(dev); - /* - * If default mreg copy action is removed at the stop stage, - * the search will return none and nothing will be done anymore. -@@ -3624,7 +3688,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + mlx5_traffic_disable(dev); + mlx5_flow_flush(dev, NULL); + mlx5_flow_meter_flush(dev, NULL); +@@ -3362,7 +3426,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, rte_eth_copy_pci_info(list[i].eth_dev, pci_dev); /* Restore non-PCI flags cleared by the above call. */ list[i].eth_dev->data->dev_flags |= restore; @@ -182,12 +183,12 @@ } if (i != ns) { diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h -index d9f5d816f..2908c8b8d 100644 +index e4af5d40d..e53934d45 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h -@@ -512,10 +512,7 @@ struct mlx5_ibv_shared { - struct mlx5_indexed_pool *ipool[MLX5_IPOOL_MAX]; - /* Memory Pool for mlx5 flow resources. */ +@@ -682,10 +682,7 @@ struct mlx5_ibv_shared { + push_vlan_action_list; /* List of push VLAN actions. */ + struct mlx5_flow_counter_mng cmng; /* Counters management structure. */ /* Shared interrupt handler section. */ - pthread_mutex_t intr_mutex; /* Interrupt config mutex. */ - uint32_t intr_cnt; /* Interrupt handler reference counter. */ @@ -196,7 +197,7 @@ struct rte_intr_handle intr_handle_devx; /* DEVX interrupt handler. */ struct mlx5dv_devx_cmd_comp *devx_comp; /* DEVX async comp obj. */ struct mlx5_devx_obj *tis; /* TIS object. */ -@@ -671,8 +668,6 @@ void mlx5_dev_interrupt_handler(void *arg); +@@ -838,8 +835,6 @@ void mlx5_dev_interrupt_handler(void *arg); void mlx5_dev_interrupt_handler_devx(void *arg); void mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev); void mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev); @@ -206,10 +207,10 @@ int mlx5_set_link_up(struct rte_eth_dev *dev); int mlx5_is_removed(struct rte_eth_dev *dev); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c -index 47f11b963..b837ce636 100644 +index 3b4c5dbe7..3b1f18b3f 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c -@@ -1444,249 +1444,6 @@ mlx5_dev_interrupt_handler_devx(void *cb_arg) +@@ -1475,249 +1475,6 @@ mlx5_dev_interrupt_handler_devx(void *cb_arg) #endif /* HAVE_IBV_DEVX_ASYNC */ } @@ -230,14 +231,14 @@ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); -- MLX5_ASSERT(priv->ibv_port); -- MLX5_ASSERT(priv->ibv_port <= sh->max_port); -- MLX5_ASSERT(dev->data->port_id < RTE_MAX_ETHPORTS); +- assert(priv->ibv_port); +- assert(priv->ibv_port <= sh->max_port); +- assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].ih_port_id >= RTE_MAX_ETHPORTS) - goto exit; -- MLX5_ASSERT(sh->port[priv->ibv_port - 1].ih_port_id == +- assert(sh->port[priv->ibv_port - 1].ih_port_id == - (uint32_t)dev->data->port_id); -- MLX5_ASSERT(sh->intr_cnt); +- assert(sh->intr_cnt); - sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; - if (!sh->intr_cnt || --sh->intr_cnt) - goto exit; @@ -266,13 +267,13 @@ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); -- MLX5_ASSERT(priv->ibv_port); -- MLX5_ASSERT(priv->ibv_port <= sh->max_port); -- MLX5_ASSERT(dev->data->port_id < RTE_MAX_ETHPORTS); +- assert(priv->ibv_port); +- assert(priv->ibv_port <= sh->max_port); +- assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].devx_ih_port_id >= RTE_MAX_ETHPORTS) - goto exit; -- MLX5_ASSERT(sh->port[priv->ibv_port - 1].devx_ih_port_id == -- (uint32_t)dev->data->port_id); +- assert(sh->port[priv->ibv_port - 1].devx_ih_port_id == +- (uint32_t)dev->data->port_id); - sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS; - if (!sh->devx_intr_cnt || --sh->devx_intr_cnt) - goto exit; @@ -310,12 +311,12 @@ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); -- MLX5_ASSERT(priv->ibv_port); -- MLX5_ASSERT(priv->ibv_port <= sh->max_port); -- MLX5_ASSERT(dev->data->port_id < RTE_MAX_ETHPORTS); +- assert(priv->ibv_port); +- assert(priv->ibv_port <= sh->max_port); +- assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].ih_port_id < RTE_MAX_ETHPORTS) { - /* The handler is already installed for this port. */ -- MLX5_ASSERT(sh->intr_cnt); +- assert(sh->intr_cnt); - goto exit; - } - if (sh->intr_cnt) { @@ -325,7 +326,7 @@ - goto exit; - } - /* No shared handler installed. */ -- MLX5_ASSERT(sh->ctx->async_fd > 0); +- assert(sh->ctx->async_fd > 0); - flags = fcntl(sh->ctx->async_fd, F_GETFL); - ret = fcntl(sh->ctx->async_fd, F_SETFL, flags | O_NONBLOCK); - if (ret) { @@ -364,12 +365,12 @@ - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - pthread_mutex_lock(&sh->intr_mutex); -- MLX5_ASSERT(priv->ibv_port); -- MLX5_ASSERT(priv->ibv_port <= sh->max_port); -- MLX5_ASSERT(dev->data->port_id < RTE_MAX_ETHPORTS); +- assert(priv->ibv_port); +- assert(priv->ibv_port <= sh->max_port); +- assert(dev->data->port_id < RTE_MAX_ETHPORTS); - if (sh->port[priv->ibv_port - 1].devx_ih_port_id < RTE_MAX_ETHPORTS) { - /* The handler is already installed for this port. */ -- MLX5_ASSERT(sh->devx_intr_cnt); +- assert(sh->devx_intr_cnt); - goto exit; - } - if (sh->devx_intr_cnt) { @@ -460,18 +461,10 @@ * DPDK callback to bring the link DOWN. * diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c -index 8106598ff..f12319376 100644 +index 6fc4190f4..04b06e11d 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c -@@ -269,6 +269,7 @@ error: - int - mlx5_dev_start(struct rte_eth_dev *dev) - { -+ struct mlx5_priv *priv = dev->data->dev_private; - int ret; - int fine_inline; - -@@ -340,7 +341,18 @@ mlx5_dev_start(struct rte_eth_dev *dev) +@@ -327,7 +327,18 @@ mlx5_dev_start(struct rte_eth_dev *dev) dev->rx_pkt_burst = mlx5_select_rx_function(dev); /* Enable datapath on secondary process. */ mlx5_mp_req_start_rxtx(dev); @@ -491,9 +484,9 @@ return 0; error: ret = rte_errno; /* Save rte_errno before cleanup. */ -@@ -382,7 +394,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev) - /* All RX queue flags will be cleared in the flush interface. */ - mlx5_flow_list_flush(dev, &priv->flows, true); +@@ -366,7 +377,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev) + mlx5_flow_stop(dev, &priv->flows); + mlx5_traffic_disable(dev); mlx5_rx_intr_vec_disable(dev); - mlx5_dev_interrupt_handler_uninstall(dev); + priv->sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS;