From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6E98AA0542 for ; Fri, 11 Nov 2022 11:34:52 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6A56E42D0E; Fri, 11 Nov 2022 11:34:52 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 61DD442D0C for ; Fri, 11 Nov 2022 11:34:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1668162889; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Kvy77svbhdlQsZHzr70E5BgE08xy7W4mkIqCVNNGhGc=; b=dfbbvD3TiyHEoTxf/QLEmC/Vi4zALs3gdrLpK/kG1h18lP7rMngo3lYaQeZOnPA4KopwRG kvzbhEfPnkrE4E5c7p9aJ8SQ5Irs8/SLDcQapR+zBjcTgSrSwQjv839NDdmQhuJQ1c5dZW 8ySkEaZSD3i2Z3f/U/OX/CTYCneYCjk= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-450-CjfkqWFwMnKdNYwdJTGqOQ-1; Fri, 11 Nov 2022 05:34:46 -0500 X-MC-Unique: CjfkqWFwMnKdNYwdJTGqOQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7137A29AB3F9; Fri, 11 Nov 2022 10:34:46 +0000 (UTC) Received: from rh.redhat.com (unknown [10.39.195.104]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73BFD2022EA4; Fri, 11 Nov 2022 10:34:45 +0000 (UTC) From: Kevin Traynor To: Yiding Zhou Cc: Qi Zhang , dpdk stable Subject: patch 'net/iavf: add thread for event callbacks' has been queued to stable release 21.11.3 Date: Fri, 11 Nov 2022 10:33:18 +0000 Message-Id: <20221111103337.307408-28-ktraynor@redhat.com> In-Reply-To: <20221111103337.307408-1-ktraynor@redhat.com> References: <20221111103337.307408-1-ktraynor@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 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 Hi, FYI, your patch has been queued to stable release 21.11.3 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 11/14/22. 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. Queued patches are on a temporary branch at: https://github.com/kevintraynor/dpdk-stable This queued commit can be viewed at: https://github.com/kevintraynor/dpdk-stable/commit/c346009ca9686fabd300f8afe688239426b5eebd Thanks. Kevin --- >From c346009ca9686fabd300f8afe688239426b5eebd Mon Sep 17 00:00:00 2001 From: Yiding Zhou Date: Thu, 20 Oct 2022 13:00:22 +0800 Subject: [PATCH] net/iavf: add thread for event callbacks [ upstream commit cb5c1b91f76f436724cd09f26c7432b2775b519c ] All callbacks registered for ethdev events are called in eal-intr-thread, and some of them execute virtchnl commands. Because interrupts are disabled in the intr thread, no response will be received for these commands. So all callbacks should be called in a new context. When the device is bonded, the bond pmd registers a callback for the LSC event to execute virtchnl commands to reinitialize the device, and it would also raise the above issue. This commit adds a new thread to call all event callbacks. Fixes: 48de41ca11f0 ("net/avf: enable link status update") Fixes: 84108425054a ("net/iavf: support asynchronous virtual channel message") Signed-off-by: Yiding Zhou Acked-by: Qi Zhang --- drivers/net/iavf/iavf.h | 2 + drivers/net/iavf/iavf_ethdev.c | 5 ++ drivers/net/iavf/iavf_vchnl.c | 153 +++++++++++++++++++++++++++++++-- 3 files changed, 154 insertions(+), 6 deletions(-) diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h index 29692e3994..afffc1a13e 100644 --- a/drivers/net/iavf/iavf.h +++ b/drivers/net/iavf/iavf.h @@ -401,4 +401,6 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops) int iavf_check_api_version(struct iavf_adapter *adapter); int iavf_get_vf_resource(struct iavf_adapter *adapter); +void iavf_dev_event_handler_fini(void); +int iavf_dev_event_handler_init(void); void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev); int iavf_enable_vlan_strip(struct iavf_adapter *adapter); diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index f835457e4f..11ddd6dc16 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -2562,4 +2562,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) ð_dev->data->mac_addrs[0]); + if (iavf_dev_event_handler_init()) + goto init_vf_err; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) { /* register callback func to eal lib */ @@ -2716,4 +2719,6 @@ iavf_dev_uninit(struct rte_eth_dev *dev) iavf_dev_close(dev); + iavf_dev_event_handler_fini(); + return 0; } diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c index 1bd3559ec2..54c6e39e16 100644 --- a/drivers/net/iavf/iavf_vchnl.c +++ b/drivers/net/iavf/iavf_vchnl.c @@ -3,4 +3,5 @@ */ +#include #include #include @@ -12,4 +13,5 @@ #include #include +#include #include @@ -28,4 +30,144 @@ #define ASQ_DELAY_MS 1 +#define MAX_EVENT_PENDING 16 + +struct iavf_event_element { + TAILQ_ENTRY(iavf_event_element) next; + struct rte_eth_dev *dev; + enum rte_eth_event_type event; + void *param; + size_t param_alloc_size; + uint8_t param_alloc_data[0]; +}; + +struct iavf_event_handler { + uint32_t ndev; + pthread_t tid; + int fd[2]; + pthread_mutex_t lock; + TAILQ_HEAD(event_list, iavf_event_element) pending; +}; + +static struct iavf_event_handler event_handler = { + .fd = {-1, -1}, +}; + +#ifndef TAILQ_FOREACH_SAFE +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +static void * +iavf_dev_event_handle(void *param __rte_unused) +{ + struct iavf_event_handler *handler = &event_handler; + TAILQ_HEAD(event_list, iavf_event_element) pending; + + while (true) { + char unused[MAX_EVENT_PENDING]; + ssize_t nr = read(handler->fd[0], &unused, sizeof(unused)); + if (nr <= 0) + break; + + TAILQ_INIT(&pending); + pthread_mutex_lock(&handler->lock); + TAILQ_CONCAT(&pending, &handler->pending, next); + pthread_mutex_unlock(&handler->lock); + + struct iavf_event_element *pos, *save_next; + TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) { + TAILQ_REMOVE(&pending, pos, next); + rte_eth_dev_callback_process(pos->dev, pos->event, pos->param); + rte_free(pos); + } + } + + return NULL; +} + +static void +iavf_dev_event_post(struct rte_eth_dev *dev, + enum rte_eth_event_type event, + void *param, size_t param_alloc_size) +{ + struct iavf_event_handler *handler = &event_handler; + char notify_byte; + struct iavf_event_element *elem = rte_malloc(NULL, sizeof(*elem) + param_alloc_size, 0); + if (!elem) + return; + + elem->dev = dev; + elem->event = event; + elem->param = param; + elem->param_alloc_size = param_alloc_size; + if (param && param_alloc_size) { + rte_memcpy(elem->param_alloc_data, param, param_alloc_size); + elem->param = elem->param_alloc_data; + } + + pthread_mutex_lock(&handler->lock); + TAILQ_INSERT_TAIL(&handler->pending, elem, next); + pthread_mutex_unlock(&handler->lock); + + ssize_t nw = write(handler->fd[1], ¬ify_byte, 1); + RTE_SET_USED(nw); +} + +int +iavf_dev_event_handler_init(void) +{ + struct iavf_event_handler *handler = &event_handler; + + if (__atomic_add_fetch(&handler->ndev, 1, __ATOMIC_RELAXED) != 1) + return 0; +#if defined(RTE_EXEC_ENV_IS_WINDOWS) && RTE_EXEC_ENV_IS_WINDOWS != 0 + int err = _pipe(handler->fd, MAX_EVENT_PENDING, O_BINARY); +#else + int err = pipe(handler->fd); +#endif + if (err != 0) { + __atomic_sub_fetch(&handler->ndev, 1, __ATOMIC_RELAXED); + return -1; + } + + TAILQ_INIT(&handler->pending); + pthread_mutex_init(&handler->lock, NULL); + + if (rte_ctrl_thread_create(&handler->tid, "iavf-event-thread", + NULL, iavf_dev_event_handle, NULL)) { + __atomic_sub_fetch(&handler->ndev, 1, __ATOMIC_RELAXED); + return -1; + } + + return 0; +} + +void +iavf_dev_event_handler_fini(void) +{ + struct iavf_event_handler *handler = &event_handler; + + if (__atomic_sub_fetch(&handler->ndev, 1, __ATOMIC_RELAXED) != 0) + return; + + int unused = pthread_cancel(handler->tid); + RTE_SET_USED(unused); + close(handler->fd[0]); + close(handler->fd[1]); + handler->fd[0] = -1; + handler->fd[1] = -1; + + pthread_join(handler->tid, NULL); + pthread_mutex_destroy(&handler->lock); + + struct iavf_event_element *pos, *save_next; + TAILQ_FOREACH_SAFE(pos, &handler->pending, next, save_next) { + TAILQ_REMOVE(&handler->pending, pos, next); + rte_free(pos); + } +} + static uint32_t iavf_convert_link_speed(enum virtchnl_link_speed virt_link_speed) @@ -279,6 +421,6 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event"); vf->vf_reset = true; - rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, - NULL); + iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET, + NULL, 0); break; case VIRTCHNL_EVENT_LINK_CHANGE: @@ -294,5 +436,5 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, } iavf_dev_link_update(dev, 0); - rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); + iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0); break; case VIRTCHNL_EVENT_PF_DRIVER_CLOSE: @@ -360,7 +502,6 @@ iavf_handle_virtchnl_msg(struct rte_eth_dev *dev) RTE_ETH_EVENT_IPSEC_UNKNOWN; desc.metadata = ev->ipsec_event_data; - rte_eth_dev_callback_process(dev, - RTE_ETH_EVENT_IPSEC, - &desc); + iavf_dev_event_post(dev, RTE_ETH_EVENT_IPSEC, + &desc, sizeof(desc)); return; } -- 2.38.1 --- Diff of the applied patch vs upstream commit (please double-check if non-empty: --- --- - 2022-11-11 10:32:17.749691045 +0000 +++ 0028-net-iavf-add-thread-for-event-callbacks.patch 2022-11-11 10:32:17.085300813 +0000 @@ -1 +1 @@ -From cb5c1b91f76f436724cd09f26c7432b2775b519c Mon Sep 17 00:00:00 2001 +From c346009ca9686fabd300f8afe688239426b5eebd Mon Sep 17 00:00:00 2001 @@ -5,0 +6,2 @@ +[ upstream commit cb5c1b91f76f436724cd09f26c7432b2775b519c ] + @@ -20 +21,0 @@ -Cc: stable@dpdk.org @@ -31 +32 @@ -index 26b858f6f0..1edebab8dc 100644 +index 29692e3994..afffc1a13e 100644 @@ -34 +35 @@ -@@ -425,4 +425,6 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops) +@@ -401,4 +401,6 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops) @@ -42 +43 @@ -index b1958e0474..8d9f3a6d3d 100644 +index f835457e4f..11ddd6dc16 100644 @@ -45 +46 @@ -@@ -2634,4 +2634,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) +@@ -2562,4 +2562,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) @@ -53 +54 @@ -@@ -2788,4 +2791,6 @@ iavf_dev_uninit(struct rte_eth_dev *dev) +@@ -2716,4 +2719,6 @@ iavf_dev_uninit(struct rte_eth_dev *dev) @@ -61 +62 @@ -index 729400cb91..654bc7edb6 100644 +index 1bd3559ec2..54c6e39e16 100644