Received: by 2002:a05:6358:7058:b0:131:369:b2a3 with SMTP id 24csp9260815rwp; Thu, 20 Jul 2023 02:01:20 -0700 (PDT) X-Google-Smtp-Source: APBJJlHCvckk8ZE9/Y9YFhTTwZV2PuTyAjnq9+Kz01Pou0ko/LORxfc+3WAlTNAqAuqgHVJUXqVZ X-Received: by 2002:aa7:d992:0:b0:521:7ab6:b954 with SMTP id u18-20020aa7d992000000b005217ab6b954mr4356495eds.1.1689843679887; Thu, 20 Jul 2023 02:01:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689843679; cv=none; d=google.com; s=arc-20160816; b=FLr+QVk773VvUINCvWQGjfzct7U0Q/18TFcRAFezWG1X0huVKNPp1K/VBuYnftc0Jp XaiRVhy/7Oe6HYB5O1PvvxsAmFf105egjImwb6OIXfV9QXSjcvIBx/4GuBFdtOLrPvFd 59F8LEZDtlEbH3P1reqmk1xkm/Ss8zdA6Duf7zObCbbCyc17mZnxw8NcgJF9WMx9cKdB I/y6bQ3iA/yIltLAam/xnJ6QDsMzQKU07WFQ4J2qjDfRM/9+GvXCtm8Za2a/I0hAfoeD tResVwb4F9UrspXYbYgjEZHHmbuar0TTqiIdbmHI7LRU/ePoV/6BkgoBKABwvoGDKVAv KWMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=FdWOiZY8JAbFso9U2x4aBoUJGl1kiwHcq73EX1vFcEw=; fh=OJ7/iRsvElcEdO8PFPHhUuQuWW/5XTtWV3MPeONcTQA=; b=y0XvcNIwELiMgFySjSnz8hRgA3HzLQIJ2XrqOXiKiuM7Gun7P52CURNrC+bJ1Flsj9 FmCnC52kGCvLjGskI3xnuILzWsn/pFBVPohWkvLnjFcFxPeR5qrt6IMsx84x2kcq+FnX tU6KStsKP37jfQ80Lf2GrGX+HlDAAhj93UlcSBRODDABo1oBt31AKqQani6wOoElV2w/ 80VxX4pMB5qmzOQpRwqTtSnrUuPAglUhqpjTV4LL1RmJm72RwTs73qI54zXgnGqu06Dd IRjAAGBQ3w01X/fpWnXkNEPYp/8rkNm0kaZo36yyTRu+NE/EJQ1KttaXoQPVHOtOPXo+ 1M6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=jM6JUqhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i17-20020aa7dd11000000b0051dec4bd870si507865edv.101.2023.07.20.02.00.49; Thu, 20 Jul 2023 02:01:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=jM6JUqhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231374AbjGTI6I (ORCPT + 99 others); Thu, 20 Jul 2023 04:58:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36786 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230006AbjGTIjk (ORCPT ); Thu, 20 Jul 2023 04:39:40 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E4E026AC for ; Thu, 20 Jul 2023 01:38:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1689842332; 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=FdWOiZY8JAbFso9U2x4aBoUJGl1kiwHcq73EX1vFcEw=; b=jM6JUqhvwITclfdbnT5qe0vq9I0TQDfrpMbT/khFKmmH0Of+SyUF2Ai/udT9B+H9xXOD2C IzWmI5FLqVCwi4QdZYZDPPXc3XcFaYx5ixl4VS4r8pwyjsFmVrpmFyUaWHsaz0pTjsbguo Nu0Y4lNd//QBBDaVYrpHNVkjgUc3ekQ= Received: from mimecast-mx02.redhat.com (66.187.233.73 [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-668-txF5yud6MoSDNVqmpSoJYw-1; Thu, 20 Jul 2023 04:38:51 -0400 X-MC-Unique: txF5yud6MoSDNVqmpSoJYw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 374333C0C4A3; Thu, 20 Jul 2023 08:38:51 +0000 (UTC) Received: from dell-per430-12.lab.eng.pek2.redhat.com (dell-per430-12.lab.eng.pek2.redhat.com [10.73.196.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id DD31FF6CD5; Thu, 20 Jul 2023 08:38:46 +0000 (UTC) From: Jason Wang To: mst@redhat.com, jasowang@redhat.com, xuanzhuo@linux.alibaba.com Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alvaro.karsz@solid-run.com, maxime.coquelin@redhat.com Subject: [PATCH net-next v4 1/2] virtio-net: convert rx mode setting to use workqueue Date: Thu, 20 Jul 2023 04:38:38 -0400 Message-Id: <20230720083839.481487-2-jasowang@redhat.com> In-Reply-To: <20230720083839.481487-1-jasowang@redhat.com> References: <20230720083839.481487-1-jasowang@redhat.com> MIME-Version: 1.0 Content-type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch convert rx mode setting to be done in a workqueue, this is a must for allow to sleep when waiting for the cvq command to response since current code is executed under addr spin lock. Note that we need to disable and flush the workqueue during freeze, this means the rx mode setting is lost after resuming. This is not the bug of this patch as we never try to restore rx mode setting during resume. Signed-off-by: Jason Wang --- drivers/net/virtio_net.c | 55 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d67b36fdba0d..9f3b1d6ac33d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -274,6 +274,12 @@ struct virtnet_info { /* Work struct for config space updates */ struct work_struct config_work; + /* Work struct for setting rx mode */ + struct work_struct rx_mode_work; + + /* OK to queue work setting RX mode? */ + bool rx_mode_work_enabled; + /* Does the affinity hint is set for virtqueues? */ bool affinity_hint_set; @@ -397,6 +403,20 @@ static void disable_delayed_refill(struct virtnet_info *vi) spin_unlock_bh(&vi->refill_lock); } +static void enable_rx_mode_work(struct virtnet_info *vi) +{ + rtnl_lock(); + vi->rx_mode_work_enabled = true; + rtnl_unlock(); +} + +static void disable_rx_mode_work(struct virtnet_info *vi) +{ + rtnl_lock(); + vi->rx_mode_work_enabled = false; + rtnl_unlock(); +} + static void virtqueue_napi_schedule(struct napi_struct *napi, struct virtqueue *vq) { @@ -2448,9 +2468,11 @@ static int virtnet_close(struct net_device *dev) return 0; } -static void virtnet_set_rx_mode(struct net_device *dev) +static void virtnet_rx_mode_work(struct work_struct *work) { - struct virtnet_info *vi = netdev_priv(dev); + struct virtnet_info *vi = + container_of(work, struct virtnet_info, rx_mode_work); + struct net_device *dev = vi->dev; struct scatterlist sg[2]; struct virtio_net_ctrl_mac *mac_data; struct netdev_hw_addr *ha; @@ -2463,6 +2485,8 @@ static void virtnet_set_rx_mode(struct net_device *dev) if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX)) return; + rtnl_lock(); + vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0); vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0); @@ -2480,14 +2504,19 @@ static void virtnet_set_rx_mode(struct net_device *dev) dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n", vi->ctrl->allmulti ? "en" : "dis"); + netif_addr_lock_bh(dev); + uc_count = netdev_uc_count(dev); mc_count = netdev_mc_count(dev); /* MAC filter - use one buffer for both lists */ buf = kzalloc(((uc_count + mc_count) * ETH_ALEN) + (2 * sizeof(mac_data->entries)), GFP_ATOMIC); mac_data = buf; - if (!buf) + if (!buf) { + netif_addr_unlock_bh(dev); + rtnl_unlock(); return; + } sg_init_table(sg, 2); @@ -2508,6 +2537,8 @@ static void virtnet_set_rx_mode(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); + netif_addr_unlock_bh(dev); + sg_set_buf(&sg[1], mac_data, sizeof(mac_data->entries) + (mc_count * ETH_ALEN)); @@ -2515,9 +2546,19 @@ static void virtnet_set_rx_mode(struct net_device *dev) VIRTIO_NET_CTRL_MAC_TABLE_SET, sg)) dev_warn(&dev->dev, "Failed to set MAC filter table.\n"); + rtnl_unlock(); + kfree(buf); } +static void virtnet_set_rx_mode(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + + if (vi->rx_mode_work_enabled) + schedule_work(&vi->rx_mode_work); +} + static int virtnet_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) { @@ -3286,6 +3327,8 @@ static void virtnet_freeze_down(struct virtio_device *vdev) /* Make sure no work handler is accessing the device */ flush_work(&vi->config_work); + disable_rx_mode_work(vi); + flush_work(&vi->rx_mode_work); netif_tx_lock_bh(vi->dev); netif_device_detach(vi->dev); @@ -3308,6 +3351,7 @@ static int virtnet_restore_up(struct virtio_device *vdev) virtio_device_ready(vdev); enable_delayed_refill(vi); + enable_rx_mode_work(vi); if (netif_running(vi->dev)) { err = virtnet_open(vi->dev); @@ -4121,6 +4165,7 @@ static int virtnet_probe(struct virtio_device *vdev) vdev->priv = vi; INIT_WORK(&vi->config_work, virtnet_config_changed_work); + INIT_WORK(&vi->rx_mode_work, virtnet_rx_mode_work); spin_lock_init(&vi->refill_lock); if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) { @@ -4229,6 +4274,8 @@ static int virtnet_probe(struct virtio_device *vdev) if (vi->has_rss || vi->has_rss_hash_report) virtnet_init_default_rss(vi); + enable_rx_mode_work(vi); + /* serialize netdev register + virtio_device_ready() with ndo_open() */ rtnl_lock(); @@ -4326,6 +4373,8 @@ static void virtnet_remove(struct virtio_device *vdev) /* Make sure no work handler is accessing the device. */ flush_work(&vi->config_work); + disable_rx_mode_work(vi); + flush_work(&vi->rx_mode_work); unregister_netdev(vi->dev); -- 2.39.3