From: Bobby Eshleman <bobbyeshleman@meta.com>
To: Michal Luczaj <mhal@rbox.co>
Cc: "Stefano Garzarella" <sgarzare@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Simon Horman" <horms@kernel.org>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Jason Wang" <jasowangio@gmail.com>,
"Xuan Zhuo" <xuanzhuo@linux.alibaba.com>,
"Eugenio Pérez" <eperezma@redhat.com>,
"Shuah Khan" <shuah@kernel.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Donald Hunter" <donald.hunter@gmail.com>,
"Eric Dumazet" <edumazet@kernel.org>,
virtualization@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
sargun@sargun.me, jlinbox@meta.com
Subject: Re: [PATCH net-next v4 4/7] vsock: add a netlink command to assign the g2h device to a netns
Date: Fri, 30 Oct 2026 13:30:24 -0700 [thread overview]
Message-ID: <auT+YIawHSMPHbJI@devvm29614.prn0.facebook.com> (raw)
In-Reply-To: <d946003a-8bec-4e8b-89a3-05eeb96780cc@rbox.co>
On Thu, Oct 29, 2026 at 10:39:50PM +0100, Michal Luczaj wrote:
> On 10/22/26 12:47, Stefano Garzarella wrote:
> >>>> +/* Move @vsk to TCP_ESTABLISHED and into the connected table, unless the device
> >>>> + * has moved to a namespace @vsk cannot reach. Returns false without doing
> >>>> + * either in that case.
> >>>> + *
> >>>> + * The reset sweep walks the same table under the same lock, so an assign
> >>>> + * cannot land between the check and the insert: either the sweep finds @vsk
> >>>> + * and closes it, or @vsk is never added.
> >>>> + */
> >>>> +bool vsock_maybe_set_connected(struct vsock_sock *vsk)
> >>>> +{
> >>>> + struct list_head *list;
> >>>> + bool reachable;
> >>>> +
> >>>> + list = vsock_connected_sockets(&vsk->remote_addr, &vsk->local_addr);
> >>>> +
> >>>> + spin_lock_bh(&vsock_table_lock);
> >>>> + reachable = vsock_g2h_reachable_sk(vsk);
> >>>> + if (reachable) {
> >>>> + sk_vsock(vsk)->sk_state = TCP_ESTABLISHED;
> >>>> + __vsock_insert_connected(list, vsk);
> >>>> + }
> >>>> + spin_unlock_bh(&vsock_table_lock);
> >>>> +
> >>>> + return reachable;
> >>>> +}
> >>>> +EXPORT_SYMBOL_GPL(vsock_maybe_set_connected);
> >>>> +
> >>>> +static bool vsock_g2h_should_reset(struct vsock_sock *vsk,
> >>>> + const struct vsock_transport *t)
> >>>> +{
> >>>> + return vsk->transport == t &&
> >>>> + READ_ONCE(sk_vsock(vsk)->sk_state) != TCP_CLOSE &&
> >>>> + !READ_ONCE(vsk->close_work_scheduled) &&
> >>>> + !vsock_g2h_reachable_sk(vsk);
> >>>> +}
> >>>> +
> >>>> +static struct vsock_sock *
> >>>> +vsock_g2h_next_unreachable(const struct vsock_transport *t, unsigned int *i)
> >>>> +{
> >>>> + struct vsock_sock *vsk;
> >>>> +
> >>>> + spin_lock_bh(&vsock_table_lock);
> >>>> +
> >>>> + for (; *i < ARRAY_SIZE(vsock_connected_table); (*i)++) {
> >>>> + list_for_each_entry(vsk, &vsock_connected_table[*i],
> >>>> + connected_table) {
> >>>> + if (vsock_g2h_should_reset(vsk, t)) {
> >>>> + sock_hold(sk_vsock(vsk));
> >>>> + spin_unlock_bh(&vsock_table_lock);
> >>>> + return vsk;
> >>>> + }
> >>>> + }
> >>>> + }
> >>>> +
> >>>> + spin_unlock_bh(&vsock_table_lock);
> >>>> +
> >>>> + return NULL;
> >>>> +}
> >>>> +
> >>>> +/* Close every connected socket of @t that can no longer reach the g2h device.
> >>>> + */
> >>>> +static void vsock_g2h_reset_unreachable(const struct vsock_transport *t)
> >>>> +{
> >>>> + struct vsock_sock *vsk;
> >>>> + unsigned int i = 0;
> >>>> + struct sock *sk;
> >>>> + bool reset;
> >>>> +
> >>>> + lockdep_assert_held(&vsock_g2h_assign_mutex);
> >>>> + lockdep_assert_not_held(&vsock_register_mutex);
> >>>> +
> >>>> + while ((vsk = vsock_g2h_next_unreachable(t, &i))) {
> >>>
> >>> can we reuse vsock_for_each_connected_socket() ?
> >>>
> >>> If not, maybe a comment here will be nice and maybe I'll try to merge
> >>> vsock_g2h_next_unreachable() here if it's not used somewhere else.
> >>
> >> I think we would need a variant that returns the socket, since we need
> >> to be able to acquire the lock_sock after releasing the
> >> vsock_table_lock.
> >
> > That would be nice if it's not too complicated.
> >
> >>
> >> Maybe the callback could return a bool, if true then return socket
> >> otherwise skip. Then the cb could also grab the sock_hold ref under the
> >> table lock.
> >
> > Yeah, looks promising to me!
> >
> >>
> >>>
> >>> I find these functions a bit hard to read.
> >>
> >> Yeah its all kind of a pain. The problem is that we need to hold
> >> sock_lock to set sk_state and sk_err, but can't acquire it under the
> >> table lock. Instead, we grab the socket ref sock_hold under the table
> >> lock to guarantee it stays alive between releasing the table lock and
> >> grabbing the socket lock.
> >>
> >> I was really tempted to not do this lock_sock dance though. The race
> >> condition I'm avoiding here is that if this reset races with an RST
> >> receive, then the socket could end up with TCP_CLOSING + sk_err
> >> ECONNRESET... but I'm not sure this actually propagates up into a real
> >> problem for any potential user.
>
> Right, vsock_connect() is fragile. Two things to be cautious about:
> 1. Don't let it reset the already connected socket. Because that would
> allow user to "re-connect()" and make mess in connected_table.
> 2. Don't let it re-assign transport of an already connected socket. Because
> that breaks the contract in few places.
>
> State 1 is not an issue: vsock_g2h_reset_unreachable() calls
> __vsock_remove_connected().
>
> State 2 may be problematic: if vsock_g2h_reset_unreachable() sets TCP_CLOSE
> when connect() is scheduled out, then after the wake-up sock may get reset
> to SS_UNCONNECTED. Then user re-connect()s and hits the transport
> re-assignment logic. I'm worried that, as we re-assign, someone may be
> holding a reference to such "connected" (even if not in connected_table
> anymore) vsock.
I see path you're looking at... after vsock_connect() gets scheduled
back in we set TCP_CLOSE/SS_UNCONNECTED if sock_error returns non-zero.
Could you elaborate on your last concern there about someone holding a
reference? I'm not sure I fully understood.
>
> So I don't know, maybe it's vsock_connect() that should be fixed/hardened
> instead?
>
> Or at least disallow transport *re*-assignment? Does the "re-" part have a
> use case?
>
> Hope it's not too off-topic.
>
> >> It also avoided some racing with the tx path, but now that send_pkt()
> >> also checks reachability I think that path is safe.
> >>
> >> What do you think about doing the below hunk (TCP_CLOSE, ECONNRESET,
> >> sk_error_report) with no lock_sock?
> >
> > Looking at the code, it seems that in all the places where we close all
> > connections (virtio_vsock_reset_sock, vhost_vsock_reset_orphans) we do
> > with no lock_sock but with vsock_table_lock.
> >
> > So, makes sense to me.
>
> virtio_vsock_reset_sock() and vhost_vsock_reset_orphans() are my pet
> peeves: state switcheroo without taking lock_sock(). Which, again, races
> vsock_connect().
True, I don't love that either, but I feel the impact is at least
constrained by the fact that it only happens when the module or device
is already going away.
Best,
Bobby
next prev parent reply other threads:[~2026-10-30 20:31 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 1:15 [PATCH net-next v4 0/7] vsock: assign the guest vsock device to a network namespace Bobby Eshleman
2026-10-21 1:15 ` [PATCH net-next v4 1/7] vsock: constify the transport in vsock_for_each_connected_socket() Bobby Eshleman
2026-10-21 1:15 ` [PATCH net-next v4 2/7] vsock: rename the vsock pernet operations Bobby Eshleman
2026-10-21 10:11 ` Stefano Garzarella
2026-10-21 1:15 ` [PATCH net-next v4 3/7] vsock: pass the netns to ->has_remote_cid() Bobby Eshleman
2026-10-21 10:14 ` Stefano Garzarella
2026-10-21 1:15 ` [PATCH net-next v4 4/7] vsock: add a netlink command to assign the g2h device to a netns Bobby Eshleman
2026-10-21 16:55 ` Stefano Garzarella
2026-10-22 0:50 ` Bobby Eshleman
2026-10-22 10:47 ` Stefano Garzarella
2026-10-29 21:39 ` Michal Luczaj
2026-10-30 20:30 ` Bobby Eshleman [this message]
2026-10-21 1:15 ` [PATCH net-next v4 5/7] vsock/virtio: support guest device network namespace Bobby Eshleman
2026-10-21 17:03 ` Stefano Garzarella
2026-10-21 1:15 ` [PATCH net-next v4 6/7] selftests/vsock: test the guest vsock " Bobby Eshleman
2026-10-21 1:15 ` [PATCH net-next v4 7/7] selftests/vsock: test the netns assign privilege checks Bobby Eshleman
2026-10-21 1:35 ` [PATCH net-next v4 0/7] vsock: assign the guest vsock device to a network namespace Jakub Kicinski
2026-10-21 9:48 ` Stefano Garzarella
2026-10-21 22:46 ` Bobby Eshleman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auT+YIawHSMPHbJI@devvm29614.prn0.facebook.com \
--to=bobbyeshleman@meta.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@kernel.org \
--cc=eperezma@redhat.com \
--cc=horms@kernel.org \
--cc=jasowangio@gmail.com \
--cc=jlinbox@meta.com \
--cc=kuba@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mhal@rbox.co \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=sargun@sargun.me \
--cc=sgarzare@redhat.com \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox