Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
handled by vsock's implementation.
Signed-off-by: Michal Luczaj <mhal@rbox.co>
---
tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 9e1250790f33..8ec8f0844e22 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
close(fd);
}
+static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
+ if (fd < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+
+ vsock_wait_remote_close(fd);
+ close(fd);
+}
+
+static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
+{
+ int fd;
+
+ fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
+ if (fd < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+
+ enable_so_zerocopy_check(fd);
+ close(fd);
+}
+
static struct test_case test_cases[] = {
{
.name = "SOCK_STREAM connection reset",
@@ -2371,6 +2399,11 @@ static struct test_case test_cases[] = {
.run_client = test_seqpacket_unread_bytes_client,
.run_server = test_seqpacket_unread_bytes_server,
},
+ {
+ .name = "SOCK_STREAM accept()ed socket custom setsockopt()",
+ .run_client = test_stream_accepted_setsockopt_client,
+ .run_server = test_stream_accepted_setsockopt_server,
+ },
{},
};
--
2.52.0
On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>handled by vsock's implementation.
>
>Signed-off-by: Michal Luczaj <mhal@rbox.co>
>---
> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
>diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>index 9e1250790f33..8ec8f0844e22 100644
>--- a/tools/testing/vsock/vsock_test.c
>+++ b/tools/testing/vsock/vsock_test.c
>@@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
> close(fd);
> }
>
>+static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>+{
>+ int fd;
>+
>+ fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>+ if (fd < 0) {
>+ perror("connect");
>+ exit(EXIT_FAILURE);
>+ }
>+
>+ vsock_wait_remote_close(fd);
>+ close(fd);
>+}
>+
>+static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>+{
>+ int fd;
>+
>+ fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>+ if (fd < 0) {
>+ perror("accept");
>+ exit(EXIT_FAILURE);
>+ }
>+
>+ enable_so_zerocopy_check(fd);
This test is passing on my env also without the patch applied.
Is that expected?
Thanks,
Stefano
>+ close(fd);
>+}
>+
> static struct test_case test_cases[] = {
> {
> .name = "SOCK_STREAM connection reset",
>@@ -2371,6 +2399,11 @@ static struct test_case test_cases[] = {
> .run_client = test_seqpacket_unread_bytes_client,
> .run_server = test_seqpacket_unread_bytes_server,
> },
>+ {
>+ .name = "SOCK_STREAM accept()ed socket custom setsockopt()",
>+ .run_client = test_stream_accepted_setsockopt_client,
>+ .run_server = test_stream_accepted_setsockopt_server,
>+ },
> {},
> };
>
>
>--
>2.52.0
>
On 12/23/25 11:27, Stefano Garzarella wrote:
> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>> handled by vsock's implementation.
>>
>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>> ---
>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>> 1 file changed, 33 insertions(+)
>>
>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>> index 9e1250790f33..8ec8f0844e22 100644
>> --- a/tools/testing/vsock/vsock_test.c
>> +++ b/tools/testing/vsock/vsock_test.c
>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>> close(fd);
>> }
>>
>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>> +{
>> + int fd;
>> +
>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>> + if (fd < 0) {
>> + perror("connect");
>> + exit(EXIT_FAILURE);
>> + }
>> +
>> + vsock_wait_remote_close(fd);
>> + close(fd);
>> +}
>> +
>> +static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>> +{
>> + int fd;
>> +
>> + fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>> + if (fd < 0) {
>> + perror("accept");
>> + exit(EXIT_FAILURE);
>> + }
>> +
>> + enable_so_zerocopy_check(fd);
>
> This test is passing on my env also without the patch applied.
>
> Is that expected?
Oh, no, definitely not. It fails for me:
36 - SOCK_STREAM accept()ed socket custom setsockopt()...36 - SOCK_STREAM
accept()ed socket custom setsockopt()...setsockopt err: Operation not
supported (95)
setsockopt SO_ZEROCOPY val 1
I have no idea what's going on :)
On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>On 12/23/25 11:27, Stefano Garzarella wrote:
>> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>> handled by vsock's implementation.
>>>
>>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>> ---
>>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>> 1 file changed, 33 insertions(+)
>>>
>>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>> index 9e1250790f33..8ec8f0844e22 100644
>>> --- a/tools/testing/vsock/vsock_test.c
>>> +++ b/tools/testing/vsock/vsock_test.c
>>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>> close(fd);
>>> }
>>>
>>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>> +{
>>> + int fd;
>>> +
>>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>> + if (fd < 0) {
>>> + perror("connect");
>>> + exit(EXIT_FAILURE);
>>> + }
>>> +
>>> + vsock_wait_remote_close(fd);
>>> + close(fd);
>>> +}
>>> +
>>> +static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>>> +{
>>> + int fd;
>>> +
>>> + fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>>> + if (fd < 0) {
>>> + perror("accept");
>>> + exit(EXIT_FAILURE);
>>> + }
>>> +
>>> + enable_so_zerocopy_check(fd);
>>
>> This test is passing on my env also without the patch applied.
>>
>> Is that expected?
>
>Oh, no, definitely not. It fails for me:
>36 - SOCK_STREAM accept()ed socket custom setsockopt()...36 - SOCK_STREAM
>accept()ed socket custom setsockopt()...setsockopt err: Operation not
>supported (95)
>setsockopt SO_ZEROCOPY val 1
aaa, right, the server is failing, sorry ;-)
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
>I have no idea what's going on :)
>
In my suite, I'm checking the client, and if the last test fails only on
the server, I'm missing it. I'd fix my suite, and maybe also vsock_test
adding another sync point.
Thanks,
Stefano
On Tue, Dec 23, 2025 at 02:20:33PM +0100, Stefano Garzarella wrote:
>On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>>On 12/23/25 11:27, Stefano Garzarella wrote:
>>>On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>>>Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>>>handled by vsock's implementation.
>>>>
>>>>Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>>>---
>>>>tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>>>1 file changed, 33 insertions(+)
>>>>
>>>>diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>>>index 9e1250790f33..8ec8f0844e22 100644
>>>>--- a/tools/testing/vsock/vsock_test.c
>>>>+++ b/tools/testing/vsock/vsock_test.c
>>>>@@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>>> close(fd);
>>>>}
>>>>
>>>>+static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>>>+{
>>>>+ int fd;
>>>>+
>>>>+ fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>>>+ if (fd < 0) {
>>>>+ perror("connect");
>>>>+ exit(EXIT_FAILURE);
>>>>+ }
>>>>+
>>>>+ vsock_wait_remote_close(fd);
On a second look, why we need to wait the remote close?
can we just have a control message?
I'm not sure even on that, I mean why this peer can't close the
connection while the other is checking if it's able to set zerocopy?
>>>>+ close(fd);
>>>>+}
>>>>+
>>>>+static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>>>>+{
>>>>+ int fd;
>>>>+
>>>>+ fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>>>>+ if (fd < 0) {
>>>>+ perror("accept");
>>>>+ exit(EXIT_FAILURE);
>>>>+ }
>>>>+
>>>>+ enable_so_zerocopy_check(fd);
>>>
>>>This test is passing on my env also without the patch applied.
>>>
>>>Is that expected?
>>
>>Oh, no, definitely not. It fails for me:
>>36 - SOCK_STREAM accept()ed socket custom setsockopt()...36 - SOCK_STREAM
>>accept()ed socket custom setsockopt()...setsockopt err: Operation not
>>supported (95)
>>setsockopt SO_ZEROCOPY val 1
>
>aaa, right, the server is failing, sorry ;-)
>
>Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>>
>>I have no idea what's going on :)
>>
>
>In my suite, I'm checking the client, and if the last test fails only
>on the server, I'm missing it. I'd fix my suite, and maybe also
>vsock_test adding another sync point.
Added a full barrier here:
https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com
Thanks,
Stefano
On 12/23/25 17:50, Stefano Garzarella wrote:
> On Tue, Dec 23, 2025 at 02:20:33PM +0100, Stefano Garzarella wrote:
>> On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>>> On 12/23/25 11:27, Stefano Garzarella wrote:
>>>> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>>>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>>>> handled by vsock's implementation.
>>>>>
>>>>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>>>> ---
>>>>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 33 insertions(+)
>>>>>
>>>>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>>>> index 9e1250790f33..8ec8f0844e22 100644
>>>>> --- a/tools/testing/vsock/vsock_test.c
>>>>> +++ b/tools/testing/vsock/vsock_test.c
>>>>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>>>> close(fd);
>>>>> }
>>>>>
>>>>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>>>> +{
>>>>> + int fd;
>>>>> +
>>>>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>>>> + if (fd < 0) {
>>>>> + perror("connect");
>>>>> + exit(EXIT_FAILURE);
>>>>> + }
>>>>> +
>>>>> + vsock_wait_remote_close(fd);
>
> On a second look, why we need to wait the remote close?
> can we just have a control message?
I think we can. I've used vsock_wait_remote_close() simply as a sync
primitive. It's one line of code less.
> I'm not sure even on that, I mean why this peer can't close the
> connection while the other is checking if it's able to set zerocopy?
I was worried that without any sync, client-side close() may race
server-side accept(), but I've just checked and it doesn't seem to cause
any issues, at least for the virtio transports.
>>>>> + close(fd);
>>>>> +}
>>>>> +
>>>>> +static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>>>>> +{
>>>>> + int fd;
>>>>> +
>>>>> + fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>>>>> + if (fd < 0) {
>>>>> + perror("accept");
>>>>> + exit(EXIT_FAILURE);
>>>>> + }
>>>>> +
>>>>> + enable_so_zerocopy_check(fd);
>>>>
>>>> This test is passing on my env also without the patch applied.
>>>>
>>>> Is that expected?
>>>
>>> Oh, no, definitely not. It fails for me:
>>> 36 - SOCK_STREAM accept()ed socket custom setsockopt()...36 - SOCK_STREAM
>>> accept()ed socket custom setsockopt()...setsockopt err: Operation not
>>> supported (95)
>>> setsockopt SO_ZEROCOPY val 1
>>
>> aaa, right, the server is failing, sorry ;-)
>>
>> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>>>
>>> I have no idea what's going on :)
>>>
>>
>> In my suite, I'm checking the client, and if the last test fails only
>> on the server, I'm missing it. I'd fix my suite, and maybe also
>> vsock_test adding another sync point.
>
> Added a full barrier here:
> https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com
Which reminds me of discussion in
https://lore.kernel.org/netdev/151bf5fe-c9ca-4244-aa21-8d7b8ff2470f@rbox.co/
. Sorry for postponing, I've put it on my vsock-cleanups branch and kept
adding more little fixes, and it was never the right time to post the series.
On Tue, Dec 23, 2025 at 09:38:07PM +0100, Michal Luczaj wrote:
>On 12/23/25 17:50, Stefano Garzarella wrote:
>> On Tue, Dec 23, 2025 at 02:20:33PM +0100, Stefano Garzarella wrote:
>>> On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>>>> On 12/23/25 11:27, Stefano Garzarella wrote:
>>>>> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>>>>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>>>>> handled by vsock's implementation.
>>>>>>
>>>>>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>>>>> ---
>>>>>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>>>>> 1 file changed, 33 insertions(+)
>>>>>>
>>>>>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>>>>> index 9e1250790f33..8ec8f0844e22 100644
>>>>>> --- a/tools/testing/vsock/vsock_test.c
>>>>>> +++ b/tools/testing/vsock/vsock_test.c
>>>>>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>>>>> close(fd);
>>>>>> }
>>>>>>
>>>>>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>>>>> +{
>>>>>> + int fd;
>>>>>> +
>>>>>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>>>>> + if (fd < 0) {
>>>>>> + perror("connect");
>>>>>> + exit(EXIT_FAILURE);
>>>>>> + }
>>>>>> +
>>>>>> + vsock_wait_remote_close(fd);
>>
>> On a second look, why we need to wait the remote close?
>> can we just have a control message?
>
>I think we can. I've used vsock_wait_remote_close() simply as a sync
>primitive. It's one line of code less.
>
>> I'm not sure even on that, I mean why this peer can't close the
>> connection while the other is checking if it's able to set zerocopy?
>
>I was worried that without any sync, client-side close() may race
>server-side accept(), but I've just checked and it doesn't seem to cause
>any issues, at least for the virtio transports.
Okay, I see. Feel free to leave it, but if it's not really needed, I'd
prefer to keep the tests as simple as possible.
>
>>>>>> + close(fd);
>>>>>> +}
>>>>>> +
>>>>>> +static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
>>>>>> +{
>>>>>> + int fd;
>>>>>> +
>>>>>> + fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
>>>>>> + if (fd < 0) {
>>>>>> + perror("accept");
>>>>>> + exit(EXIT_FAILURE);
>>>>>> + }
>>>>>> +
>>>>>> + enable_so_zerocopy_check(fd);
>>>>>
>>>>> This test is passing on my env also without the patch applied.
>>>>>
>>>>> Is that expected?
>>>>
>>>> Oh, no, definitely not. It fails for me:
>>>> 36 - SOCK_STREAM accept()ed socket custom setsockopt()...36 - SOCK_STREAM
>>>> accept()ed socket custom setsockopt()...setsockopt err: Operation not
>>>> supported (95)
>>>> setsockopt SO_ZEROCOPY val 1
>>>
>>> aaa, right, the server is failing, sorry ;-)
>>>
>>> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>>>>
>>>> I have no idea what's going on :)
>>>>
>>>
>>> In my suite, I'm checking the client, and if the last test fails only
>>> on the server, I'm missing it. I'd fix my suite, and maybe also
>>> vsock_test adding another sync point.
>>
>> Added a full barrier here:
>> https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com
>
>Which reminds me of discussion in
>https://lore.kernel.org/netdev/151bf5fe-c9ca-4244-aa21-8d7b8ff2470f@rbox.co/
Oh, I forgot that we already discussed that.
My first attempt was exactly that, but then discovered that it didn't
add too much except for the last one since for the others we have 2 full
barriers back to back, so I preferred to move outside the loop. In that
way we can also be sure the 2 `vsock_tests` are in sync with the amount
of tests to run.
But yeah, also that one fix the issue.
>. Sorry for postponing, I've put it on my vsock-cleanups branch and kept
>adding more little fixes, and it was never the right time to post the series.
>
Nah, don't apologize, you're doing an amazing job!
Thanks,
Stefano
On 12/24/25 10:15, Stefano Garzarella wrote:
> On Tue, Dec 23, 2025 at 09:38:07PM +0100, Michal Luczaj wrote:
>> On 12/23/25 17:50, Stefano Garzarella wrote:
>>> On Tue, Dec 23, 2025 at 02:20:33PM +0100, Stefano Garzarella wrote:
>>>> On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>>>>> On 12/23/25 11:27, Stefano Garzarella wrote:
>>>>>> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>>>>>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>>>>>> handled by vsock's implementation.
>>>>>>>
>>>>>>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>>>>>> ---
>>>>>>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>>>>>> 1 file changed, 33 insertions(+)
>>>>>>>
>>>>>>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>>>>>> index 9e1250790f33..8ec8f0844e22 100644
>>>>>>> --- a/tools/testing/vsock/vsock_test.c
>>>>>>> +++ b/tools/testing/vsock/vsock_test.c
>>>>>>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>>>>>> close(fd);
>>>>>>> }
>>>>>>>
>>>>>>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>>>>>> +{
>>>>>>> + int fd;
>>>>>>> +
>>>>>>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>>>>>> + if (fd < 0) {
>>>>>>> + perror("connect");
>>>>>>> + exit(EXIT_FAILURE);
>>>>>>> + }
>>>>>>> +
>>>>>>> + vsock_wait_remote_close(fd);
>>>
>>> On a second look, why we need to wait the remote close?
>>> can we just have a control message?
>>
>> I think we can. I've used vsock_wait_remote_close() simply as a sync
>> primitive. It's one line of code less.
>>
>>> I'm not sure even on that, I mean why this peer can't close the
>>> connection while the other is checking if it's able to set zerocopy?
>>
>> I was worried that without any sync, client-side close() may race
>> server-side accept(), but I've just checked and it doesn't seem to cause
>> any issues, at least for the virtio transports.
>
> Okay, I see. Feel free to leave it, but if it's not really needed, I'd
> prefer to keep the tests as simple as possible.
OK, dropping the sync here. It will be interesting to see if it ever blows up.
...
>>>> In my suite, I'm checking the client, and if the last test fails only
>>>> on the server, I'm missing it. I'd fix my suite, and maybe also
>>>> vsock_test adding another sync point.
>>>
>>> Added a full barrier here:
>>> https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com
>>
>> Which reminds me of discussion in
>> https://lore.kernel.org/netdev/151bf5fe-c9ca-4244-aa21-8d7b8ff2470f@rbox.co/
>
> Oh, I forgot that we already discussed that.
>
> My first attempt was exactly that, but then discovered that it didn't
> add too much except for the last one since for the others we have 2 full
> barriers back to back, so I preferred to move outside the loop. In that
> way we can also be sure the 2 `vsock_tests` are in sync with the amount
> of tests to run.
Might it be that we're solving different issues?
I was annoyed by the next test's name/prompt being printed when the
previous test is still running on the other side. Which happens e.g. when
one side takes longer than the other. Or when one of the sides is
unimplemented.
How about something like below; would that cover your case as well?
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index d843643ced6b..5d94ffd2fa82 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -495,7 +495,7 @@ void run_tests(const struct test_case *test_cases,
printf("skipped\n");
free(line);
- continue;
+ goto sync;
}
control_cmpln(line, "NEXT", true);
@@ -510,6 +510,9 @@ void run_tests(const struct test_case *test_cases,
run(opts);
printf("ok\n");
+sync:
+ control_writeln("RUN_TESTS_SYNC");
+ control_expectln("RUN_TESTS_SYNC");
}
}
On Mon, Dec 29, 2025 at 08:40:22PM +0100, Michal Luczaj wrote:
>On 12/24/25 10:15, Stefano Garzarella wrote:
>> On Tue, Dec 23, 2025 at 09:38:07PM +0100, Michal Luczaj wrote:
>>> On 12/23/25 17:50, Stefano Garzarella wrote:
>>>> On Tue, Dec 23, 2025 at 02:20:33PM +0100, Stefano Garzarella wrote:
>>>>> On Tue, Dec 23, 2025 at 12:10:25PM +0100, Michal Luczaj wrote:
>>>>>> On 12/23/25 11:27, Stefano Garzarella wrote:
>>>>>>> On Tue, Dec 23, 2025 at 10:15:29AM +0100, Michal Luczaj wrote:
>>>>>>>> Make sure setsockopt(SOL_SOCKET, SO_ZEROCOPY) on an accept()ed socket is
>>>>>>>> handled by vsock's implementation.
>>>>>>>>
>>>>>>>> Signed-off-by: Michal Luczaj <mhal@rbox.co>
>>>>>>>> ---
>>>>>>>> tools/testing/vsock/vsock_test.c | 33 +++++++++++++++++++++++++++++++++
>>>>>>>> 1 file changed, 33 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>>>>>>>> index 9e1250790f33..8ec8f0844e22 100644
>>>>>>>> --- a/tools/testing/vsock/vsock_test.c
>>>>>>>> +++ b/tools/testing/vsock/vsock_test.c
>>>>>>>> @@ -2192,6 +2192,34 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
>>>>>>>> close(fd);
>>>>>>>> }
>>>>>>>>
>>>>>>>> +static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
>>>>>>>> +{
>>>>>>>> + int fd;
>>>>>>>> +
>>>>>>>> + fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
>>>>>>>> + if (fd < 0) {
>>>>>>>> + perror("connect");
>>>>>>>> + exit(EXIT_FAILURE);
>>>>>>>> + }
>>>>>>>> +
>>>>>>>> + vsock_wait_remote_close(fd);
>>>>
>>>> On a second look, why we need to wait the remote close?
>>>> can we just have a control message?
>>>
>>> I think we can. I've used vsock_wait_remote_close() simply as a sync
>>> primitive. It's one line of code less.
>>>
>>>> I'm not sure even on that, I mean why this peer can't close the
>>>> connection while the other is checking if it's able to set zerocopy?
>>>
>>> I was worried that without any sync, client-side close() may race
>>> server-side accept(), but I've just checked and it doesn't seem to cause
>>> any issues, at least for the virtio transports.
>>
>> Okay, I see. Feel free to leave it, but if it's not really needed, I'd
>> prefer to keep the tests as simple as possible.
>
>OK, dropping the sync here. It will be interesting to see if it ever blows up.
>
>...
>>>>> In my suite, I'm checking the client, and if the last test fails only
>>>>> on the server, I'm missing it. I'd fix my suite, and maybe also
>>>>> vsock_test adding another sync point.
>>>>
>>>> Added a full barrier here:
>>>> https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com
>>>
>>> Which reminds me of discussion in
>>> https://lore.kernel.org/netdev/151bf5fe-c9ca-4244-aa21-8d7b8ff2470f@rbox.co/
>>
>> Oh, I forgot that we already discussed that.
>>
>> My first attempt was exactly that, but then discovered that it didn't
>> add too much except for the last one since for the others we have 2 full
>> barriers back to back, so I preferred to move outside the loop. In that
>> way we can also be sure the 2 `vsock_tests` are in sync with the amount
>> of tests to run.
>
>Might it be that we're solving different issues?
>
>I was annoyed by the next test's name/prompt being printed when the
>previous test is still running on the other side. Which happens e.g. when
>one side takes longer than the other. Or when one of the sides is
>unimplemented.
I don't see this that bad, because this will show us exactly what is
going on. One peer did everything well in its test function and it's
ready to start the next test, while the other is having some kind of
trouble at the end of the test.
If a test really want to be sure that one peer should wait the other
(for some reason), should explicitly set a sync point like we already do
in some cases.
>
>How about something like below; would that cover your case as well?
>
>diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
>index d843643ced6b..5d94ffd2fa82 100644
>--- a/tools/testing/vsock/util.c
>+++ b/tools/testing/vsock/util.c
>@@ -495,7 +495,7 @@ void run_tests(const struct test_case *test_cases,
> printf("skipped\n");
>
> free(line);
>- continue;
>+ goto sync;
> }
>
> control_cmpln(line, "NEXT", true);
>@@ -510,6 +510,9 @@ void run_tests(const struct test_case *test_cases,
> run(opts);
>
> printf("ok\n");
>+sync:
>+ control_writeln("RUN_TESTS_SYNC");
>+ control_expectln("RUN_TESTS_SYNC");
> }
> }
>
This was my first attempt, but except for the first test, we have
essentially 2 full barrier back to back, that IMO is not really great.
BTW I think it's better to continue that discussion on
https://lore.kernel.org/netdev/20251223162210.43976-1-sgarzare@redhat.com/
Thanks,
Stefano
© 2016 - 2026 Red Hat, Inc.