From nobody Thu Jun 18 08:16:10 2026 Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12B223D3482 for ; Thu, 30 Apr 2026 23:39:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777592347; cv=none; b=PwCjPlV4ALlxBnUKSWd8ptnSEGxvIGedMjN8DWmjovHTOaiXO2O9qlO5OtmUaiKmYMpCN+s+ZPOS6HJS6pxPOKiVQFjwhPxi1UAfFruK/H8Hg0oHBlJyKztJODEALDe0yRYIVQZiiJb3poh73NYez3K4+wSd5dIdvBMH09LMdeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777592347; c=relaxed/simple; bh=RosUM6xPRIY1oTK9LeKQ/7oZG5o9uW6w4P5hZC7Uc/U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IZZe8pn6/Zwl7XbzTU8LEJPpyP+YXKOSsz+/YjXORxw+l6pt1r373YxLgjiZBAFIMEpHwIEs+9VEjqJ9mQxDM7kkNruLzbbVJtkq9EJlZ+i+5X+4VVXyuwun+0we9EEm5aiENUHXMZmxg2m6OntiZUaeMpGUpafgSRfZ/KiqlLM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ovn.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.160.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ovn.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-qt1-f195.google.com with SMTP id d75a77b69052e-5102582e237so11164681cf.2 for ; Thu, 30 Apr 2026 16:39:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777592345; x=1778197145; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SA+eWHMkILjGV4lZwdF0bh9/zh8ox7+jWKzlWflnjB8=; b=Ji6reKgW0UXaEbS/5I2TGxmxEft5oEa4OQ9bfebJHT8W6TI4XfglJdJv/Db1AVkbAe ZGq8vRj4zpQYxDMHOH6ycn8Ab0CMKKVr8f+jOn8YDU0pE+b0QzRcCtGqrTLk1wL0Ov/c Q5M41lNbqYEg5rsBTup3UiwLU+7uZxUbhTIm0+4kV4ZHjRUoRwqgBbm0TEjNUC6mtAPN 3fWkRK1TF7tiKK/A4C7+8FbukdhFv9siKiaCpNaNyFoWx+aiq7LbkRSmEnbTZoDx9SIS Hd+Ql2pOa6S+D39IgF6wmMVj9dI3n6HQAUkxKORpk6sDCQTvJkzfbsWavCo1cY1UTESZ EZGA== X-Forwarded-Encrypted: i=1; AFNElJ8WROzbPG3GxnDUkL0kMN7/wdssqSQIWgqP809WitWeZfbJTyWofVZ4YYI5/Zy1L6ahH4kJK3yDMmphU2c=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7kRHWjM+1MHxYb5zykErvaQeGN+Z/k3uNUYKiNML1IelU6NQR fw73DXD1rlBHa+yOP+yLxhCzTQfGSRacsa7c+uN2w8Wd7zE6961hSQC3 X-Gm-Gg: AeBDietr37WgxL6seaxKtYzsg3hDImByY7hP3skXNeiNkV+rSA5ZOALPrNC5LQanu17 VJPRPyTxKKET2WMq8lMsRB1voJ25Ep0YXjjcyyxFOb3nzUVg70tpb8BAF6L9M4SaP/UMOu+C+K2 /GuMC1LbCqUSui9MLeCWN6iEl/gRx/I4tTtvj+TNl1JAjCjhYlq1e4lUIofIOOt8JgSyQnafFjH dIkvGEXE2nFpK2OufZI7E4qgQOv5dY+W2q0/6oUKWK5i0XBECDdT/X04RsTmCqdKLoDiAomc0aR z0io3LyVi65q6klucmQSB5AEJMOW6nc46FkCK7VTogU1kCBVkKdaQ+A8Cu7tamkd1FB7lXL+oCB WsIEONAFg9GqxOdXDUM6yunEvw0xSn1wNxifkj1bUcLdmww1kn5i1Dp0pokf2wOF8WNqkqWLImh H5dxpqnqHFJzAxI+DCkA4IqBs8fgDBwVE1Su/b/b1gCAm5AMawt7xFZoqguWx6If2chyiZ7Q== X-Received: by 2002:ac8:5a0e:0:b0:50d:8db0:7abb with SMTP id d75a77b69052e-5102adc9563mr74431601cf.42.1777592344891; Thu, 30 Apr 2026 16:39:04 -0700 (PDT) Received: from im-t490s.redhat.com (89-24-32-159.nat.epc.tmcz.cz. [89.24.32.159]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51040934199sm221cf.13.2026.04.30.16.39.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Apr 2026 16:39:04 -0700 (PDT) From: Ilya Maximets To: netdev@vger.kernel.org Cc: Aaron Conole , Eelco Chaudron , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , Yuan Tan , Yang Yang , dev@openvswitch.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Ilya Maximets , stable@vger.kernel.org Subject: [PATCH net v2 1/2] openvswitch: vport: fix self-deadlock on release of tunnel ports Date: Fri, 1 May 2026 01:38:37 +0200 Message-ID: <20260430233848.440994-2-i.maximets@ovn.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260430233848.440994-1-i.maximets@ovn.org> References: <20260430233848.440994-1-i.maximets@ovn.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" vports are used concurrently and protected by RCU, so netdev_put() must happen after the RCU grace period. So, either in an RCU call or after the synchronize_net(). The rtnl_delete_link() must happen under RTNL and so can't be executed in RCU context. Calling synchronize_net() while holding RTNL is not a good idea for performance and system stability under load in general, so calling netdev_put() in RCU call is the right solution here. However, when the device is deleted, rtnl_unlock() will call netdev_run_todo() and block until all the references are gone. In the current code this means that we never reach the call_rcu() and the vport is never freed and the reference is never released, causing a self-deadlock on device removal. Fix that by moving the rcu_call() before the rtnl_unlock(), so the scheduled RCU callback will be executed when synchronize_net() is called from the rtnl_unlock()->netdev_run_todo() while the RTNL itself is already released. Fixes: 6931d21f87bc ("openvswitch: defer tunnel netdev_put to RCU release") Cc: stable@vger.kernel.org Acked-by: Eelco Chaudron Signed-off-by: Ilya Maximets Acked-by: Aaron Conole --- net/openvswitch/vport-netdev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 12055af832dc0..a1df551e915bc 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -196,9 +196,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport) */ if (vport->dev->reg_state =3D=3D NETREG_REGISTERED) rtnl_delete_link(vport->dev, 0, NULL); - rtnl_unlock(); =20 + /* We can't put the device reference yet, since it can still be in + * use, but rtnl_unlock()->netdev_run_todo() will block until all + * the references are released, so the RCU call must be before it. + */ call_rcu(&vport->rcu, vport_netdev_free); + rtnl_unlock(); } EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy); =20 --=20 2.53.0 From nobody Thu Jun 18 08:16:10 2026 Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5F673D3482 for ; Thu, 30 Apr 2026 23:39:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777592354; cv=none; b=tk+wkaOzfrQh2cq9Pqb7cv7HfrJQENBdTIyD4HeYoXuL+cMGXqhFxfbUYpZ+syasCJ5cSN5sWYzHMghAQYkkilkJbcMtXxyK31nWGbuOfV4NYTueGNhSaqWfEeeDUewmjzCV3zunehsQ53y2CaPI0BinipB9r+4fE6S3mrvk2dU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777592354; c=relaxed/simple; bh=xa+90cajr5mMWrTYdZcEISHBJqeKrEmHV2IcV7+g/Tc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KFTGGaU/Ruq/6VmUeKomHzqJRKBJhOORIoPzeo80SM8a1jv+xuYUGfNc1o9WISoRbyX0LItfWKTUudhuNje/10617vrZrv14ZmTHgGnx9vZIZyGXbD3K/5xZlYo/S/EILvH4Cromx6euBYnoeL8WfpH50FGEai/1THjmIqaCcUg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ovn.org; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.160.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ovn.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-qt1-f195.google.com with SMTP id d75a77b69052e-50e5eb0fabaso14516171cf.0 for ; Thu, 30 Apr 2026 16:39:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777592352; x=1778197152; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=L9p6ZBs3o3Fa+hheEbjqBW5O3NwkqJypwl5eyCvle18=; b=A2B3oOTGonCEeVIAKKw53Ha/iCkrATAkH0DobopEQbwUP5aMS2tAD2FH6H2eYz7gdL 7cksCAz2ELpaWMst2ToL9i0cu9fpeNFn4FdGRkrNTbWgXLHz68Bdd9EznHPlY4AnI9Rx 2u1DWo06IEscF7UgOs0znMndmH3o48ZC62MZ6uSRFilv/VrFVpTOmBaFP8WnNgdgoue3 WhS8/k1QMxFpF5kl4hB9V2bq6W8zf74IUR3HBTxGfbov4+XoIysZt0p8Pzlr5UKSbLHr tlxBx0vYZULVl0c9EG1L3+NS7qDP6fsKu4NgWJARhohEg3jPN6s62Mj71nTwFN2c+6OD lQHg== X-Forwarded-Encrypted: i=1; AFNElJ87khHWRM+SbUbOibDLD0Ubq9/k6PDBMmkW2GyVjOPUlMgQ+473wuF+5y7XVYQcHu2uCFOWei4qZeh+caU=@vger.kernel.org X-Gm-Message-State: AOJu0YwMLiFNGQaPOvONH5CGUrXbSO73tDcprSfIPkcm1lC+5N42zG2e 4UEKX9FhOQPuq1by1zXcxFZLJplzEM4SutpGjczuVXVK3YOG4aCjSynj X-Gm-Gg: AeBDietMR3EXVoFa5zLUvWs4riB90zaAgzCa3Lf0QOXvpqGjSVsAzoHlsCNyj9NFvcq FVPResvd2ngZ322fU+q97Ql+oUEm9WQAYYihb/u1CGN1Fta10dLKWHKyXslnC4+2Bd8FHxVWoCw ZmGu8uPB7Ubq9wSidjdUuNhqxeySLE0oeBlYes0uf4gJKUF6ZlISYh4H1YbYXgHORHzlK2WXqlS WNteATj1dGQxAs3aArV4zjAfgnBy/+M1OyPala0AwlyDtuU6uoC73IkQgO9Edx68rOJ9u5yQ/Pj NBcDzjykj48+pAqNjCPNFpQjnZrsloyeUCS0k7URZk8IR/8ZFwX9CRp2PTDjDA6nUv+WVMMA+0a u1DZKCBbhaeTMEGzkfZc4k+hexZ/MEheFwIt9ECKCyvm9FXLd8CCvV6LoQo75qkQ7xmgv+ikXwa j2cMo6qfktazqtnWuT+k/KkVLk0KHYPi1mi1husQwuMhHERqbkQBmM97e2584INzTOhsfftw== X-Received: by 2002:a05:622a:1b19:b0:50d:b33d:bc6b with SMTP id d75a77b69052e-5102ab1f495mr75917351cf.20.1777592351818; Thu, 30 Apr 2026 16:39:11 -0700 (PDT) Received: from im-t490s.redhat.com (89-24-32-159.nat.epc.tmcz.cz. [89.24.32.159]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51040934199sm221cf.13.2026.04.30.16.39.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Apr 2026 16:39:11 -0700 (PDT) From: Ilya Maximets To: netdev@vger.kernel.org Cc: Aaron Conole , Eelco Chaudron , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , Yuan Tan , Yang Yang , dev@openvswitch.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Ilya Maximets Subject: [PATCH net v2 2/2] selftests: openvswitch: add tests for tunnel vport refcounting Date: Fri, 1 May 2026 01:38:38 +0200 Message-ID: <20260430233848.440994-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260430233848.440994-1-i.maximets@ovn.org> References: <20260430233848.440994-1-i.maximets@ovn.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There were a few issues found with the tunnel vport types around the vport destruction code. Add some basic tests, so at least we know that they can be properly added and removed without obvious issues. The test creates OVS datapath, adds a non-LWT tunnel port, makes sure they are created, and then removes the datapath and waits for all the ports to be gone. The dpctl script had a few bugs in the none-lwt tunnel creation code, so fixing them as well to make the testing possible: - The type of the --lwt option changed in order to properly disable it. - Removed byte order conversion for the port numbers, as the value supposed to be in the host order. - Added missing 'gre' choice for the tunnel type. Signed-off-by: Ilya Maximets Acked-by: Aaron Conole Acked-by: Eelco Chaudron --- .../selftests/net/openvswitch/openvswitch.sh | 37 +++++++++++++++++++ .../selftests/net/openvswitch/ovs-dpctl.py | 19 +++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools= /testing/selftests/net/openvswitch/openvswitch.sh index b327d3061ed53..3cdd953f68132 100755 --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh @@ -26,6 +26,7 @@ tests=3D" netlink_checks ovsnl: validate netlink attrs and settings upcall_interfaces ovs: test the upcall interfaces tunnel_metadata ovs: test extraction of tunnel metadata + tunnel_refcount ovs: test tunnel vport reference cleanup drop_reason drop: test drop reasons are emitted psample psample: Sampling packets with psample" =20 @@ -830,6 +831,42 @@ test_tunnel_metadata() { return 0 } =20 +test_tunnel_refcount() { + sbxname=3D"test_tunnel_refcount" + sbx_add "${sbxname}" || return 1 + + ovs_sbx "${sbxname}" ip netns add trefns || return 1 + on_exit "ovs_sbx ${sbxname} ip netns del trefns" + + for tun_type in gre vxlan geneve; do + info "testing ${tun_type} tunnel vport refcount" + + ovs_sbx "${sbxname}" ip netns exec trefns \ + python3 $ovs_base/ovs-dpctl.py \ + add-dp dp-${tun_type} || return 1 + + ovs_sbx "${sbxname}" ip netns exec trefns \ + python3 $ovs_base/ovs-dpctl.py \ + add-if --no-lwt -t ${tun_type} \ + dp-${tun_type} ovs-${tun_type}0 || return 1 + + ovs_wait ip -netns trefns link show \ + ovs-${tun_type}0 >/dev/null 2>&1 || return 1 + + info "deleting dp - may hang if reference counting is broken" + ovs_sbx "${sbxname}" ip netns exec trefns \ + python3 $ovs_base/ovs-dpctl.py \ + del-dp dp-${tun_type} & + + dev_removed() { + ! ip -netns trefns link show "$1" >/dev/null 2>&1 + } + ovs_wait dev_removed dp-${tun_type} || return 1 + ovs_wait dev_removed ovs-${tun_type}0 || return 1 + done + return 0 +} + run_test() { ( tname=3D"$1" diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/t= esting/selftests/net/openvswitch/ovs-dpctl.py index 848f61fdcee09..bbe35e2718d26 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -11,7 +11,6 @@ import logging import math import multiprocessing import re -import socket import struct import sys import time @@ -2069,7 +2068,7 @@ class OvsVport(GenericNetlinkSocket): elif vport_type =3D=3D "internal": return OvsVport.OVS_VPORT_TYPE_INTERNAL elif vport_type =3D=3D "gre": - return OvsVport.OVS_VPORT_TYPE_INTERNAL + return OvsVport.OVS_VPORT_TYPE_GRE elif vport_type =3D=3D "vxlan": return OvsVport.OVS_VPORT_TYPE_VXLAN elif vport_type =3D=3D "geneve": @@ -2121,6 +2120,7 @@ class OvsVport(GenericNetlinkSocket): ) =20 TUNNEL_DEFAULTS =3D [("geneve", 6081), + ("gre", 0), ("vxlan", 4789)] =20 for tnl in TUNNEL_DEFAULTS: @@ -2129,9 +2129,13 @@ class OvsVport(GenericNetlinkSocket): dport =3D tnl[1] =20 if not lwt: + if tnl[0] =3D=3D "gre": + # GRE tunnels have no options. + break + vportopt =3D OvsVport.ovs_vport_msg.vportopts() vportopt["attrs"].append( - ["OVS_TUNNEL_ATTR_DST_PORT", socket.htons(dport)] + ["OVS_TUNNEL_ATTR_DST_PORT", dport] ) msg["attrs"].append( ["OVS_VPORT_ATTR_OPTIONS", vportopt] @@ -2145,6 +2149,9 @@ class OvsVport(GenericNetlinkSocket): geneve_port=3Ddport, geneve_collect_metadata=3DTrue, geneve_udp_zero_csum6_rx=3D1) + elif tnl[0] =3D=3D "gre": + ipr.link("add", ifname=3Dvport_ifname, kind=3D"gre= tap", + gre_collect_metadata=3DTrue) elif tnl[0] =3D=3D "vxlan": ipr.link("add", ifname=3Dvport_ifname, kind=3Dtnl[= 0], vxlan_learning=3D0, vxlan_collect_metadat= a=3D1, @@ -2563,7 +2570,7 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=3DND= B(), vpl=3DOvsVport()): if vpo: dpo =3D vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT") if dpo: - opts +=3D " tnl-dport:%s" % socket.ntohs(dpo) + opts +=3D " tnl-dport:%s" % dpo print( " port %d: %s (%s%s)" % ( @@ -2632,7 +2639,7 @@ def main(argv): "--ptype", type=3Dstr, default=3D"netdev", - choices=3D["netdev", "internal", "geneve", "vxlan"], + choices=3D["netdev", "internal", "gre", "geneve", "vxlan"], help=3D"Interface type (default netdev)", ) addifcmd.add_argument( @@ -2645,7 +2652,7 @@ def main(argv): addifcmd.add_argument( "-l", "--lwt", - type=3Dbool, + action=3Dargparse.BooleanOptionalAction, default=3DTrue, help=3D"Use LWT infrastructure instead of vport (default true)." ) --=20 2.53.0