From nobody Tue Jun 16 19:34:15 2026 Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) (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 0534037996B for ; Wed, 29 Apr 2026 15:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.67 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475890; cv=none; b=tbiDIq1zeAqizgNGlgz6B5HDfGl9Vo7GtXh5KGLbXWM15W432rVAl83Q6E1dSaSemzrJN12IH31GJ7QjjiUsYsEfvwLTZ59+KMVXYlpEr0Cir7/iHQZ83HDI/3atWGV0fdSvllqq0odjTAXRLm6o4RyR1v33qHgIWIZ+/MUVgVc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475890; c=relaxed/simple; bh=IcSgz7CPtBhFf1K8izNXcbPchRtKjVsJDl/ciso75PU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fR/WUjof2rDHhHtxMFHkGQLkAP8e1Iev+kO4mxF7cbRoAX1+AEB+dDWmRLg5xB1g4xCCDJR2SzzT7otC5sEZNcMPJRLXV3HQJRWe3t6bwK36w28iEuiR59h60WpIlXH2LS36bQeHbj/gXruJudBJt0BZXt7k9HgILZ1p0TjRCf8= 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.128.67 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-wm1-f67.google.com with SMTP id 5b1f17b1804b1-488a14c31eeso105948025e9.0 for ; Wed, 29 Apr 2026 08:18:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777475887; x=1778080687; 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=wI/PIcTVy7eu/PfacjAoItlkhWbBUZ77v7uqcAyLoWE=; b=J8rUQ82Ys7jPBPuv2eKZtEPpt6XbiMQq+JSReW+5w/D3BCJKIiAJpPIXr0fCgrrcRJ 0utijMrFDFNX9I31p1CISLrU3dDPuXmqtACkdMAF4ixt+FcTFs9PUmLBf4DmwxD+Fkk5 XdVr2R+yhXNpLIsA+yCGB8W945CB/hS0TZgOXID/iumcbjraGPpC4tUfsGVhEuLDYI4v q+l1vM2e3kWXYlkwpuNI8bHaPZtUTRnC5sy3fYBMgflaOq7L7NNXKV2ZHOC9YcDhzh23 kSjFLyw0CjtJ1LyAB74fKszzNk1ZYUZrFyiWi2JAIfIODXc3IAqHNqlTQDmdrYePQqds hs1w== X-Forwarded-Encrypted: i=1; AFNElJ/R3IxGZPLDkvNIjrNs+dHM4L6U2J9eC0g+pyfWexL3XHP0mz/fwp5Xuv34Jp3sfkHgUll+sr57Kw+vhg4=@vger.kernel.org X-Gm-Message-State: AOJu0YwQ7g4Qil0JRKU6reFORBfZsdmw9q2D/dz5pyeTVAcCOsYGTY52 sElcDsQokM5s4qXsE0vS7HIUKTqB4mZQGzNa9ofXT0aOQNWlFmfAI83W X-Gm-Gg: AeBDiesszBw7eJ4Qay8GRpvoIzCDAmx5ck7nyVy5nj6oCcb+kEonVwPdYbuEcn2vVYA RE+lL3PwqHVyUjCt5Sd+1fD8WJQ2g4JqXxUxNJRQ4CdxPIatBIQptRX6H4rZnLAn6kugjQg0zfD fHeL1kj1IsfQ7DguM11FIs4f67/rhvYzdJAyu2s+RE241mJQTwZH5HmNwYuSZ7YDAcn1rkVZ58/ LCBOjcbVI/hB16AoReB3NHF7xMwzZr7M46v/Xpl4y1j9aEl0+wSHKiZ9zRGvxGXipubChg3aNKj l8IrcWwVBPLns9tKeIIaJEm9Feq1c57zCHeVVQArb99XVUYwTbszkfjxVlEYIl8AhBqgx0A3v2o 08RDj7IfMZ/ZpogoWzGGO2ilITd93cpu8oCRJswpcRKJYPxI19x9eKyQ8YUQwRh7cKvkWtwMiIc s27NLmcx71bLDx9T1jb57xyrjDpp1v8uxuF9xUZGkCXxl1MgTd2O/QRBsTNiCmPppqGRcBTA== X-Received: by 2002:a05:600c:1396:b0:48a:5565:ec3d with SMTP id 5b1f17b1804b1-48a77b1b85fmr132416975e9.22.1777475887157; Wed, 29 Apr 2026 08:18:07 -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 5b1f17b1804b1-48a7c2d3811sm32358165e9.3.2026.04.29.08.18.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 08:18:06 -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 1/2] openvswitch: vport: fix self-deadlock on release of tunnel ports Date: Wed, 29 Apr 2026 17:16:36 +0200 Message-ID: <20260429151756.4157670-2-i.maximets@ovn.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260429151756.4157670-1-i.maximets@ovn.org> References: <20260429151756.4157670-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 Signed-off-by: Ilya Maximets Acked-by: Eelco Chaudron --- 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 Tue Jun 16 19:34:15 2026 Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) (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 2239437CD4A for ; Wed, 29 Apr 2026 15:18:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.67 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475896; cv=none; b=UYwxmPttpty/ptD+F4c+I5lXv4Ecv9aq+fSIkuM1my1trVBoW+/YZ/Fd/ZTROd+bwdTIAEYy41gBxWjwI2vgdooziJOBD67wbf5V6aYwL/MMNNTfhrpWudhGV789kdWCuRy9FsE7GUsD4Lp8A7A7UnirixPPgHtqLINZ6BxiKA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777475896; c=relaxed/simple; bh=SCCuZca09OdAS3knl33zqAdII8RwnJ+xs+WR0FRDVV0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AVc6iPHTNM6txG3o8nGT0/h9+A1bjUG+zjZdEaW0ughpvAaLVsm44mFxYdlnc5uJJ43P/v+k1TqU8ApBm7VsbiCv9ZDTAxAa5oUcdbPwGNIG/xAy/nxPYAtg6vVFjSJHyZEPmUJ5pA+64AiFxl+S4P9UHih5epinxegzerAiVN8= 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.221.67 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-wr1-f67.google.com with SMTP id ffacd0b85a97d-448528f4e69so408756f8f.3 for ; Wed, 29 Apr 2026 08:18:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777475891; x=1778080691; 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=hJJfrQeEaqhpRK/hzlkX5+ypxVhHeghBlozgM+ehlX8=; b=kbeBfwPx/JaLdrvHY2txZw/zXSArxyyeRH6kvr6n6BpGaPyMBLP5kk5CzZS3Vof7E+ diYbYVAa1pt87Q29ZdWcInSuyeYXdKTpKDizJaxA/F7rqzecvLXiXKRdU7uGED2ShfEq mm5bnzcoCyb85ffpIJJqai6E23Nf2Mgiql8oQoJ7mPZDJEj6mGBLF3DdtALEwe9Y4UbC WecVtiP0ASgaxc3zC/OdDqSv3f1zQz1bPEfLdFZqMmwd3kuWvOnXuvE9crTRYNQuyGG7 kDlEyiW0f4BcqV29gLlDvkhZqVwIqF6RZ1+/ndNy3QvjSFuQM1ZjahG0rO0D2/tM6O0G belA== X-Forwarded-Encrypted: i=1; AFNElJ8f/vdBPD2QEzVE5LcTqWBoBznT6FB4ssGrHujm86RtrObeWJzeiV1divoUCFzKqC4waL/KBixLNAf+/7Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yzt2HW+IV2FC2gxZs4YA560SHQ001y3Z5oSM4Tr1JAnn3B6VHIK JWbCiiTx3w6GP7Qs00E5XXvuhlelLXJRuCF1TV17vfnoX6Q5/WLk1z3V X-Gm-Gg: AeBDietpyTr6V9f0Hakc0uWswi5nM5/t/pmupgJGnB+iFlU69acbB74/qK62RdolN2f XENnXb4pyEkNDibWk2cbkLanOojd8qbmh6/pDIrrXfftqna5RCVXxP/pZvy+kp8QwfXEZfxkDOG +teMIFfo7wWtF4B7STKi7KWWesmIRfTLKjHsFyaDJ+6MavHuB9okGw+g+dVnQnwKDVEd1hjJMVn iFM62qpZMWbXwwQmZPADBdxGJ5iVfDzXx4/gAn/qAq1qQxBmVxKc0nBOkCHG4EjxyX6ascrWhpE U5tOX7dhTpanuilhyLSYAjj/kOZwMv6JWdqFUiVika+kT6Oe/SYP0tjdb37RrnneMtfxP2FHOWw 2mmi5D8lXohud9SpNaxeP2+OmspaGTEENj+ze4e8lNGX7e1onf1ubB5ZmaEfWS/L9IgjxEshMqP uyTsFw+A/cQ+43cVo9ZO40yvWA5xp8qt3guN5ymvAGk3KmmY9rIXGki0YYBADDA6c4dB+wOA== X-Received: by 2002:a05:600c:4fcd:b0:488:a916:14a8 with SMTP id 5b1f17b1804b1-48a77af0507mr126951365e9.10.1777475890388; Wed, 29 Apr 2026 08:18:10 -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 5b1f17b1804b1-48a7c2d3811sm32358165e9.3.2026.04.29.08.18.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 08:18:09 -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 2/2] selftests: openvswitch: add tests for tunnel vport refcounting Date: Wed, 29 Apr 2026 17:16:37 +0200 Message-ID: <20260429151756.4157670-3-i.maximets@ovn.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260429151756.4157670-1-i.maximets@ovn.org> References: <20260429151756.4157670-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: Eelco Chaudron --- .../selftests/net/openvswitch/openvswitch.sh | 37 +++++++++++++++++++ .../selftests/net/openvswitch/ovs-dpctl.py | 10 ++--- 2 files changed, 42 insertions(+), 5 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..196813f476434 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -2069,7 +2069,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": @@ -2131,7 +2131,7 @@ class OvsVport(GenericNetlinkSocket): if not lwt: 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] @@ -2563,7 +2563,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 +2632,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 +2645,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