* [PATCH net-next v2 0/3] vsock: Introduce SIOCINQ ioctl support
@ 2025-06-13 3:11 Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Xuewei Niu @ 2025-06-13 3:11 UTC (permalink / raw)
To: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha
Cc: virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
This patchset introduces SIOCINQ ioctl support for vsock, indicating the
length of unread bytes.
Similar with SIOCOUTQ ioctl, the information is transport-dependent.
The first patch introduces a new callback, unread_bytes, in vsock
transport, and adds ioctl support in AF_VSOCK.
The second patch implements the SIOCINQ ioctl for all virtio-based transports.
The last one adds two test cases to check the functionality. The changes
have been tested, and the results are as expected.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
--
v1->v2:
https://lore.kernel.org/lkml/20250519070649.3063874-1-niuxuewei.nxw@antgroup.com/
- Use net-next tree.
- Reuse `rx_bytes` to count unread bytes.
- Wrap ioctl syscall with an int pointer argument to implement a retry
mechanism.
Xuewei Niu (3):
vsock: Add support for SIOCINQ ioctl
vsock/virtio: Add SIOCINQ support for all virtio based transports
test/vsock: Add ioctl SIOCINQ tests
drivers/vhost/vsock.c | 1 +
include/linux/virtio_vsock.h | 1 +
include/net/af_vsock.h | 2 +
net/vmw_vsock/af_vsock.c | 22 +++++++
net/vmw_vsock/virtio_transport.c | 1 +
net/vmw_vsock/virtio_transport_common.c | 13 ++++
net/vmw_vsock/vsock_loopback.c | 1 +
tools/testing/vsock/util.c | 36 ++++++++---
tools/testing/vsock/util.h | 2 +
tools/testing/vsock/vsock_test.c | 83 ++++++++++++++++++++++++-
10 files changed, 152 insertions(+), 10 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-13 3:11 [PATCH net-next v2 0/3] vsock: Introduce SIOCINQ ioctl support Xuewei Niu
@ 2025-06-13 3:11 ` Xuewei Niu
2025-06-16 13:42 ` Luigi Leonardi
2025-06-16 13:53 ` Stefano Garzarella
2025-06-13 3:11 ` [PATCH net-next v2 2/3] vsock/virtio: Add SIOCINQ support for all virtio based transports Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests Xuewei Niu
2 siblings, 2 replies; 13+ messages in thread
From: Xuewei Niu @ 2025-06-13 3:11 UTC (permalink / raw)
To: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha
Cc: virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
This patch adds support for SIOCINQ ioctl, which returns the number of
bytes unread in the socket.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
include/net/af_vsock.h | 2 ++
net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index d56e6e135158..723a886253ba 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -171,6 +171,8 @@ struct vsock_transport {
/* SIOCOUTQ ioctl */
ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
+ /* SIOCINQ ioctl */
+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
/* Shutdown. */
int (*shutdown)(struct vsock_sock *, int);
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 2e7a3034e965..466b1ebadbbc 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
vsk = vsock_sk(sk);
switch (cmd) {
+ case SIOCINQ: {
+ ssize_t n_bytes;
+
+ if (!vsk->transport || !vsk->transport->unread_bytes) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (sock_type_connectible(sk->sk_type) &&
+ sk->sk_state == TCP_LISTEN) {
+ ret = -EINVAL;
+ break;
+ }
+
+ n_bytes = vsk->transport->unread_bytes(vsk);
+ if (n_bytes < 0) {
+ ret = n_bytes;
+ break;
+ }
+ ret = put_user(n_bytes, arg);
+ break;
+ }
case SIOCOUTQ: {
ssize_t n_bytes;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 2/3] vsock/virtio: Add SIOCINQ support for all virtio based transports
2025-06-13 3:11 [PATCH net-next v2 0/3] vsock: Introduce SIOCINQ ioctl support Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
@ 2025-06-13 3:11 ` Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests Xuewei Niu
2 siblings, 0 replies; 13+ messages in thread
From: Xuewei Niu @ 2025-06-13 3:11 UTC (permalink / raw)
To: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha
Cc: virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
The value of the SIOCINQ is obtained by `virtio_transport_unread_bytes()`,
which is generic for all virtio transports. The function acquires the
`rx_lock` and returns the value of `rx_bytes`.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
drivers/vhost/vsock.c | 1 +
include/linux/virtio_vsock.h | 1 +
net/vmw_vsock/virtio_transport.c | 1 +
net/vmw_vsock/virtio_transport_common.c | 13 +++++++++++++
net/vmw_vsock/vsock_loopback.c | 1 +
5 files changed, 17 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 802153e23073..0f20af6e5036 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -452,6 +452,7 @@ static struct virtio_transport vhost_transport = {
.notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat,
.unsent_bytes = virtio_transport_unsent_bytes,
+ .unread_bytes = virtio_transport_unread_bytes,
.read_skb = virtio_transport_read_skb,
},
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 36fb3edfa403..74c50224431e 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -196,6 +196,7 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk);
u32 virtio_transport_seqpacket_has_data(struct vsock_sock *vsk);
ssize_t virtio_transport_unsent_bytes(struct vsock_sock *vsk);
+ssize_t virtio_transport_unread_bytes(struct vsock_sock *vsk);
void virtio_transport_consume_skb_sent(struct sk_buff *skb,
bool consume);
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index f0e48e6911fc..917881537b63 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -585,6 +585,7 @@ static struct virtio_transport virtio_transport = {
.notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat,
.unsent_bytes = virtio_transport_unsent_bytes,
+ .unread_bytes = virtio_transport_unread_bytes,
.read_skb = virtio_transport_read_skb,
},
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 1b5d9896edae..59e72d2dbd85 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1135,6 +1135,19 @@ ssize_t virtio_transport_unsent_bytes(struct vsock_sock *vsk)
}
EXPORT_SYMBOL_GPL(virtio_transport_unsent_bytes);
+ssize_t virtio_transport_unread_bytes(struct vsock_sock *vsk)
+{
+ struct virtio_vsock_sock *vvs = vsk->trans;
+ size_t ret;
+
+ spin_lock_bh(&vvs->rx_lock);
+ ret = vvs->rx_bytes;
+ spin_unlock_bh(&vvs->rx_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(virtio_transport_unread_bytes);
+
static int virtio_transport_reset(struct vsock_sock *vsk,
struct sk_buff *skb)
{
diff --git a/net/vmw_vsock/vsock_loopback.c b/net/vmw_vsock/vsock_loopback.c
index 6e78927a598e..13a77db2a76f 100644
--- a/net/vmw_vsock/vsock_loopback.c
+++ b/net/vmw_vsock/vsock_loopback.c
@@ -99,6 +99,7 @@ static struct virtio_transport loopback_transport = {
.notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat,
.unsent_bytes = virtio_transport_unsent_bytes,
+ .unread_bytes = virtio_transport_unread_bytes,
.read_skb = virtio_transport_read_skb,
},
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests
2025-06-13 3:11 [PATCH net-next v2 0/3] vsock: Introduce SIOCINQ ioctl support Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 2/3] vsock/virtio: Add SIOCINQ support for all virtio based transports Xuewei Niu
@ 2025-06-13 3:11 ` Xuewei Niu
2025-06-16 13:59 ` Stefano Garzarella
2 siblings, 1 reply; 13+ messages in thread
From: Xuewei Niu @ 2025-06-13 3:11 UTC (permalink / raw)
To: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha
Cc: virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
This patch adds SIOCINQ ioctl tests for both SOCK_STREAM and
SOCK_SEQPACKET.
The client waits for the server to send data, and checks if the SIOCINQ
ioctl value matches the data size. After consuming the data, the client
checks if the SIOCINQ value is 0.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
tools/testing/vsock/util.c | 36 ++++++++++----
tools/testing/vsock/util.h | 2 +
tools/testing/vsock/vsock_test.c | 83 +++++++++++++++++++++++++++++++-
3 files changed, 111 insertions(+), 10 deletions(-)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 0c7e9cbcbc85..472246198966 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -97,28 +97,46 @@ void vsock_wait_remote_close(int fd)
close(epollfd);
}
-/* Wait until transport reports no data left to be sent.
- * Return false if transport does not implement the unsent_bytes() callback.
+/* Wait until ioctl gives an expected int value.
+ * Return a negative value if the op is not supported.
*/
-bool vsock_wait_sent(int fd)
+int ioctl_int(int fd, unsigned long op, int *actual, int expected)
{
- int ret, sock_bytes_unsent;
+ int ret;
+ char name[32];
+
+ if (!actual) {
+ fprintf(stderr, "%s requires a non-null pointer\n", __func__);
+ exit(EXIT_FAILURE);
+ }
+
+ snprintf(name, sizeof(name), "ioctl(%lu)", op);
timeout_begin(TIMEOUT);
do {
- ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
+ ret = ioctl(fd, op, actual);
if (ret < 0) {
if (errno == EOPNOTSUPP)
break;
- perror("ioctl(SIOCOUTQ)");
+ perror(name);
exit(EXIT_FAILURE);
}
- timeout_check("SIOCOUTQ");
- } while (sock_bytes_unsent != 0);
+ timeout_check(name);
+ } while (*actual != expected);
timeout_end();
- return !ret;
+ return ret;
+}
+
+/* Wait until transport reports no data left to be sent.
+ * Return false if transport does not implement the unsent_bytes() callback.
+ */
+bool vsock_wait_sent(int fd)
+{
+ int sock_bytes_unsent;
+
+ return !(ioctl_int(fd, SIOCOUTQ, &sock_bytes_unsent, 0));
}
/* Create socket <type>, bind to <cid, port> and return the file descriptor. */
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 5e2db67072d5..945c85ff8d22 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -3,6 +3,7 @@
#define UTIL_H
#include <sys/socket.h>
+#include <sys/ioctl.h>
#include <linux/vm_sockets.h>
/* Tests can either run as the client or the server */
@@ -54,6 +55,7 @@ int vsock_stream_listen(unsigned int cid, unsigned int port);
int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
struct sockaddr_vm *clientaddrp);
void vsock_wait_remote_close(int fd);
+int ioctl_int(int fd, unsigned long op, int *actual, int expected);
bool vsock_wait_sent(int fd);
void send_buf(int fd, const void *buf, size_t len, int flags,
ssize_t expected_ret);
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index f669baaa0dca..43996447f9a2 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -20,7 +20,6 @@
#include <sys/mman.h>
#include <poll.h>
#include <signal.h>
-#include <sys/ioctl.h>
#include <linux/time64.h>
#include "vsock_test_zerocopy.h"
@@ -1305,6 +1304,58 @@ static void test_unsent_bytes_client(const struct test_opts *opts, int type)
close(fd);
}
+static void test_unread_bytes_server(const struct test_opts *opts, int type)
+{
+ unsigned char buf[MSG_BUF_IOCTL_LEN];
+ int client_fd;
+
+ client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
+ if (client_fd < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+
+ for (int i = 0; i < sizeof(buf); i++)
+ buf[i] = rand() & 0xFF;
+
+ send_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
+ control_writeln("SENT");
+ control_expectln("RECEIVED");
+
+ close(client_fd);
+}
+
+static void test_unread_bytes_client(const struct test_opts *opts, int type)
+{
+ unsigned char buf[MSG_BUF_IOCTL_LEN];
+ int ret, fd;
+ int sock_bytes_unread;
+
+ fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
+ if (fd < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+
+ control_expectln("SENT");
+ /* The data has arrived but has not been read. The expected is
+ * MSG_BUF_IOCTL_LEN.
+ */
+ ret = ioctl_int(fd, TIOCINQ, &sock_bytes_unread, MSG_BUF_IOCTL_LEN);
+ if (ret) {
+ fprintf(stderr, "Test skipped, TIOCINQ not supported.\n");
+ goto out;
+ }
+
+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
+ // All date has been consumed, so the expected is 0.
+ ioctl_int(fd, TIOCINQ, &sock_bytes_unread, 0);
+ control_writeln("RECEIVED");
+
+out:
+ close(fd);
+}
+
static void test_stream_unsent_bytes_client(const struct test_opts *opts)
{
test_unsent_bytes_client(opts, SOCK_STREAM);
@@ -1325,6 +1376,26 @@ static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
test_unsent_bytes_server(opts, SOCK_SEQPACKET);
}
+static void test_stream_unread_bytes_client(const struct test_opts *opts)
+{
+ test_unread_bytes_client(opts, SOCK_STREAM);
+}
+
+static void test_stream_unread_bytes_server(const struct test_opts *opts)
+{
+ test_unread_bytes_server(opts, SOCK_STREAM);
+}
+
+static void test_seqpacket_unread_bytes_client(const struct test_opts *opts)
+{
+ test_unread_bytes_client(opts, SOCK_SEQPACKET);
+}
+
+static void test_seqpacket_unread_bytes_server(const struct test_opts *opts)
+{
+ test_unread_bytes_server(opts, SOCK_SEQPACKET);
+}
+
#define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
/* This define is the same as in 'include/linux/virtio_vsock.h':
* it is used to decide when to send credit update message during
@@ -2016,6 +2087,16 @@ static struct test_case test_cases[] = {
.run_client = test_seqpacket_unsent_bytes_client,
.run_server = test_seqpacket_unsent_bytes_server,
},
+ {
+ .name = "SOCK_STREAM ioctl(SIOCINQ) functionality",
+ .run_client = test_stream_unread_bytes_client,
+ .run_server = test_stream_unread_bytes_server,
+ },
+ {
+ .name = "SOCK_SEQPACKET ioctl(SIOCINQ) functionality",
+ .run_client = test_seqpacket_unread_bytes_client,
+ .run_server = test_seqpacket_unread_bytes_server,
+ },
{
.name = "SOCK_STREAM leak accept queue",
.run_client = test_stream_leak_acceptq_client,
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
@ 2025-06-16 13:42 ` Luigi Leonardi
2025-06-16 14:30 ` Luigi Leonardi
2025-06-16 13:53 ` Stefano Garzarella
1 sibling, 1 reply; 13+ messages in thread
From: Luigi Leonardi @ 2025-06-16 13:42 UTC (permalink / raw)
To: Xuewei Niu
Cc: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha, virtualization, kvm, linux-kernel, fupan.lfp,
Xuewei Niu
On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
>This patch adds support for SIOCINQ ioctl, which returns the number of
>bytes unread in the socket.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> include/net/af_vsock.h | 2 ++
> net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> 2 files changed, 24 insertions(+)
>
>diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
>index d56e6e135158..723a886253ba 100644
>--- a/include/net/af_vsock.h
>+++ b/include/net/af_vsock.h
>@@ -171,6 +171,8 @@ struct vsock_transport {
>
> /* SIOCOUTQ ioctl */
> ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
>+ /* SIOCINQ ioctl */
>+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
>
> /* Shutdown. */
> int (*shutdown)(struct vsock_sock *, int);
>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>index 2e7a3034e965..466b1ebadbbc 100644
>--- a/net/vmw_vsock/af_vsock.c
>+++ b/net/vmw_vsock/af_vsock.c
>@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
> vsk = vsock_sk(sk);
>
> switch (cmd) {
>+ case SIOCINQ: {
>+ ssize_t n_bytes;
>+
>+ if (!vsk->transport || !vsk->transport->unread_bytes) {
>+ ret = -EOPNOTSUPP;
>+ break;
>+ }
>+
>+ if (sock_type_connectible(sk->sk_type) &&
>+ sk->sk_state == TCP_LISTEN) {
>+ ret = -EINVAL;
>+ break;
>+ }
>+
>+ n_bytes = vsk->transport->unread_bytes(vsk);
>+ if (n_bytes < 0) {
>+ ret = n_bytes;
>+ break;
>+ }
>+ ret = put_user(n_bytes, arg);
>+ break;
>+ }
> case SIOCOUTQ: {
> ssize_t n_bytes;
>
>--
>2.34.1
>
Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
2025-06-16 13:42 ` Luigi Leonardi
@ 2025-06-16 13:53 ` Stefano Garzarella
2025-06-16 14:28 ` Xuewei Niu
1 sibling, 1 reply; 13+ messages in thread
From: Stefano Garzarella @ 2025-06-16 13:53 UTC (permalink / raw)
To: Xuewei Niu
Cc: mst, pabeni, jasowang, xuanzhuo, davem, netdev, stefanha,
virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
>This patch adds support for SIOCINQ ioctl, which returns the number of
>bytes unread in the socket.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> include/net/af_vsock.h | 2 ++
> net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> 2 files changed, 24 insertions(+)
>
>diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
>index d56e6e135158..723a886253ba 100644
>--- a/include/net/af_vsock.h
>+++ b/include/net/af_vsock.h
>@@ -171,6 +171,8 @@ struct vsock_transport {
>
> /* SIOCOUTQ ioctl */
> ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
>+ /* SIOCINQ ioctl */
>+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
Instead of adding a new callback, can we just use
`vsock_stream_has_data()` ?
Maybe adjusting it or changing something in the transports, but for
virtio-vsock, it seems to me it does exactly what the new
`virtio_transport_unread_bytes()` does, right?
Thanks,
Stefano
>
> /* Shutdown. */
> int (*shutdown)(struct vsock_sock *, int);
>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>index 2e7a3034e965..466b1ebadbbc 100644
>--- a/net/vmw_vsock/af_vsock.c
>+++ b/net/vmw_vsock/af_vsock.c
>@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
> vsk = vsock_sk(sk);
>
> switch (cmd) {
>+ case SIOCINQ: {
>+ ssize_t n_bytes;
>+
>+ if (!vsk->transport || !vsk->transport->unread_bytes) {
>+ ret = -EOPNOTSUPP;
>+ break;
>+ }
>+
>+ if (sock_type_connectible(sk->sk_type) &&
>+ sk->sk_state == TCP_LISTEN) {
>+ ret = -EINVAL;
>+ break;
>+ }
>+
>+ n_bytes = vsk->transport->unread_bytes(vsk);
>+ if (n_bytes < 0) {
>+ ret = n_bytes;
>+ break;
>+ }
>+ ret = put_user(n_bytes, arg);
>+ break;
>+ }
> case SIOCOUTQ: {
> ssize_t n_bytes;
>
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests
2025-06-13 3:11 ` [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests Xuewei Niu
@ 2025-06-16 13:59 ` Stefano Garzarella
2025-06-16 14:39 ` Xuewei Niu
0 siblings, 1 reply; 13+ messages in thread
From: Stefano Garzarella @ 2025-06-16 13:59 UTC (permalink / raw)
To: Xuewei Niu
Cc: mst, pabeni, jasowang, xuanzhuo, davem, netdev, stefanha,
virtualization, kvm, linux-kernel, fupan.lfp, Xuewei Niu
On Fri, Jun 13, 2025 at 11:11:52AM +0800, Xuewei Niu wrote:
>This patch adds SIOCINQ ioctl tests for both SOCK_STREAM and
>SOCK_SEQPACKET.
>
>The client waits for the server to send data, and checks if the SIOCINQ
>ioctl value matches the data size. After consuming the data, the client
>checks if the SIOCINQ value is 0.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> tools/testing/vsock/util.c | 36 ++++++++++----
> tools/testing/vsock/util.h | 2 +
> tools/testing/vsock/vsock_test.c | 83 +++++++++++++++++++++++++++++++-
> 3 files changed, 111 insertions(+), 10 deletions(-)
>
>diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
>index 0c7e9cbcbc85..472246198966 100644
>--- a/tools/testing/vsock/util.c
>+++ b/tools/testing/vsock/util.c
>@@ -97,28 +97,46 @@ void vsock_wait_remote_close(int fd)
> close(epollfd);
> }
>
>-/* Wait until transport reports no data left to be sent.
>- * Return false if transport does not implement the unsent_bytes() callback.
>+/* Wait until ioctl gives an expected int value.
>+ * Return a negative value if the op is not supported.
> */
>-bool vsock_wait_sent(int fd)
>+int ioctl_int(int fd, unsigned long op, int *actual, int expected)
> {
>- int ret, sock_bytes_unsent;
>+ int ret;
>+ char name[32];
>+
>+ if (!actual) {
>+ fprintf(stderr, "%s requires a non-null pointer\n", __func__);
>+ exit(EXIT_FAILURE);
>+ }
>+
>+ snprintf(name, sizeof(name), "ioctl(%lu)", op);
>
> timeout_begin(TIMEOUT);
> do {
>- ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
>+ ret = ioctl(fd, op, actual);
> if (ret < 0) {
> if (errno == EOPNOTSUPP)
> break;
>
>- perror("ioctl(SIOCOUTQ)");
>+ perror(name);
> exit(EXIT_FAILURE);
> }
>- timeout_check("SIOCOUTQ");
>- } while (sock_bytes_unsent != 0);
>+ timeout_check(name);
>+ } while (*actual != expected);
> timeout_end();
>
>- return !ret;
>+ return ret;
>+}
>+
>+/* Wait until transport reports no data left to be sent.
>+ * Return false if transport does not implement the unsent_bytes() callback.
>+ */
>+bool vsock_wait_sent(int fd)
>+{
>+ int sock_bytes_unsent;
>+
>+ return !(ioctl_int(fd, SIOCOUTQ, &sock_bytes_unsent, 0));
> }
Please split this patch in 2, one where you do the refactoring in
util.c/h and one for the new test.
>
> /* Create socket <type>, bind to <cid, port> and return the file descriptor. */
>diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
>index 5e2db67072d5..945c85ff8d22 100644
>--- a/tools/testing/vsock/util.h
>+++ b/tools/testing/vsock/util.h
>@@ -3,6 +3,7 @@
> #define UTIL_H
>
> #include <sys/socket.h>
>+#include <sys/ioctl.h>
Why we need this in util.h?
> #include <linux/vm_sockets.h>
>
> /* Tests can either run as the client or the server */
>@@ -54,6 +55,7 @@ int vsock_stream_listen(unsigned int cid, unsigned int port);
> int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
> struct sockaddr_vm *clientaddrp);
> void vsock_wait_remote_close(int fd);
>+int ioctl_int(int fd, unsigned long op, int *actual, int expected);
> bool vsock_wait_sent(int fd);
> void send_buf(int fd, const void *buf, size_t len, int flags,
> ssize_t expected_ret);
>diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>index f669baaa0dca..43996447f9a2 100644
>--- a/tools/testing/vsock/vsock_test.c
>+++ b/tools/testing/vsock/vsock_test.c
>@@ -20,7 +20,6 @@
> #include <sys/mman.h>
> #include <poll.h>
> #include <signal.h>
>-#include <sys/ioctl.h>
> #include <linux/time64.h>
>
> #include "vsock_test_zerocopy.h"
>@@ -1305,6 +1304,58 @@ static void test_unsent_bytes_client(const struct test_opts *opts, int type)
> close(fd);
> }
>
>+static void test_unread_bytes_server(const struct test_opts *opts, int type)
>+{
>+ unsigned char buf[MSG_BUF_IOCTL_LEN];
>+ int client_fd;
>+
>+ client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
>+ if (client_fd < 0) {
>+ perror("accept");
>+ exit(EXIT_FAILURE);
>+ }
>+
>+ for (int i = 0; i < sizeof(buf); i++)
>+ buf[i] = rand() & 0xFF;
>+
>+ send_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
>+ control_writeln("SENT");
>+ control_expectln("RECEIVED");
>+
>+ close(client_fd);
>+}
>+
>+static void test_unread_bytes_client(const struct test_opts *opts, int type)
>+{
>+ unsigned char buf[MSG_BUF_IOCTL_LEN];
>+ int ret, fd;
>+ int sock_bytes_unread;
>+
>+ fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
>+ if (fd < 0) {
>+ perror("connect");
>+ exit(EXIT_FAILURE);
>+ }
>+
>+ control_expectln("SENT");
>+ /* The data has arrived but has not been read. The expected is
>+ * MSG_BUF_IOCTL_LEN.
>+ */
>+ ret = ioctl_int(fd, TIOCINQ, &sock_bytes_unread, MSG_BUF_IOCTL_LEN);
>+ if (ret) {
>+ fprintf(stderr, "Test skipped, TIOCINQ not supported.\n");
>+ goto out;
>+ }
>+
>+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
>+ // All date has been consumed, so the expected is 0.
>+ ioctl_int(fd, TIOCINQ, &sock_bytes_unread, 0);
>+ control_writeln("RECEIVED");
>+
>+out:
>+ close(fd);
>+}
>+
> static void test_stream_unsent_bytes_client(const struct test_opts *opts)
> {
> test_unsent_bytes_client(opts, SOCK_STREAM);
>@@ -1325,6 +1376,26 @@ static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
> test_unsent_bytes_server(opts, SOCK_SEQPACKET);
> }
>
>+static void test_stream_unread_bytes_client(const struct test_opts *opts)
>+{
>+ test_unread_bytes_client(opts, SOCK_STREAM);
>+}
>+
>+static void test_stream_unread_bytes_server(const struct test_opts *opts)
>+{
>+ test_unread_bytes_server(opts, SOCK_STREAM);
>+}
>+
>+static void test_seqpacket_unread_bytes_client(const struct test_opts *opts)
>+{
>+ test_unread_bytes_client(opts, SOCK_SEQPACKET);
>+}
>+
>+static void test_seqpacket_unread_bytes_server(const struct test_opts *opts)
>+{
>+ test_unread_bytes_server(opts, SOCK_SEQPACKET);
>+}
>+
> #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
> /* This define is the same as in 'include/linux/virtio_vsock.h':
> * it is used to decide when to send credit update message during
>@@ -2016,6 +2087,16 @@ static struct test_case test_cases[] = {
> .run_client = test_seqpacket_unsent_bytes_client,
> .run_server = test_seqpacket_unsent_bytes_server,
> },
>+ {
>+ .name = "SOCK_STREAM ioctl(SIOCINQ) functionality",
>+ .run_client = test_stream_unread_bytes_client,
>+ .run_server = test_stream_unread_bytes_server,
>+ },
>+ {
>+ .name = "SOCK_SEQPACKET ioctl(SIOCINQ) functionality",
>+ .run_client = test_seqpacket_unread_bytes_client,
>+ .run_server = test_seqpacket_unread_bytes_server,
>+ },
I think I already mentioned in the previous version: please add new
tests at the end of the array, so we can preserve test IDs.
Thanks,
Stefano
> {
> .name = "SOCK_STREAM leak accept queue",
> .run_client = test_stream_leak_acceptq_client,
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-16 13:53 ` Stefano Garzarella
@ 2025-06-16 14:28 ` Xuewei Niu
2025-06-16 14:37 ` Stefano Garzarella
0 siblings, 1 reply; 13+ messages in thread
From: Xuewei Niu @ 2025-06-16 14:28 UTC (permalink / raw)
To: sgarzare
Cc: davem, fupan.lfp, jasowang, kvm, linux-kernel, mst, netdev,
niuxuewei.nxw, niuxuewei97, pabeni, stefanha, virtualization,
xuanzhuo
> On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
> >This patch adds support for SIOCINQ ioctl, which returns the number of
> >bytes unread in the socket.
> >
> >Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
> >---
> > include/net/af_vsock.h | 2 ++
> > net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> > 2 files changed, 24 insertions(+)
> >
> >diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
> >index d56e6e135158..723a886253ba 100644
> >--- a/include/net/af_vsock.h
> >+++ b/include/net/af_vsock.h
> >@@ -171,6 +171,8 @@ struct vsock_transport {
> >
> > /* SIOCOUTQ ioctl */
> > ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
> >+ /* SIOCINQ ioctl */
> >+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
>
> Instead of adding a new callback, can we just use
> `vsock_stream_has_data()` ?
>
> Maybe adjusting it or changing something in the transports, but for
> virtio-vsock, it seems to me it does exactly what the new
> `virtio_transport_unread_bytes()` does, right?
Sorry, I forgot to update this.
I am curious that is there a plan to implement dgram support in
virtio-vsock? If yes, adding a new callback is the right way to go. I
deadly hope to see that feature. If no, will do in the next.
Thanks,
Xuewei
> Thanks,
> Stefano
>
> >
> > /* Shutdown. */
> > int (*shutdown)(struct vsock_sock *, int);
> >diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> >index 2e7a3034e965..466b1ebadbbc 100644
> >--- a/net/vmw_vsock/af_vsock.c
> >+++ b/net/vmw_vsock/af_vsock.c
> >@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
> > vsk = vsock_sk(sk);
> >
> > switch (cmd) {
> >+ case SIOCINQ: {
> >+ ssize_t n_bytes;
> >+
> >+ if (!vsk->transport || !vsk->transport->unread_bytes) {
> >+ ret = -EOPNOTSUPP;
> >+ break;
> >+ }
> >+
> >+ if (sock_type_connectible(sk->sk_type) &&
> >+ sk->sk_state == TCP_LISTEN) {
> >+ ret = -EINVAL;
> >+ break;
> >+ }
> >+
> >+ n_bytes = vsk->transport->unread_bytes(vsk);
> >+ if (n_bytes < 0) {
> >+ ret = n_bytes;
> >+ break;
> >+ }
> >+ ret = put_user(n_bytes, arg);
> >+ break;
> >+ }
> > case SIOCOUTQ: {
> > ssize_t n_bytes;
> >
> >--
> >2.34.1
> >
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-16 13:42 ` Luigi Leonardi
@ 2025-06-16 14:30 ` Luigi Leonardi
2025-06-16 14:42 ` Xuewei Niu
0 siblings, 1 reply; 13+ messages in thread
From: Luigi Leonardi @ 2025-06-16 14:30 UTC (permalink / raw)
To: Xuewei Niu
Cc: sgarzare, mst, pabeni, jasowang, xuanzhuo, davem, netdev,
stefanha, virtualization, kvm, linux-kernel, fupan.lfp,
Xuewei Niu
On Mon, Jun 16, 2025 at 03:42:53PM +0200, Luigi Leonardi wrote:
>On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
>>This patch adds support for SIOCINQ ioctl, which returns the number of
>>bytes unread in the socket.
>>
>>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>>---
>>include/net/af_vsock.h | 2 ++
>>net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
>>2 files changed, 24 insertions(+)
>>
>>diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
>>index d56e6e135158..723a886253ba 100644
>>--- a/include/net/af_vsock.h
>>+++ b/include/net/af_vsock.h
>>@@ -171,6 +171,8 @@ struct vsock_transport {
>>
>> /* SIOCOUTQ ioctl */
>> ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
>>+ /* SIOCINQ ioctl */
>>+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
>>
>> /* Shutdown. */
>> int (*shutdown)(struct vsock_sock *, int);
>>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>>index 2e7a3034e965..466b1ebadbbc 100644
>>--- a/net/vmw_vsock/af_vsock.c
>>+++ b/net/vmw_vsock/af_vsock.c
>>@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
>> vsk = vsock_sk(sk);
>>
>> switch (cmd) {
>>+ case SIOCINQ: {
>>+ ssize_t n_bytes;
>>+
>>+ if (!vsk->transport || !vsk->transport->unread_bytes) {
>>+ ret = -EOPNOTSUPP;
>>+ break;
>>+ }
>>+
>>+ if (sock_type_connectible(sk->sk_type) &&
>>+ sk->sk_state == TCP_LISTEN) {
>>+ ret = -EINVAL;
>>+ break;
>>+ }
>>+
>>+ n_bytes = vsk->transport->unread_bytes(vsk);
>>+ if (n_bytes < 0) {
>>+ ret = n_bytes;
>>+ break;
>>+ }
>>+ ret = put_user(n_bytes, arg);
>>+ break;
>>+ }
>> case SIOCOUTQ: {
>> ssize_t n_bytes;
>>
>>--
>>2.34.1
>>
>
>Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
Stefano is totally right, reusing `virtio_transport_unread_bytes` is a
good idea.
nit: commit message should use 'imperative' language [1]. "This patch
adds" should be avoided.
Sorry for the confusion.
Thanks,
Luigi
[1]https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-16 14:28 ` Xuewei Niu
@ 2025-06-16 14:37 ` Stefano Garzarella
0 siblings, 0 replies; 13+ messages in thread
From: Stefano Garzarella @ 2025-06-16 14:37 UTC (permalink / raw)
To: Xuewei Niu
Cc: davem, fupan.lfp, jasowang, kvm, linux-kernel, mst, netdev,
niuxuewei.nxw, pabeni, stefanha, virtualization, xuanzhuo
On Mon, Jun 16, 2025 at 10:28:22PM +0800, Xuewei Niu wrote:
>> On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
>> >This patch adds support for SIOCINQ ioctl, which returns the number of
>> >bytes unread in the socket.
>> >
>> >Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>> >---
>> > include/net/af_vsock.h | 2 ++
>> > net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
>> > 2 files changed, 24 insertions(+)
>> >
>> >diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
>> >index d56e6e135158..723a886253ba 100644
>> >--- a/include/net/af_vsock.h
>> >+++ b/include/net/af_vsock.h
>> >@@ -171,6 +171,8 @@ struct vsock_transport {
>> >
>> > /* SIOCOUTQ ioctl */
>> > ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
>> >+ /* SIOCINQ ioctl */
>> >+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
>>
>> Instead of adding a new callback, can we just use
>> `vsock_stream_has_data()` ?
>>
>> Maybe adjusting it or changing something in the transports, but for
>> virtio-vsock, it seems to me it does exactly what the new
>> `virtio_transport_unread_bytes()` does, right?
>
>Sorry, I forgot to update this.
Don't worry.
>
>I am curious that is there a plan to implement dgram support in
>virtio-vsock? If yes, adding a new callback is the right way to go. I
>deadly hope to see that feature. If no, will do in the next.
I don't know the status, there were folks working on it, but I didn't
see updates.
IMO we can deal with it later, since also this patch will not work as it
is with datagram since you're checking if the socket is "connectible"
and also a state. And maybe we also need some
"vsock_datagram_has_data()" anyway, so let's do this when we will have
the support. For now let's reuse what we have as much as we can.
Thanks.
Stefano
>
>Thanks,
>Xuewei
>
>> Thanks,
>> Stefano
>>
>> >
>> > /* Shutdown. */
>> > int (*shutdown)(struct vsock_sock *, int);
>> >diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>> >index 2e7a3034e965..466b1ebadbbc 100644
>> >--- a/net/vmw_vsock/af_vsock.c
>> >+++ b/net/vmw_vsock/af_vsock.c
>> >@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
>> > vsk = vsock_sk(sk);
>> >
>> > switch (cmd) {
>> >+ case SIOCINQ: {
>> >+ ssize_t n_bytes;
>> >+
>> >+ if (!vsk->transport || !vsk->transport->unread_bytes) {
>> >+ ret = -EOPNOTSUPP;
>> >+ break;
>> >+ }
>> >+
>> >+ if (sock_type_connectible(sk->sk_type) &&
>> >+ sk->sk_state == TCP_LISTEN) {
>> >+ ret = -EINVAL;
>> >+ break;
>> >+ }
>> >+
>> >+ n_bytes = vsk->transport->unread_bytes(vsk);
>> >+ if (n_bytes < 0) {
>> >+ ret = n_bytes;
>> >+ break;
>> >+ }
>> >+ ret = put_user(n_bytes, arg);
>> >+ break;
>> >+ }
>> > case SIOCOUTQ: {
>> > ssize_t n_bytes;
>> >
>> >--
>> >2.34.1
>> >
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests
2025-06-16 13:59 ` Stefano Garzarella
@ 2025-06-16 14:39 ` Xuewei Niu
2025-06-16 14:51 ` Stefano Garzarella
0 siblings, 1 reply; 13+ messages in thread
From: Xuewei Niu @ 2025-06-16 14:39 UTC (permalink / raw)
To: sgarzare
Cc: davem, fupan.lfp, jasowang, kvm, linux-kernel, mst, netdev,
niuxuewei.nxw, niuxuewei97, pabeni, stefanha, virtualization,
xuanzhuo
> On Fri, Jun 13, 2025 at 11:11:52AM +0800, Xuewei Niu wrote:
> >This patch adds SIOCINQ ioctl tests for both SOCK_STREAM and
> >SOCK_SEQPACKET.
> >
> >The client waits for the server to send data, and checks if the SIOCINQ
> >ioctl value matches the data size. After consuming the data, the client
> >checks if the SIOCINQ value is 0.
> >
> >Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
> >---
> > tools/testing/vsock/util.c | 36 ++++++++++----
> > tools/testing/vsock/util.h | 2 +
> > tools/testing/vsock/vsock_test.c | 83 +++++++++++++++++++++++++++++++-
> > 3 files changed, 111 insertions(+), 10 deletions(-)
> >
> >diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
> >index 0c7e9cbcbc85..472246198966 100644
> >--- a/tools/testing/vsock/util.c
> >+++ b/tools/testing/vsock/util.c
> >@@ -97,28 +97,46 @@ void vsock_wait_remote_close(int fd)
> > close(epollfd);
> > }
> >
> >-/* Wait until transport reports no data left to be sent.
> >- * Return false if transport does not implement the unsent_bytes() callback.
> >+/* Wait until ioctl gives an expected int value.
> >+ * Return a negative value if the op is not supported.
> > */
> >-bool vsock_wait_sent(int fd)
> >+int ioctl_int(int fd, unsigned long op, int *actual, int expected)
> > {
> >- int ret, sock_bytes_unsent;
> >+ int ret;
> >+ char name[32];
> >+
> >+ if (!actual) {
> >+ fprintf(stderr, "%s requires a non-null pointer\n", __func__);
> >+ exit(EXIT_FAILURE);
> >+ }
> >+
> >+ snprintf(name, sizeof(name), "ioctl(%lu)", op);
> >
> > timeout_begin(TIMEOUT);
> > do {
> >- ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
> >+ ret = ioctl(fd, op, actual);
> > if (ret < 0) {
> > if (errno == EOPNOTSUPP)
> > break;
> >
> >- perror("ioctl(SIOCOUTQ)");
> >+ perror(name);
> > exit(EXIT_FAILURE);
> > }
> >- timeout_check("SIOCOUTQ");
> >- } while (sock_bytes_unsent != 0);
> >+ timeout_check(name);
> >+ } while (*actual != expected);
> > timeout_end();
> >
> >- return !ret;
> >+ return ret;
> >+}
> >+
> >+/* Wait until transport reports no data left to be sent.
> >+ * Return false if transport does not implement the unsent_bytes() callback.
> >+ */
> >+bool vsock_wait_sent(int fd)
> >+{
> >+ int sock_bytes_unsent;
> >+
> >+ return !(ioctl_int(fd, SIOCOUTQ, &sock_bytes_unsent, 0));
> > }
>
> Please split this patch in 2, one where you do the refactoring in
> util.c/h and one for the new test.
Will do.
> > /* Create socket <type>, bind to <cid, port> and return the file descriptor. */
> >diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
> >index 5e2db67072d5..945c85ff8d22 100644
> >--- a/tools/testing/vsock/util.h
> >+++ b/tools/testing/vsock/util.h
> >@@ -3,6 +3,7 @@
> > #define UTIL_H
> >
> > #include <sys/socket.h>
> >+#include <sys/ioctl.h>
>
> Why we need this in util.h?
We call `ioctl()` in the util.c. And we use `TIOCINQ` in the vsock_test.c,
where includes "util.h". So including `sys/ioctl.h` in util.h is needed.
> > #include <linux/vm_sockets.h>
> >
> > /* Tests can either run as the client or the server */
> >@@ -54,6 +55,7 @@ int vsock_stream_listen(unsigned int cid, unsigned int port);
> > int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
> > struct sockaddr_vm *clientaddrp);
> > void vsock_wait_remote_close(int fd);
> >+int ioctl_int(int fd, unsigned long op, int *actual, int expected);
> > bool vsock_wait_sent(int fd);
> > void send_buf(int fd, const void *buf, size_t len, int flags,
> > ssize_t expected_ret);
> >diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
> >index f669baaa0dca..43996447f9a2 100644
> >--- a/tools/testing/vsock/vsock_test.c
> >+++ b/tools/testing/vsock/vsock_test.c
> >@@ -20,7 +20,6 @@
> > #include <sys/mman.h>
> > #include <poll.h>
> > #include <signal.h>
> >-#include <sys/ioctl.h>
> > #include <linux/time64.h>
> >
> > #include "vsock_test_zerocopy.h"
> >@@ -1305,6 +1304,58 @@ static void test_unsent_bytes_client(const struct test_opts *opts, int type)
> > close(fd);
> > }
> >
> >+static void test_unread_bytes_server(const struct test_opts *opts, int type)
> >+{
> >+ unsigned char buf[MSG_BUF_IOCTL_LEN];
> >+ int client_fd;
> >+
> >+ client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
> >+ if (client_fd < 0) {
> >+ perror("accept");
> >+ exit(EXIT_FAILURE);
> >+ }
> >+
> >+ for (int i = 0; i < sizeof(buf); i++)
> >+ buf[i] = rand() & 0xFF;
> >+
> >+ send_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
> >+ control_writeln("SENT");
> >+ control_expectln("RECEIVED");
> >+
> >+ close(client_fd);
> >+}
> >+
> >+static void test_unread_bytes_client(const struct test_opts *opts, int type)
> >+{
> >+ unsigned char buf[MSG_BUF_IOCTL_LEN];
> >+ int ret, fd;
> >+ int sock_bytes_unread;
> >+
> >+ fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
> >+ if (fd < 0) {
> >+ perror("connect");
> >+ exit(EXIT_FAILURE);
> >+ }
> >+
> >+ control_expectln("SENT");
> >+ /* The data has arrived but has not been read. The expected is
> >+ * MSG_BUF_IOCTL_LEN.
> >+ */
> >+ ret = ioctl_int(fd, TIOCINQ, &sock_bytes_unread, MSG_BUF_IOCTL_LEN);
> >+ if (ret) {
> >+ fprintf(stderr, "Test skipped, TIOCINQ not supported.\n");
> >+ goto out;
> >+ }
> >+
> >+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
> >+ // All date has been consumed, so the expected is 0.
> >+ ioctl_int(fd, TIOCINQ, &sock_bytes_unread, 0);
> >+ control_writeln("RECEIVED");
> >+
> >+out:
> >+ close(fd);
> >+}
> >+
> > static void test_stream_unsent_bytes_client(const struct test_opts *opts)
> > {
> > test_unsent_bytes_client(opts, SOCK_STREAM);
> >@@ -1325,6 +1376,26 @@ static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
> > test_unsent_bytes_server(opts, SOCK_SEQPACKET);
> > }
> >
> >+static void test_stream_unread_bytes_client(const struct test_opts *opts)
> >+{
> >+ test_unread_bytes_client(opts, SOCK_STREAM);
> >+}
> >+
> >+static void test_stream_unread_bytes_server(const struct test_opts *opts)
> >+{
> >+ test_unread_bytes_server(opts, SOCK_STREAM);
> >+}
> >+
> >+static void test_seqpacket_unread_bytes_client(const struct test_opts *opts)
> >+{
> >+ test_unread_bytes_client(opts, SOCK_SEQPACKET);
> >+}
> >+
> >+static void test_seqpacket_unread_bytes_server(const struct test_opts *opts)
> >+{
> >+ test_unread_bytes_server(opts, SOCK_SEQPACKET);
> >+}
> >+
> > #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
> > /* This define is the same as in 'include/linux/virtio_vsock.h':
> > * it is used to decide when to send credit update message during
> >@@ -2016,6 +2087,16 @@ static struct test_case test_cases[] = {
> > .run_client = test_seqpacket_unsent_bytes_client,
> > .run_server = test_seqpacket_unsent_bytes_server,
> > },
> >+ {
> >+ .name = "SOCK_STREAM ioctl(SIOCINQ) functionality",
> >+ .run_client = test_stream_unread_bytes_client,
> >+ .run_server = test_stream_unread_bytes_server,
> >+ },
> >+ {
> >+ .name = "SOCK_SEQPACKET ioctl(SIOCINQ) functionality",
> >+ .run_client = test_seqpacket_unread_bytes_client,
> >+ .run_server = test_seqpacket_unread_bytes_server,
> >+ },
>
> I think I already mentioned in the previous version: please add new
> tests at the end of the array, so we can preserve test IDs.
My bad. Sorry. Will do.
Thanks,
Xuewei
> Thanks,
> Stefano
>
> > {
> > .name = "SOCK_STREAM leak accept queue",
> > .run_client = test_stream_leak_acceptq_client,
> >--
> >2.34.1
> >
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl
2025-06-16 14:30 ` Luigi Leonardi
@ 2025-06-16 14:42 ` Xuewei Niu
0 siblings, 0 replies; 13+ messages in thread
From: Xuewei Niu @ 2025-06-16 14:42 UTC (permalink / raw)
To: leonardi
Cc: davem, fupan.lfp, jasowang, kvm, linux-kernel, mst, netdev,
niuxuewei.nxw, niuxuewei97, pabeni, sgarzare, stefanha,
virtualization, xuanzhuo
> On Mon, Jun 16, 2025 at 03:42:53PM +0200, Luigi Leonardi wrote:
> >On Fri, Jun 13, 2025 at 11:11:50AM +0800, Xuewei Niu wrote:
> >>This patch adds support for SIOCINQ ioctl, which returns the number of
> >>bytes unread in the socket.
> >>
> >>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
> >>---
> >>include/net/af_vsock.h | 2 ++
> >>net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> >>2 files changed, 24 insertions(+)
> >>
> >>diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
> >>index d56e6e135158..723a886253ba 100644
> >>--- a/include/net/af_vsock.h
> >>+++ b/include/net/af_vsock.h
> >>@@ -171,6 +171,8 @@ struct vsock_transport {
> >>
> >> /* SIOCOUTQ ioctl */
> >> ssize_t (*unsent_bytes)(struct vsock_sock *vsk);
> >>+ /* SIOCINQ ioctl */
> >>+ ssize_t (*unread_bytes)(struct vsock_sock *vsk);
> >>
> >> /* Shutdown. */
> >> int (*shutdown)(struct vsock_sock *, int);
> >>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> >>index 2e7a3034e965..466b1ebadbbc 100644
> >>--- a/net/vmw_vsock/af_vsock.c
> >>+++ b/net/vmw_vsock/af_vsock.c
> >>@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
> >> vsk = vsock_sk(sk);
> >>
> >> switch (cmd) {
> >>+ case SIOCINQ: {
> >>+ ssize_t n_bytes;
> >>+
> >>+ if (!vsk->transport || !vsk->transport->unread_bytes) {
> >>+ ret = -EOPNOTSUPP;
> >>+ break;
> >>+ }
> >>+
> >>+ if (sock_type_connectible(sk->sk_type) &&
> >>+ sk->sk_state == TCP_LISTEN) {
> >>+ ret = -EINVAL;
> >>+ break;
> >>+ }
> >>+
> >>+ n_bytes = vsk->transport->unread_bytes(vsk);
> >>+ if (n_bytes < 0) {
> >>+ ret = n_bytes;
> >>+ break;
> >>+ }
> >>+ ret = put_user(n_bytes, arg);
> >>+ break;
> >>+ }
> >> case SIOCOUTQ: {
> >> ssize_t n_bytes;
> >>
> >>--
> >>2.34.1
> >>
> >
> >Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
>
> Stefano is totally right, reusing `virtio_transport_unread_bytes` is a
> good idea.
>
> nit: commit message should use 'imperative' language [1]. "This patch
> adds" should be avoided.
>
> Sorry for the confusion.
>
> Thanks,
> Luigi
>
> [1]https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes
Thanks for pointing out. I'll update the commit message following the
guidelines.
Thanks,
Xuewei
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests
2025-06-16 14:39 ` Xuewei Niu
@ 2025-06-16 14:51 ` Stefano Garzarella
0 siblings, 0 replies; 13+ messages in thread
From: Stefano Garzarella @ 2025-06-16 14:51 UTC (permalink / raw)
To: Xuewei Niu
Cc: davem, fupan.lfp, jasowang, kvm, linux-kernel, mst, netdev,
niuxuewei.nxw, pabeni, stefanha, virtualization, xuanzhuo
On Mon, 16 Jun 2025 at 16:39, Xuewei Niu <niuxuewei97@gmail.com> wrote:
>
> > On Fri, Jun 13, 2025 at 11:11:52AM +0800, Xuewei Niu wrote:
> > >This patch adds SIOCINQ ioctl tests for both SOCK_STREAM and
> > >SOCK_SEQPACKET.
> > >
> > >The client waits for the server to send data, and checks if the SIOCINQ
> > >ioctl value matches the data size. After consuming the data, the client
> > >checks if the SIOCINQ value is 0.
> > >
> > >Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
> > >---
> > > tools/testing/vsock/util.c | 36 ++++++++++----
> > > tools/testing/vsock/util.h | 2 +
> > > tools/testing/vsock/vsock_test.c | 83 +++++++++++++++++++++++++++++++-
> > > 3 files changed, 111 insertions(+), 10 deletions(-)
> > >
> > >diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
> > >index 0c7e9cbcbc85..472246198966 100644
> > >--- a/tools/testing/vsock/util.c
> > >+++ b/tools/testing/vsock/util.c
> > >@@ -97,28 +97,46 @@ void vsock_wait_remote_close(int fd)
> > > close(epollfd);
> > > }
> > >
> > >-/* Wait until transport reports no data left to be sent.
> > >- * Return false if transport does not implement the unsent_bytes() callback.
> > >+/* Wait until ioctl gives an expected int value.
> > >+ * Return a negative value if the op is not supported.
> > > */
> > >-bool vsock_wait_sent(int fd)
> > >+int ioctl_int(int fd, unsigned long op, int *actual, int expected)
> > > {
> > >- int ret, sock_bytes_unsent;
> > >+ int ret;
> > >+ char name[32];
> > >+
> > >+ if (!actual) {
> > >+ fprintf(stderr, "%s requires a non-null pointer\n", __func__);
> > >+ exit(EXIT_FAILURE);
> > >+ }
> > >+
> > >+ snprintf(name, sizeof(name), "ioctl(%lu)", op);
> > >
> > > timeout_begin(TIMEOUT);
> > > do {
> > >- ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
> > >+ ret = ioctl(fd, op, actual);
> > > if (ret < 0) {
> > > if (errno == EOPNOTSUPP)
> > > break;
> > >
> > >- perror("ioctl(SIOCOUTQ)");
> > >+ perror(name);
> > > exit(EXIT_FAILURE);
> > > }
> > >- timeout_check("SIOCOUTQ");
> > >- } while (sock_bytes_unsent != 0);
> > >+ timeout_check(name);
> > >+ } while (*actual != expected);
> > > timeout_end();
> > >
> > >- return !ret;
> > >+ return ret;
> > >+}
> > >+
> > >+/* Wait until transport reports no data left to be sent.
> > >+ * Return false if transport does not implement the unsent_bytes() callback.
> > >+ */
> > >+bool vsock_wait_sent(int fd)
> > >+{
> > >+ int sock_bytes_unsent;
> > >+
> > >+ return !(ioctl_int(fd, SIOCOUTQ, &sock_bytes_unsent, 0));
> > > }
> >
> > Please split this patch in 2, one where you do the refactoring in
> > util.c/h and one for the new test.
>
> Will do.
>
> > > /* Create socket <type>, bind to <cid, port> and return the file descriptor. */
> > >diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
> > >index 5e2db67072d5..945c85ff8d22 100644
> > >--- a/tools/testing/vsock/util.h
> > >+++ b/tools/testing/vsock/util.h
> > >@@ -3,6 +3,7 @@
> > > #define UTIL_H
> > >
> > > #include <sys/socket.h>
> > >+#include <sys/ioctl.h>
> >
> > Why we need this in util.h?
>
> We call `ioctl()` in the util.c. And we use `TIOCINQ` in the vsock_test.c,
> where includes "util.h". So including `sys/ioctl.h` in util.h is needed.
But we are not using anything in util.c from sys/ioctl.h IIUC, in that
case please move it in util.c where actually is needed.
Thanks,
Stefano
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-06-16 14:51 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-13 3:11 [PATCH net-next v2 0/3] vsock: Introduce SIOCINQ ioctl support Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 1/3] vsock: Add support for SIOCINQ ioctl Xuewei Niu
2025-06-16 13:42 ` Luigi Leonardi
2025-06-16 14:30 ` Luigi Leonardi
2025-06-16 14:42 ` Xuewei Niu
2025-06-16 13:53 ` Stefano Garzarella
2025-06-16 14:28 ` Xuewei Niu
2025-06-16 14:37 ` Stefano Garzarella
2025-06-13 3:11 ` [PATCH net-next v2 2/3] vsock/virtio: Add SIOCINQ support for all virtio based transports Xuewei Niu
2025-06-13 3:11 ` [PATCH net-next v2 3/3] test/vsock: Add ioctl SIOCINQ tests Xuewei Niu
2025-06-16 13:59 ` Stefano Garzarella
2025-06-16 14:39 ` Xuewei Niu
2025-06-16 14:51 ` Stefano Garzarella
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).