* Re: [RFC PATCH 1/1] KVM: VMX: Use Hyper-V EPT flush for local TLB flushes
From: Vitaly Kuznetsov @ 2025-07-09 15:46 UTC (permalink / raw)
To: Jeremi Piotrowski
Cc: Dave Hansen, linux-kernel, alanjiang, chinang.ma,
andrea.pellegrini, Kevin Tian, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Dexuan Cui, linux-hyperv, Sean Christopherson,
Paolo Bonzini, kvm
In-Reply-To: <ca26fba1-c2bb-40a1-bb5e-92811c4a6fc6@linux.microsoft.com>
Jeremi Piotrowski <jpiotrowski@linux.microsoft.com> writes:
> On 27/06/2025 10:31, Vitaly Kuznetsov wrote:
>> Jeremi Piotrowski <jpiotrowski@linux.microsoft.com> writes:
>>
>>> Use Hyper-V's HvCallFlushGuestPhysicalAddressSpace for local TLB flushes.
>>> This makes any KVM_REQ_TLB_FLUSH_CURRENT (such as on root alloc) visible to
>>> all CPUs which means we no longer need to do a KVM_REQ_TLB_FLUSH on CPU
>>> migration.
>>>
>>> The goal is to avoid invept-global in KVM_REQ_TLB_FLUSH. Hyper-V uses a
>>> shadow page table for the nested hypervisor (KVM) and has to invalidate all
>>> EPT roots when invept-global is issued. This has a performance impact on
>>> all nested VMs. KVM issues KVM_REQ_TLB_FLUSH on CPU migration, and under
>>> load the performance hit causes vCPUs to use up more of their slice of CPU
>>> time, leading to more CPU migrations. This has a snowball effect and causes
>>> CPU usage spikes.
>>>
>>> By issuing the hypercall we are now guaranteed that any root modification
>>> that requires a local TLB flush becomes visible to all CPUs. The same
>>> hypercall is already used in kvm_arch_flush_remote_tlbs and
>>> kvm_arch_flush_remote_tlbs_range. The KVM expectation is that roots are
>>> flushed locally on alloc and we achieve consistency on migration by
>>> flushing all roots - the new behavior of achieving consistency on alloc on
>>> Hyper-V is a superset of the expected guarantees. This makes the
>>> KVM_REQ_TLB_FLUSH on CPU migration no longer necessary on Hyper-V.
>>
>> Sounds reasonable overall, my only concern (not sure if valid or not) is
>> that using the hypercall for local flushes is going to be more expensive
>> than invept-context we do today and thus while the performance is
>> improved for the scenario when vCPUs are migrating a lot, we will take a
>> hit in other cases.
>>
>
Sorry for delayed reply!
....
>>> return;
>>>
>>> - if (enable_ept)
>>> + if (enable_ept) {
>>> + /*
>>> + * hyperv_flush_guest_mapping() has the semantics of
>>> + * invept-single across all pCPUs. This makes root
>>> + * modifications consistent across pCPUs, so an invept-global
>>> + * on migration is no longer required.
>>> + */
>>> + if (vmx_hv_use_flush_guest_mapping(vcpu))
>>> + return (void)WARN_ON_ONCE(hyperv_flush_guest_mapping(root_hpa));
>>> +
>>
>> HvCallFlushGuestPhysicalAddressSpace sounds like a heavy operation as it
>> affects all processors. Is there any visible perfomance impact of this
>> change when there are no migrations (e.g. with vCPU pinning)? Or do we
>> believe that Hyper-V actually handles invept-context the exact same way?
>>
> I'm going to have to do some more investigation to answer that - do you have an
> idea of a workload that would be sensitive to tlb flushes that I could compare
> this on?
>
> In terms of cost, Hyper-V needs to invalidate the VMs shadow page table for a root
> and do the tlb flush. The first part is CPU intensive but is the same in both cases
> (hypercall and invept-single). The tlb flush part will require a bit more work for
> the hypercall as it needs to happen on all cores, and the tlb will now be empty
> for that root.
>
> My assumption is that these local tlb flushes are rather rare as they will
> only happen when:
> - new root is allocated
> - we need to switch to a special root
>
KVM's MMU is an amazing maze so I'd appreciate if someone more
knowledgeble corrects me;t my understanding is that we call
*_flush_tlb_current() from two places:
kvm_mmu_load() and this covers the two cases above. These should not be
common under normal circumstances but can be frequent in some special
cases, e.g. when running a nested setup. Given that we're already
running on top of Hyper-V, this means 3+ level nesting which I don't
believe anyone really cares about.
kvm_vcpu_flush_tlb_current() from KVM_REQ_TLB_FLUSH_CURRENT. These are
things like some CR4 writes, APIC mode changes, ... which also shouldn't
be that common but VM boot time can be affected. So I'd suggest to test
big VM startup time, i.e. take the biggest available instance type on
Azure and measure how much time it takes to boot a VM which has the same
vCPU count. Honestly, I don't expect to see a significant change but I
guess it's still worth checking.
> So not very frequent post vm boot (with or without pinning). And the effect of the
> tlb being empty for that root on other CPUs should be a neutral, as users of the
> root would have performed the same local flush at a later point in
> time (when using it).
>
> All the other mmu updates use kvm_flush_remote_tlbs* which already go
> through the hypercall.
--
Vitaly
^ permalink raw reply
* Re: [PATCH net-next v6 4/4] test/vsock: Add ioctl SIOCINQ tests
From: Luigi Leonardi @ 2025-07-09 15:05 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-hyperv, virtualization, netdev,
linux-kernel, niuxuewei97
In-Reply-To: <20250708-siocinq-v6-4-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:14PM +0800, Xuewei Niu wrote:
>Add 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/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 79 insertions(+)
>
>diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>index be6ce764f69480c0f9c3e2288fc19cd2e74be148..a66d2360133dd0e36940a5907679aeacc8af7714 100644
>--- a/tools/testing/vsock/vsock_test.c
>+++ b/tools/testing/vsock/vsock_test.c
>@@ -24,6 +24,7 @@
> #include <linux/time64.h>
> #include <pthread.h>
> #include <fcntl.h>
>+#include <linux/sockios.h>
>
> #include "vsock_test_zerocopy.h"
> #include "timeout.h"
>@@ -1307,6 +1308,54 @@ 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");
>+
>+ close(client_fd);
>+}
>+
>+static void test_unread_bytes_client(const struct test_opts *opts, int type)
>+{
>+ unsigned char buf[MSG_BUF_IOCTL_LEN];
>+ int fd;
>+
>+ 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.
>+ */
>+ if (!vsock_ioctl_int(fd, SIOCINQ, MSG_BUF_IOCTL_LEN)) {
>+ fprintf(stderr, "Test skipped, SIOCINQ not supported.\n");
>+ goto out;
>+ }
>+
>+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
>+ /* All data has been consumed, so the expected is 0. */
>+ vsock_ioctl_int(fd, SIOCINQ, 0);
>+
>+out:
>+ close(fd);
>+}
>+
> static void test_stream_unsent_bytes_client(const struct test_opts *opts)
> {
> test_unsent_bytes_client(opts, SOCK_STREAM);
>@@ -1327,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
>@@ -2276,6 +2345,16 @@ static struct test_case test_cases[] = {
> .run_client = test_stream_transport_change_client,
> .run_server = test_stream_transport_change_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,
>+ },
> {},
> };
>
>
>--
>2.34.1
>
I ran the tests, everything went smoothly!
I had to apply this patch[1] first otherwise the transport_change test
would cause problems.
Tested-by: Luigi Leonardi <leonardi@redhat.com>
Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
Thanks for the series!
[1]https://lore.kernel.org/netdev/20250708111701.129585-1-sgarzare@redhat.com/
^ permalink raw reply
* Re: [PATCH net-next v6 3/4] test/vsock: Add retry mechanism to ioctl wrapper
From: Luigi Leonardi @ 2025-07-09 15:02 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-hyperv, virtualization, netdev,
linux-kernel, niuxuewei97
In-Reply-To: <20250708-siocinq-v6-3-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:13PM +0800, Xuewei Niu wrote:
>Wrap the ioctl in `ioctl_int()`, which takes a pointer to the actual
>int value and an expected int value. The function will not return until
>either the ioctl returns the expected value or a timeout occurs, thus
>avoiding immediate failure.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> tools/testing/vsock/util.c | 30 +++++++++++++++++++++---------
> tools/testing/vsock/util.h | 1 +
> 2 files changed, 22 insertions(+), 9 deletions(-)
>
>diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
>index 803f1e075b62228c25f9dffa1eff131b8072a06a..1e65c5abd85b8bcf5886272de15437d7be13eb89 100644
>--- a/tools/testing/vsock/util.c
>+++ b/tools/testing/vsock/util.c
>@@ -17,6 +17,7 @@
> #include <unistd.h>
> #include <assert.h>
> #include <sys/epoll.h>
>+#include <sys/ioctl.h>
> #include <sys/mman.h>
> #include <linux/sockios.h>
>
>@@ -101,28 +102,39 @@ 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 false if the op is not supported.
> */
>-bool vsock_wait_sent(int fd)
>+bool vsock_ioctl_int(int fd, unsigned long op, int expected)
> {
>- int ret, sock_bytes_unsent;
>+ int actual, ret;
>+ char name[32];
>+
>+ 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 >= 0;
>+}
>+
>+/* 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)
>+{
>+ return vsock_ioctl_int(fd, SIOCOUTQ, 0);
> }
>
> /* Create socket <type>, bind to <cid, port>.
>diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
>index fdd4649fe2d49f57c93c4aa5dfbb37b710c65918..142c02a6834acb7117aca485b661332b73754b63 100644
>--- a/tools/testing/vsock/util.h
>+++ b/tools/testing/vsock/util.h
>@@ -87,6 +87,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);
>+bool vsock_ioctl_int(int fd, unsigned long op, 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);
>
>--
>2.34.1
>
Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
^ permalink raw reply
* Re: [PATCH net-next v6 2/4] vsock: Add support for SIOCINQ ioctl
From: Luigi Leonardi @ 2025-07-09 15:00 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-hyperv, virtualization, netdev,
linux-kernel, niuxuewei97
In-Reply-To: <20250708-siocinq-v6-2-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:12PM +0800, Xuewei Niu wrote:
>Add support for SIOCINQ ioctl, indicating the length of bytes unread in the
>socket. The value is obtained from `vsock_stream_has_data()`.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>index 2e7a3034e965db30b6ee295370d866e6d8b1c341..bae6b89bb5fb7dd7a3a378f92097561a98a0c814 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) {
>+ ret = -EOPNOTSUPP;
>+ break;
>+ }
>+
>+ if (sock_type_connectible(sk->sk_type) &&
>+ sk->sk_state == TCP_LISTEN) {
>+ ret = -EINVAL;
>+ break;
>+ }
>+
>+ n_bytes = vsock_stream_has_data(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
>
LGTM!
Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
^ permalink raw reply
* [PATCH] net: mana: fix spelling for mana_gd_deregiser_irq()
From: Shradha Gupta @ 2025-07-09 13:43 UTC (permalink / raw)
To: Dexuan Cui, Wei Liu, Haiyang Zhang, K. Y. Srinivasan, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Konstantin Taranov, Souradeep Chakrabarti, Erni Sri Satya Vennela,
Long Li, Dipayaan Roy, Shiraz Saleem
Cc: Shradha Gupta, netdev, linux-hyperv, linux-kernel, Paul Rosswurm,
Shradha Gupta
Fix the typo in function name mana_gd_deregiser_irq()
Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
---
drivers/net/ethernet/microsoft/mana/gdma_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index a468cd8e5f36..d6c0699bc8cf 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -657,7 +657,7 @@ static int mana_gd_register_irq(struct gdma_queue *queue,
return 0;
}
-static void mana_gd_deregiser_irq(struct gdma_queue *queue)
+static void mana_gd_deregister_irq(struct gdma_queue *queue)
{
struct gdma_dev *gd = queue->gdma_dev;
struct gdma_irq_context *gic;
@@ -750,7 +750,7 @@ static void mana_gd_destroy_eq(struct gdma_context *gc, bool flush_evenets,
dev_warn(gc->dev, "Failed to flush EQ: %d\n", err);
}
- mana_gd_deregiser_irq(queue);
+ mana_gd_deregister_irq(queue);
if (queue->eq.disable_needed)
mana_gd_disable_queue(queue);
base-commit: ea988b450690448d5b12ce743a598ade7a8c34b1
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v3] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Saurabh Singh Sengar @ 2025-07-09 11:22 UTC (permalink / raw)
To: Naman Jain
Cc: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Michael Kelley, linux-hyperv, linux-kernel, Olaf Hering
In-Reply-To: <20250708080319.3904-1-namjain@linux.microsoft.com>
On Tue, Jul 08, 2025 at 01:33:19PM +0530, Naman Jain wrote:
> Size of ring buffer, as defined in uio_hv_generic driver, is no longer
> fixed to 16 KB. This creates a problem in fcopy, since this size was
> hardcoded. With the change in place to make ring sysfs node actually
> reflect the size of underlying ring buffer, it is safe to get the size
> of ring sysfs file and use it for ring buffer size in fcopy daemon.
> Fix the issue of disparity in ring buffer size, by making it dynamic
> in fcopy uio daemon.
>
> Cc: stable@vger.kernel.org
> Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
> tools/hv/hv_fcopy_uio_daemon.c | 82 +++++++++++++++++++++++++++++++---
> 1 file changed, 75 insertions(+), 7 deletions(-)
>
> diff --git a/tools/hv/hv_fcopy_uio_daemon.c b/tools/hv/hv_fcopy_uio_daemon.c
> index 0198321d14a2..5388ee1ebf4d 100644
> --- a/tools/hv/hv_fcopy_uio_daemon.c
> +++ b/tools/hv/hv_fcopy_uio_daemon.c
> @@ -36,6 +36,7 @@
> #define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
>
> #define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
> +#define FCOPY_CHANNELS_PATH "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/channels"
We can use a single path up to the device ID and then append either 'uio' or 'channels' using
two separate variables.
>
> #define FCOPY_VER_COUNT 1
> static const int fcopy_versions[] = {
> @@ -47,9 +48,62 @@ static const int fw_versions[] = {
> UTIL_FW_VERSION
> };
>
> -#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */
> +static uint32_t get_ring_buffer_size(void)
> +{
> + char ring_path[PATH_MAX];
> + DIR *dir;
> + struct dirent *entry;
> + struct stat st;
> + uint32_t ring_size = 0;
> + int retry_count = 0;
>
> -static unsigned char desc[HV_RING_SIZE];
> + /* Find the channel directory */
> + dir = opendir(FCOPY_CHANNELS_PATH);
> + if (!dir) {
> + usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
> + dir = opendir(FCOPY_CHANNELS_PATH);
> + if (!dir) {
> + syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
> + return 0;
> + }
> + }
> +
> +retry_once:
> + while ((entry = readdir(dir)) != NULL) {
> + if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
> + strcmp(entry->d_name, "..") != 0) {
> + snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
> + FCOPY_CHANNELS_PATH, entry->d_name);
> +
> + if (stat(ring_path, &st) == 0) {
> + /*
> + * stat returns size of Tx, Rx rings combined,
> + * so take half of it for individual ring size.
> + */
> + ring_size = (uint32_t)st.st_size / 2;
> + syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
> + ring_path, ring_size);
> + break;
> + }
> + }
> + }
> +
> + if (!ring_size && retry_count == 0) {
> + retry_count = 1;
> + rewinddir(dir);
> + usleep(100 * 1000); /* Wait 100ms and retry once */
> + goto retry_once;
Is this retry solving any real problem ?
> + }
> +
> + closedir(dir);
> +
> + if (!ring_size)
> + syslog(LOG_ERR, "Could not determine ring size");
> +
> + return ring_size;
> +}
> +
> +static unsigned char *desc;
>
> static int target_fd;
> static char target_fname[PATH_MAX];
> @@ -406,7 +460,7 @@ int main(int argc, char *argv[])
> int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
> struct vmbus_br txbr, rxbr;
> void *ring;
> - uint32_t len = HV_RING_SIZE;
> + uint32_t ring_size, len;
> char uio_name[NAME_MAX] = {0};
> char uio_dev_path[PATH_MAX] = {0};
>
> @@ -437,6 +491,20 @@ int main(int argc, char *argv[])
> openlog("HV_UIO_FCOPY", 0, LOG_USER);
> syslog(LOG_INFO, "starting; pid is:%d", getpid());
>
> + ring_size = get_ring_buffer_size();
> + if (!ring_size) {
> + ret = -ENODEV;
> + goto exit;
> + }
> +
> + len = ring_size;
Do we need this ?
> + desc = malloc(ring_size * sizeof(unsigned char));
> + if (!desc) {
> + syslog(LOG_ERR, "malloc failed for desc buffer");
> + ret = -ENOMEM;
> + goto exit;
> + }
This memory is not being freed anywhere. While I agree that freeing memory at
program exit may not have much practical value, we can easily address
this by adding a goto label for cleanup, this will keep all the static code
analyzers happy.
> +
> fcopy_get_first_folder(FCOPY_UIO, uio_name);
> snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
> fcopy_fd = open(uio_dev_path, O_RDWR);
> @@ -448,14 +516,14 @@ int main(int argc, char *argv[])
> goto exit;
> }
>
> - ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
> + ring = vmbus_uio_map(&fcopy_fd, ring_size);
> if (!ring) {
> ret = errno;
> syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
> goto close;
> }
> - vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
> - vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
> + vmbus_br_setup(&txbr, ring, ring_size);
> + vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
>
> rxbr.vbr->imask = 0;
>
> @@ -472,7 +540,7 @@ int main(int argc, char *argv[])
> goto close;
> }
>
> - len = HV_RING_SIZE;
> + len = ring_size;
> ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
> if (unlikely(ret <= 0)) {
> /* This indicates a failure to communicate (or worse) */
>
> base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
> --
> 2.34.1
^ permalink raw reply
* Re: [PATCH] PCI/MSI: Initialize the prepare descriptor by default
From: Naman Jain @ 2025-07-09 4:42 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Shradha Gupta, Bjorn Helgaas, Thomas Gleixner, Marc Zyngier,
Lorenzo Pieralisi, Shivamurthy Shastri, linux-pci, linux-kernel,
linux-hyperv, Roman Kisel
In-Reply-To: <20250708160817.GA2148355@bhelgaas>
On 7/8/2025 9:38 PM, Bjorn Helgaas wrote:
> On Tue, Jul 08, 2025 at 03:45:05PM +0530, Naman Jain wrote:
>> On 7/8/2025 3:32 PM, Shradha Gupta wrote:
>>> On Tue, Jul 08, 2025 at 10:48:48AM +0530, Naman Jain wrote:
>>>> Plug the default MSI-X prepare descriptor for non-implemented ops by
>>>> default to workaround the inability of Hyper-V vPCI module to setup
>>>> the MSI-X descriptors properly; especially for dynamically allocated
>>>> MSI-X.
>>>>
>>>> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
>>>> ---
>>>> drivers/pci/msi/irqdomain.c | 2 ++
>>>> 1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
>>>> index 765312c92d9b..655e99b9c8cc 100644
>>>> --- a/drivers/pci/msi/irqdomain.c
>>>> +++ b/drivers/pci/msi/irqdomain.c
>>>> @@ -84,6 +84,8 @@ static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
>>>> } else {
>>>> if (ops->set_desc == NULL)
>>>> ops->set_desc = pci_msi_domain_set_desc;
>>>> + if (ops->prepare_desc == NULL)
>>>> + ops->prepare_desc = pci_msix_prepare_desc;
>>>> }
>>>> }
>>>>
>>>> base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
>>>> --
>>>> 2.34.1
>>>>
>>>
>>> Hey Naman,
>>>
>>> can you please try your tests with this patch:
>>> https://lore.kernel.org/all/1749651015-9668-1-git-send-email-shradhagupta@linux.microsoft.com/
>>> I think this should help your use case
>>
>> Hey,
>> Thanks for sharing this, this works for me.
>>
>> Closing this thread.
>
> I guess this means we should ignore this patch? If it turns out that
> we do need this patch, I'd like to add some details in the commit log
> about what this problem looks like to users.
>
> Bjorn
Yes, my patch is no longer required, since it was doing the same thing
that Shradha's patch (1-2) were doing, but in a different way. Shradha's
patch is better and would suffice for the use case. Please ignore this
patch.
Thanks.
Regards,
Naman
^ permalink raw reply
* Re: [PATCH] PCI/MSI: Initialize the prepare descriptor by default
From: Bjorn Helgaas @ 2025-07-08 16:08 UTC (permalink / raw)
To: Naman Jain
Cc: Shradha Gupta, Bjorn Helgaas, Thomas Gleixner, Marc Zyngier,
Lorenzo Pieralisi, Shivamurthy Shastri, linux-pci, linux-kernel,
linux-hyperv, Roman Kisel
In-Reply-To: <e589da81-ed8d-4fbd-8a29-687eb271d1fe@linux.microsoft.com>
On Tue, Jul 08, 2025 at 03:45:05PM +0530, Naman Jain wrote:
> On 7/8/2025 3:32 PM, Shradha Gupta wrote:
> > On Tue, Jul 08, 2025 at 10:48:48AM +0530, Naman Jain wrote:
> > > Plug the default MSI-X prepare descriptor for non-implemented ops by
> > > default to workaround the inability of Hyper-V vPCI module to setup
> > > the MSI-X descriptors properly; especially for dynamically allocated
> > > MSI-X.
> > >
> > > Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> > > ---
> > > drivers/pci/msi/irqdomain.c | 2 ++
> > > 1 file changed, 2 insertions(+)
> > >
> > > diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
> > > index 765312c92d9b..655e99b9c8cc 100644
> > > --- a/drivers/pci/msi/irqdomain.c
> > > +++ b/drivers/pci/msi/irqdomain.c
> > > @@ -84,6 +84,8 @@ static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
> > > } else {
> > > if (ops->set_desc == NULL)
> > > ops->set_desc = pci_msi_domain_set_desc;
> > > + if (ops->prepare_desc == NULL)
> > > + ops->prepare_desc = pci_msix_prepare_desc;
> > > }
> > > }
> > >
> > > base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
> > > --
> > > 2.34.1
> > >
> >
> > Hey Naman,
> >
> > can you please try your tests with this patch:
> > https://lore.kernel.org/all/1749651015-9668-1-git-send-email-shradhagupta@linux.microsoft.com/
> > I think this should help your use case
>
> Hey,
> Thanks for sharing this, this works for me.
>
> Closing this thread.
I guess this means we should ignore this patch? If it turns out that
we do need this patch, I'd like to add some details in the commit log
about what this problem looks like to users.
Bjorn
^ permalink raw reply
* Re: [PATCH v5 03/10] dt-bindings: reserved-memory: Wakeup Mailbox for Intel processors
From: Rob Herring (Arm) @ 2025-07-08 12:41 UTC (permalink / raw)
To: Ricardo Neri
Cc: Haiyang Zhang, Yunhong Jiang, Conor Dooley, K. Y. Srinivasan,
Wei Liu, Dexuan Cui, Chris Oo, Kirill A. Shutemov, Michael Kelley,
Ricardo Neri, Saurabh Sengar, devicetree, linux-acpi,
linux-kernel, Rafael J. Wysocki, Krzysztof Kozlowski,
linux-hyperv, x86
In-Reply-To: <20250627-rneri-wakeup-mailbox-v5-3-df547b1d196e@linux.intel.com>
On Fri, 27 Jun 2025 20:35:09 -0700, Ricardo Neri wrote:
> Add DeviceTree bindings to enumerate the wakeup mailbox used in platform
> firmware for Intel processors.
>
> x86 platforms commonly boot secondary CPUs using an INIT assert, de-assert
> followed by Start-Up IPI messages. The wakeup mailbox can be used when this
> mechanism is unavailable.
>
> The wakeup mailbox offers more control to the operating system to boot
> secondary CPUs than a spin-table. It allows the reuse of same wakeup vector
> for all CPUs while maintaining control over which CPUs to boot and when.
> While it is possible to achieve the same level of control using a spin-
> table, it would require to specify a separate `cpu-release-addr` for each
> secondary CPU.
>
> The operation and structure of the mailbox is described in the
> Multiprocessor Wakeup Structure defined in the ACPI specification. Note
> that this structure does not specify how to publish the mailbox to the
> operating system (ACPI-based platform firmware uses a separate table). No
> ACPI table is needed in DeviceTree-based firmware to enumerate the mailbox.
>
> Add a `compatible` property that the operating system can use to discover
> the mailbox. Nodes wanting to refer to the reserved memory usually define a
> `memory-region` property. /cpus/cpu* nodes would want to refer to the
> mailbox, but they do not have such property defined in the DeviceTree
> specification. Moreover, it would imply that there is a memory region per
> CPU.
>
> Co-developed-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
> Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
> ---
> Changes since v4:
> - Specified the version and section of the ACPI spec in which the
> wakeup mailbox is defined. (Rafael)
> - Fixed a warning from yamllint about line lengths of URLs.
>
> Changes since v3:
> - Removed redefinitions of the mailbox and instead referred to ACPI
> specification as per discussion on LKML.
> - Clarified that DeviceTree-based firmware do not require the use of
> ACPI tables to enumerate the mailbox. (Rob)
> - Described the need of using a `compatible` property.
> - Dropped the `alignment` property. (Krzysztof, Rafael)
> - Used a real address for the mailbox node. (Krzysztof)
>
> Changes since v2:
> - Implemented the mailbox as a reserved-memory node. Add to it a
> `compatible` property. (Krzysztof)
> - Explained the relationship between the mailbox and the `enable-mehod`
> property of the CPU nodes.
> - Expanded the documentation of the binding.
>
> Changes since v1:
> - Added more details to the description of the binding.
> - Added requirement a new requirement for cpu@N nodes to add an
> `enable-method`.
> ---
> .../reserved-memory/intel,wakeup-mailbox.yaml | 50 ++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH net-next v6 4/4] test/vsock: Add ioctl SIOCINQ tests
From: Stefano Garzarella @ 2025-07-08 10:57 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-4-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:14PM +0800, Xuewei Niu wrote:
>Add 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/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 79 insertions(+)
While testing this, I found an issue with the previous test.
I'll send a patch to fix that, but skipping that test, this run well:
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
>diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
>index be6ce764f69480c0f9c3e2288fc19cd2e74be148..a66d2360133dd0e36940a5907679aeacc8af7714 100644
>--- a/tools/testing/vsock/vsock_test.c
>+++ b/tools/testing/vsock/vsock_test.c
>@@ -24,6 +24,7 @@
> #include <linux/time64.h>
> #include <pthread.h>
> #include <fcntl.h>
>+#include <linux/sockios.h>
>
> #include "vsock_test_zerocopy.h"
> #include "timeout.h"
>@@ -1307,6 +1308,54 @@ 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");
>+
>+ close(client_fd);
>+}
>+
>+static void test_unread_bytes_client(const struct test_opts *opts, int type)
>+{
>+ unsigned char buf[MSG_BUF_IOCTL_LEN];
>+ int fd;
>+
>+ 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.
>+ */
>+ if (!vsock_ioctl_int(fd, SIOCINQ, MSG_BUF_IOCTL_LEN)) {
>+ fprintf(stderr, "Test skipped, SIOCINQ not supported.\n");
>+ goto out;
>+ }
>+
>+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
>+ /* All data has been consumed, so the expected is 0. */
>+ vsock_ioctl_int(fd, SIOCINQ, 0);
>+
>+out:
>+ close(fd);
>+}
>+
> static void test_stream_unsent_bytes_client(const struct test_opts *opts)
> {
> test_unsent_bytes_client(opts, SOCK_STREAM);
>@@ -1327,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
>@@ -2276,6 +2345,16 @@ static struct test_case test_cases[] = {
> .run_client = test_stream_transport_change_client,
> .run_server = test_stream_transport_change_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,
>+ },
> {},
> };
>
>
>--
>2.34.1
>
^ permalink raw reply
* Re: [PATCH net-next v6 3/4] test/vsock: Add retry mechanism to ioctl wrapper
From: Stefano Garzarella @ 2025-07-08 10:54 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-3-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:13PM +0800, Xuewei Niu wrote:
>Wrap the ioctl in `ioctl_int()`, which takes a pointer to the actual
>int value and an expected int value. The function will not return until
>either the ioctl returns the expected value or a timeout occurs, thus
>avoiding immediate failure.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> tools/testing/vsock/util.c | 30 +++++++++++++++++++++---------
> tools/testing/vsock/util.h | 1 +
> 2 files changed, 22 insertions(+), 9 deletions(-)
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
>diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
>index 803f1e075b62228c25f9dffa1eff131b8072a06a..1e65c5abd85b8bcf5886272de15437d7be13eb89 100644
>--- a/tools/testing/vsock/util.c
>+++ b/tools/testing/vsock/util.c
>@@ -17,6 +17,7 @@
> #include <unistd.h>
> #include <assert.h>
> #include <sys/epoll.h>
>+#include <sys/ioctl.h>
> #include <sys/mman.h>
> #include <linux/sockios.h>
>
>@@ -101,28 +102,39 @@ 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 false if the op is not supported.
> */
>-bool vsock_wait_sent(int fd)
>+bool vsock_ioctl_int(int fd, unsigned long op, int expected)
> {
>- int ret, sock_bytes_unsent;
>+ int actual, ret;
>+ char name[32];
>+
>+ 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 >= 0;
>+}
>+
>+/* 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)
>+{
>+ return vsock_ioctl_int(fd, SIOCOUTQ, 0);
> }
>
> /* Create socket <type>, bind to <cid, port>.
>diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
>index fdd4649fe2d49f57c93c4aa5dfbb37b710c65918..142c02a6834acb7117aca485b661332b73754b63 100644
>--- a/tools/testing/vsock/util.h
>+++ b/tools/testing/vsock/util.h
>@@ -87,6 +87,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);
>+bool vsock_ioctl_int(int fd, unsigned long op, 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);
>
>--
>2.34.1
>
^ permalink raw reply
* Re: [PATCH net-next v6 2/4] vsock: Add support for SIOCINQ ioctl
From: Stefano Garzarella @ 2025-07-08 10:52 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-2-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:12PM +0800, Xuewei Niu wrote:
>Add support for SIOCINQ ioctl, indicating the length of bytes unread in the
>socket. The value is obtained from `vsock_stream_has_data()`.
>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>index 2e7a3034e965db30b6ee295370d866e6d8b1c341..bae6b89bb5fb7dd7a3a378f92097561a98a0c814 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) {
>+ ret = -EOPNOTSUPP;
>+ break;
>+ }
>+
>+ if (sock_type_connectible(sk->sk_type) &&
>+ sk->sk_state == TCP_LISTEN) {
>+ ret = -EINVAL;
>+ break;
>+ }
>+
>+ n_bytes = vsock_stream_has_data(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
* Re: [PATCH net-next v6 1/4] hv_sock: Return the readable bytes in hvs_stream_has_data()
From: Stefano Garzarella @ 2025-07-08 10:49 UTC (permalink / raw)
To: Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-1-3775f9a9e359@antgroup.com>
On Tue, Jul 08, 2025 at 02:36:11PM +0800, Xuewei Niu wrote:
>From: Dexuan Cui <decui@microsoft.com>
>
>When hv_sock was originally added, __vsock_stream_recvmsg() and
>vsock_stream_has_data() actually only needed to know whether there
>is any readable data or not, so hvs_stream_has_data() was written to
>return 1 or 0 for simplicity.
>
>However, now hvs_stream_has_data() should return the readable bytes
>because vsock_data_ready() -> vsock_stream_has_data() needs to know the
>actual bytes rather than a boolean value of 1 or 0.
>
>The SIOCINQ ioctl support also needs hvs_stream_has_data() to return
>the readable bytes.
>
>Let hvs_stream_has_data() return the readable bytes of the payload in
>the next host-to-guest VMBus hv_sock packet.
>
>Note: there may be multiple incoming hv_sock packets pending in the
>VMBus channel's ringbuffer, but so far there is not a VMBus API that
>allows us to know all the readable bytes in total without reading and
>caching the payload of the multiple packets, so let's just return the
>readable bytes of the next single packet. In the future, we'll either
>add a VMBus API that allows us to know the total readable bytes without
>touching the data in the ringbuffer, or the hv_sock driver needs to
>understand the VMBus packet format and parse the packets directly.
>
>Signed-off-by: Dexuan Cui <decui@microsoft.com>
>Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
>---
> net/vmw_vsock/hyperv_transport.c | 17 ++++++++++++++---
> 1 file changed, 14 insertions(+), 3 deletions(-)
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
>
>diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
>index 31342ab502b4fc35feb812d2c94e0e35ded73771..432fcbbd14d4f44bd2550be8376e42ce65122758 100644
>--- a/net/vmw_vsock/hyperv_transport.c
>+++ b/net/vmw_vsock/hyperv_transport.c
>@@ -694,15 +694,26 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
> static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> {
> struct hvsock *hvs = vsk->trans;
>+ bool need_refill;
> s64 ret;
>
> if (hvs->recv_data_len > 0)
>- return 1;
>+ return hvs->recv_data_len;
>
> switch (hvs_channel_readable_payload(hvs->chan)) {
> case 1:
>- ret = 1;
>- break;
>+ need_refill = !hvs->recv_desc;
>+ if (!need_refill)
>+ return -EIO;
>+
>+ hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
>+ if (!hvs->recv_desc)
>+ return -ENOBUFS;
>+
>+ ret = hvs_update_recv_data(hvs);
>+ if (ret)
>+ return ret;
>+ return hvs->recv_data_len;
> case 0:
> vsk->peer_shutdown |= SEND_SHUTDOWN;
> ret = 0;
>
>--
>2.34.1
>
^ permalink raw reply
* Re: [PATCH] PCI/MSI: Initialize the prepare descriptor by default
From: Naman Jain @ 2025-07-08 10:15 UTC (permalink / raw)
To: Shradha Gupta
Cc: Bjorn Helgaas, Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Shivamurthy Shastri, linux-pci, linux-kernel, linux-hyperv,
Roman Kisel
In-Reply-To: <20250708100248.GA27472@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
On 7/8/2025 3:32 PM, Shradha Gupta wrote:
> On Tue, Jul 08, 2025 at 10:48:48AM +0530, Naman Jain wrote:
>> Plug the default MSI-X prepare descriptor for non-implemented ops by
>> default to workaround the inability of Hyper-V vPCI module to setup
>> the MSI-X descriptors properly; especially for dynamically allocated
>> MSI-X.
>>
>> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
>> ---
>> drivers/pci/msi/irqdomain.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
>> index 765312c92d9b..655e99b9c8cc 100644
>> --- a/drivers/pci/msi/irqdomain.c
>> +++ b/drivers/pci/msi/irqdomain.c
>> @@ -84,6 +84,8 @@ static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
>> } else {
>> if (ops->set_desc == NULL)
>> ops->set_desc = pci_msi_domain_set_desc;
>> + if (ops->prepare_desc == NULL)
>> + ops->prepare_desc = pci_msix_prepare_desc;
>> }
>> }
>>
>>
>> base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
>> --
>> 2.34.1
>>
>
> Hey Naman,
>
> can you please try your tests with this patch:
> https://lore.kernel.org/all/1749651015-9668-1-git-send-email-shradhagupta@linux.microsoft.com/
> I think this should help your use case
>
> Regards,
> Shradha.
Hey,
Thanks for sharing this, this works for me.
Closing this thread.
Regards,
Naman
^ permalink raw reply
* Re: [PATCH] PCI/MSI: Initialize the prepare descriptor by default
From: Shradha Gupta @ 2025-07-08 10:02 UTC (permalink / raw)
To: Naman Jain
Cc: Bjorn Helgaas, Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Shivamurthy Shastri, linux-pci, linux-kernel, linux-hyperv,
Roman Kisel
In-Reply-To: <20250708051848.3214-1-namjain@linux.microsoft.com>
On Tue, Jul 08, 2025 at 10:48:48AM +0530, Naman Jain wrote:
> Plug the default MSI-X prepare descriptor for non-implemented ops by
> default to workaround the inability of Hyper-V vPCI module to setup
> the MSI-X descriptors properly; especially for dynamically allocated
> MSI-X.
>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
> drivers/pci/msi/irqdomain.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
> index 765312c92d9b..655e99b9c8cc 100644
> --- a/drivers/pci/msi/irqdomain.c
> +++ b/drivers/pci/msi/irqdomain.c
> @@ -84,6 +84,8 @@ static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
> } else {
> if (ops->set_desc == NULL)
> ops->set_desc = pci_msi_domain_set_desc;
> + if (ops->prepare_desc == NULL)
> + ops->prepare_desc = pci_msix_prepare_desc;
> }
> }
>
>
> base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
> --
> 2.34.1
>
Hey Naman,
can you please try your tests with this patch:
https://lore.kernel.org/all/1749651015-9668-1-git-send-email-shradhagupta@linux.microsoft.com/
I think this should help your use case
Regards,
Shradha.
^ permalink raw reply
* Re: [PATCH v3] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Naman Jain @ 2025-07-08 8:07 UTC (permalink / raw)
To: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Michael Kelley
Cc: linux-hyperv, linux-kernel, Olaf Hering, Saurabh Sengar
In-Reply-To: <20250708080319.3904-1-namjain@linux.microsoft.com>
On 7/8/2025 1:33 PM, Naman Jain wrote:
> Size of ring buffer, as defined in uio_hv_generic driver, is no longer
> fixed to 16 KB. This creates a problem in fcopy, since this size was
> hardcoded. With the change in place to make ring sysfs node actually
> reflect the size of underlying ring buffer, it is safe to get the size
> of ring sysfs file and use it for ring buffer size in fcopy daemon.
> Fix the issue of disparity in ring buffer size, by making it dynamic
> in fcopy uio daemon.
>
> Cc: stable@vger.kernel.org
> Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
Noticed that I missed adding change logs. Adding them now.
Changes since v2:
https://lore.kernel.org/all/20250701104837.3006-1-namjain@linux.microsoft.com/
* Removed fallback mechanism to default size, to keep fcopy behavior
consistent (Long's suggestion). If ring sysfs file is not present for
some reason, things are already bad and its the right thing for fcopy to
abort.
Changes since v1:
https://lore.kernel.org/all/20250620070618.3097-1-namjain@linux.microsoft.com/
* Removed unnecessary type casting in malloc for desc variable (Olaf)
* Added retry mechanisms to avoid potential race conditions (Michael)
* Moved the logic to fetch ring size to a later part in main (Michael)
> tools/hv/hv_fcopy_uio_daemon.c | 82 +++++++++++++++++++++++++++++++---
> 1 file changed, 75 insertions(+), 7 deletions(-)
>
Regards,
Naman
^ permalink raw reply
* [PATCH v3] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Naman Jain @ 2025-07-08 8:03 UTC (permalink / raw)
To: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Michael Kelley
Cc: linux-hyperv, linux-kernel, Olaf Hering, Saurabh Sengar,
Naman Jain
Size of ring buffer, as defined in uio_hv_generic driver, is no longer
fixed to 16 KB. This creates a problem in fcopy, since this size was
hardcoded. With the change in place to make ring sysfs node actually
reflect the size of underlying ring buffer, it is safe to get the size
of ring sysfs file and use it for ring buffer size in fcopy daemon.
Fix the issue of disparity in ring buffer size, by making it dynamic
in fcopy uio daemon.
Cc: stable@vger.kernel.org
Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
---
tools/hv/hv_fcopy_uio_daemon.c | 82 +++++++++++++++++++++++++++++++---
1 file changed, 75 insertions(+), 7 deletions(-)
diff --git a/tools/hv/hv_fcopy_uio_daemon.c b/tools/hv/hv_fcopy_uio_daemon.c
index 0198321d14a2..5388ee1ebf4d 100644
--- a/tools/hv/hv_fcopy_uio_daemon.c
+++ b/tools/hv/hv_fcopy_uio_daemon.c
@@ -36,6 +36,7 @@
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
#define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
+#define FCOPY_CHANNELS_PATH "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/channels"
#define FCOPY_VER_COUNT 1
static const int fcopy_versions[] = {
@@ -47,9 +48,62 @@ static const int fw_versions[] = {
UTIL_FW_VERSION
};
-#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */
+static uint32_t get_ring_buffer_size(void)
+{
+ char ring_path[PATH_MAX];
+ DIR *dir;
+ struct dirent *entry;
+ struct stat st;
+ uint32_t ring_size = 0;
+ int retry_count = 0;
-static unsigned char desc[HV_RING_SIZE];
+ /* Find the channel directory */
+ dir = opendir(FCOPY_CHANNELS_PATH);
+ if (!dir) {
+ usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
+ dir = opendir(FCOPY_CHANNELS_PATH);
+ if (!dir) {
+ syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
+ return 0;
+ }
+ }
+
+retry_once:
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
+ strcmp(entry->d_name, "..") != 0) {
+ snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
+ FCOPY_CHANNELS_PATH, entry->d_name);
+
+ if (stat(ring_path, &st) == 0) {
+ /*
+ * stat returns size of Tx, Rx rings combined,
+ * so take half of it for individual ring size.
+ */
+ ring_size = (uint32_t)st.st_size / 2;
+ syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
+ ring_path, ring_size);
+ break;
+ }
+ }
+ }
+
+ if (!ring_size && retry_count == 0) {
+ retry_count = 1;
+ rewinddir(dir);
+ usleep(100 * 1000); /* Wait 100ms and retry once */
+ goto retry_once;
+ }
+
+ closedir(dir);
+
+ if (!ring_size)
+ syslog(LOG_ERR, "Could not determine ring size");
+
+ return ring_size;
+}
+
+static unsigned char *desc;
static int target_fd;
static char target_fname[PATH_MAX];
@@ -406,7 +460,7 @@ int main(int argc, char *argv[])
int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
struct vmbus_br txbr, rxbr;
void *ring;
- uint32_t len = HV_RING_SIZE;
+ uint32_t ring_size, len;
char uio_name[NAME_MAX] = {0};
char uio_dev_path[PATH_MAX] = {0};
@@ -437,6 +491,20 @@ int main(int argc, char *argv[])
openlog("HV_UIO_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
+ ring_size = get_ring_buffer_size();
+ if (!ring_size) {
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ len = ring_size;
+ desc = malloc(ring_size * sizeof(unsigned char));
+ if (!desc) {
+ syslog(LOG_ERR, "malloc failed for desc buffer");
+ ret = -ENOMEM;
+ goto exit;
+ }
+
fcopy_get_first_folder(FCOPY_UIO, uio_name);
snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
fcopy_fd = open(uio_dev_path, O_RDWR);
@@ -448,14 +516,14 @@ int main(int argc, char *argv[])
goto exit;
}
- ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
+ ring = vmbus_uio_map(&fcopy_fd, ring_size);
if (!ring) {
ret = errno;
syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
goto close;
}
- vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
- vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
+ vmbus_br_setup(&txbr, ring, ring_size);
+ vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
rxbr.vbr->imask = 0;
@@ -472,7 +540,7 @@ int main(int argc, char *argv[])
goto close;
}
- len = HV_RING_SIZE;
+ len = ring_size;
ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
if (unlikely(ret <= 0)) {
/* This indicates a failure to communicate (or worse) */
base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v6 0/4] vsock: Introduce SIOCINQ ioctl support
From: Xuewei Niu @ 2025-07-08 6:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
niuxuewei97
Introduce SIOCINQ ioctl support for vsock, indicating the length of unread
bytes.
Similar with SIOCOUTQ ioctl, the information is transport-dependent.
The first patch adds SIOCINQ ioctl support in AF_VSOCK.
Thanks to @dexuan, the second patch is to fix the issue where hyper-v
`hvs_stream_has_data()` doesn't return the readable bytes.
The third patch wraps the ioctl into `ioctl_int()`, which implements a
retry mechanism to prevent immediate failure.
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.
v2->v3:
https://lore.kernel.org/netdev/20250613031152.1076725-1-niuxuewei.nxw@antgroup.com/
- Update commit messages following the guidelines
- Remove `unread_bytes` callback and reuse `vsock_stream_has_data()`
- Move the tests to the end of array
- Split the refactoring patch
- Include <sys/ioctl.h> in the util.c
v3->v4:
https://lore.kernel.org/netdev/20250617045347.1233128-1-niuxuewei.nxw@antgroup.com/
- Hyper-v `hvs_stream_has_data()` returns the readable bytes
- Skip testing the null value for `actual` (int pointer)
- Rename `ioctl_int()` to `vsock_ioctl_int()`
- Fix a typo and a format issue in comments
- Remove the `RECEIVED` barrier.
- The return type of `vsock_ioctl_int()` has been changed to bool
v4->v5:
https://lore.kernel.org/netdev/20250630075727.210462-1-niuxuewei.nxw@antgroup.com/
- Put the hyper-v fix before the SIOCINQ ioctl implementation.
- Remove my SOB from the hyper-v fix patch.
- Move the `need_refill` initialization into the `case 1` block.
- Remove the `actual` argument from `vsock_ioctl_int()`.
- Replace `TIOCINQ` with `SIOCINQ`.
v5->v6:
https://lore.kernel.org/netdev/20250706-siocinq-v5-0-8d0b96a87465@antgroup.com/
- Correct the author
- Fix a typo in hyper-v fix
---
Dexuan Cui (1):
hv_sock: Return the readable bytes in hvs_stream_has_data()
Xuewei Niu (3):
vsock: Add support for SIOCINQ ioctl
test/vsock: Add retry mechanism to ioctl wrapper
test/vsock: Add ioctl SIOCINQ tests
net/vmw_vsock/af_vsock.c | 22 +++++++++++
net/vmw_vsock/hyperv_transport.c | 17 +++++++--
tools/testing/vsock/util.c | 30 ++++++++++-----
tools/testing/vsock/util.h | 1 +
tools/testing/vsock/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 137 insertions(+), 12 deletions(-)
---
base-commit: 5f712c3877f99d5b5e4d011955c6467ae0e535a6
change-id: 20250703-siocinq-9e2907939806
Best regards,
--
Xuewei Niu <niuxuewei.nxw@antgroup.com>
^ permalink raw reply
* [PATCH net-next v6 1/4] hv_sock: Return the readable bytes in hvs_stream_has_data()
From: Xuewei Niu @ 2025-07-08 6:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-0-3775f9a9e359@antgroup.com>
From: Dexuan Cui <decui@microsoft.com>
When hv_sock was originally added, __vsock_stream_recvmsg() and
vsock_stream_has_data() actually only needed to know whether there
is any readable data or not, so hvs_stream_has_data() was written to
return 1 or 0 for simplicity.
However, now hvs_stream_has_data() should return the readable bytes
because vsock_data_ready() -> vsock_stream_has_data() needs to know the
actual bytes rather than a boolean value of 1 or 0.
The SIOCINQ ioctl support also needs hvs_stream_has_data() to return
the readable bytes.
Let hvs_stream_has_data() return the readable bytes of the payload in
the next host-to-guest VMBus hv_sock packet.
Note: there may be multiple incoming hv_sock packets pending in the
VMBus channel's ringbuffer, but so far there is not a VMBus API that
allows us to know all the readable bytes in total without reading and
caching the payload of the multiple packets, so let's just return the
readable bytes of the next single packet. In the future, we'll either
add a VMBus API that allows us to know the total readable bytes without
touching the data in the ringbuffer, or the hv_sock driver needs to
understand the VMBus packet format and parse the packets directly.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
net/vmw_vsock/hyperv_transport.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 31342ab502b4fc35feb812d2c94e0e35ded73771..432fcbbd14d4f44bd2550be8376e42ce65122758 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -694,15 +694,26 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
static s64 hvs_stream_has_data(struct vsock_sock *vsk)
{
struct hvsock *hvs = vsk->trans;
+ bool need_refill;
s64 ret;
if (hvs->recv_data_len > 0)
- return 1;
+ return hvs->recv_data_len;
switch (hvs_channel_readable_payload(hvs->chan)) {
case 1:
- ret = 1;
- break;
+ need_refill = !hvs->recv_desc;
+ if (!need_refill)
+ return -EIO;
+
+ hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
+ if (!hvs->recv_desc)
+ return -ENOBUFS;
+
+ ret = hvs_update_recv_data(hvs);
+ if (ret)
+ return ret;
+ return hvs->recv_data_len;
case 0:
vsk->peer_shutdown |= SEND_SHUTDOWN;
ret = 0;
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v6 3/4] test/vsock: Add retry mechanism to ioctl wrapper
From: Xuewei Niu @ 2025-07-08 6:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-0-3775f9a9e359@antgroup.com>
Wrap the ioctl in `ioctl_int()`, which takes a pointer to the actual
int value and an expected int value. The function will not return until
either the ioctl returns the expected value or a timeout occurs, thus
avoiding immediate failure.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
tools/testing/vsock/util.c | 30 +++++++++++++++++++++---------
tools/testing/vsock/util.h | 1 +
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 803f1e075b62228c25f9dffa1eff131b8072a06a..1e65c5abd85b8bcf5886272de15437d7be13eb89 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -17,6 +17,7 @@
#include <unistd.h>
#include <assert.h>
#include <sys/epoll.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/sockios.h>
@@ -101,28 +102,39 @@ 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 false if the op is not supported.
*/
-bool vsock_wait_sent(int fd)
+bool vsock_ioctl_int(int fd, unsigned long op, int expected)
{
- int ret, sock_bytes_unsent;
+ int actual, ret;
+ char name[32];
+
+ 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 >= 0;
+}
+
+/* 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)
+{
+ return vsock_ioctl_int(fd, SIOCOUTQ, 0);
}
/* Create socket <type>, bind to <cid, port>.
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index fdd4649fe2d49f57c93c4aa5dfbb37b710c65918..142c02a6834acb7117aca485b661332b73754b63 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -87,6 +87,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);
+bool vsock_ioctl_int(int fd, unsigned long op, 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);
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v6 4/4] test/vsock: Add ioctl SIOCINQ tests
From: Xuewei Niu @ 2025-07-08 6:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-0-3775f9a9e359@antgroup.com>
Add 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/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index be6ce764f69480c0f9c3e2288fc19cd2e74be148..a66d2360133dd0e36940a5907679aeacc8af7714 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -24,6 +24,7 @@
#include <linux/time64.h>
#include <pthread.h>
#include <fcntl.h>
+#include <linux/sockios.h>
#include "vsock_test_zerocopy.h"
#include "timeout.h"
@@ -1307,6 +1308,54 @@ 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");
+
+ close(client_fd);
+}
+
+static void test_unread_bytes_client(const struct test_opts *opts, int type)
+{
+ unsigned char buf[MSG_BUF_IOCTL_LEN];
+ int fd;
+
+ 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.
+ */
+ if (!vsock_ioctl_int(fd, SIOCINQ, MSG_BUF_IOCTL_LEN)) {
+ fprintf(stderr, "Test skipped, SIOCINQ not supported.\n");
+ goto out;
+ }
+
+ recv_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
+ /* All data has been consumed, so the expected is 0. */
+ vsock_ioctl_int(fd, SIOCINQ, 0);
+
+out:
+ close(fd);
+}
+
static void test_stream_unsent_bytes_client(const struct test_opts *opts)
{
test_unsent_bytes_client(opts, SOCK_STREAM);
@@ -1327,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
@@ -2276,6 +2345,16 @@ static struct test_case test_cases[] = {
.run_client = test_stream_transport_change_client,
.run_server = test_stream_transport_change_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,
+ },
{},
};
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v6 2/4] vsock: Add support for SIOCINQ ioctl
From: Xuewei Niu @ 2025-07-08 6:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
niuxuewei97
In-Reply-To: <20250708-siocinq-v6-0-3775f9a9e359@antgroup.com>
Add support for SIOCINQ ioctl, indicating the length of bytes unread in the
socket. The value is obtained from `vsock_stream_has_data()`.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 2e7a3034e965db30b6ee295370d866e6d8b1c341..bae6b89bb5fb7dd7a3a378f92097561a98a0c814 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) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (sock_type_connectible(sk->sk_type) &&
+ sk->sk_state == TCP_LISTEN) {
+ ret = -EINVAL;
+ break;
+ }
+
+ n_bytes = vsock_stream_has_data(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
* Re: [PATCH net-next v5 1/4] hv_sock: Return the readable bytes in hvs_stream_has_data()
From: Xuewei Niu @ 2025-07-08 5:05 UTC (permalink / raw)
To: Stefano Garzarella, Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
fupan.lfp
In-Reply-To: <xhzslzuxrhdoixffmzwprn254ctolimj7giuxj4nfrfg23eesy@ycpe6kma5vih>
On 2025/7/7 21:40, Stefano Garzarella wrote:
> On Sun, Jul 06, 2025 at 12:36:29PM +0800, Xuewei Niu wrote:
>
> Again, this patch should have `From: Dexuan Cui <decui@microsoft.com>` on first line, and this is done automatically by `git format-patch` (or others tools) if the author is the right one in your branch.
> I'm not sure what is going on on your side, but you should avoid to reset the original author.
> Applying this patch we will have:
>
> commit ed36075e04ecbb1dd02a3d8eba5bfac6469d73e4
> Author: Xuewei Niu <niuxuewei97@gmail.com>
> Date: Sun Jul 6 12:36:29 2025 +0800
>
> hv_sock: Return the readable bytes in hvs_stream_has_data()
>
> This is not what we want, right?
>
>> When hv_sock was originally added, __vsock_stream_recvmsg() and
>> vsock_stream_has_data() actually only needed to know whether there
>> is any readable data or not, so hvs_stream_has_data() was written to
>> return 1 or 0 for simplicity.
>>
>> However, now hvs_stream_has_data() should return the readable bytes
>> because vsock_data_ready() -> vsock_stream_has_data() needs to know the
>> actual bytes rather than a boolean value of 1 or 0.
>>
>> The SIOCINQ ioctl support also needs hvs_stream_has_data() to return
>> the readable bytes.
>>
>> Let hvs_stream_has_data() return the readable bytes of the payload in
>> the next host-to-guest VMBus hv_sock packet.
>>
>> Note: there may be multpile incoming hv_sock packets pending in the
>> VMBus channel's ringbuffer, but so far there is not a VMBus API that
>> allows us to know all the readable bytes in total without reading and
>> caching the payload of the multiple packets, so let's just return the
>> readable bytes of the next single packet. In the future, we'll either
>> add a VMBus API that allows us to know the total readable bytes without
>> touching the data in the ringbuffer, or the hv_sock driver needs to
>> understand the VMBus packet format and parse the packets directly.
>>
>> Signed-off-by: Dexuan Cui <decui@microsoft.com>
>
> Your S-o-b was fine here, I was talking about the author.
I misunderstood the meaning of author. Sorry about that.
Will update this in v6.
Thanks,
Xuewei
> Thanks,
> Stefano
>
>> ---
>> net/vmw_vsock/hyperv_transport.c | 17 ++++++++++++++---
>> 1 file changed, 14 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
>> index 31342ab502b4fc35feb812d2c94e0e35ded73771..432fcbbd14d4f44bd2550be8376e42ce65122758 100644
>> --- a/net/vmw_vsock/hyperv_transport.c
>> +++ b/net/vmw_vsock/hyperv_transport.c
>> @@ -694,15 +694,26 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
>> static s64 hvs_stream_has_data(struct vsock_sock *vsk)
>> {
>> struct hvsock *hvs = vsk->trans;
>> + bool need_refill;
>> s64 ret;
>>
>> if (hvs->recv_data_len > 0)
>> - return 1;
>> + return hvs->recv_data_len;
>>
>> switch (hvs_channel_readable_payload(hvs->chan)) {
>> case 1:
>> - ret = 1;
>> - break;
>> + need_refill = !hvs->recv_desc;
>> + if (!need_refill)
>> + return -EIO;
>> +
>> + hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
>> + if (!hvs->recv_desc)
>> + return -ENOBUFS;
>> +
>> + ret = hvs_update_recv_data(hvs);
>> + if (ret)
>> + return ret;
>> + return hvs->recv_data_len;
>> case 0:
>> vsk->peer_shutdown |= SEND_SHUTDOWN;
>> ret = 0;
>>
>> --
>> 2.34.1
>>
^ permalink raw reply
* Re: [PATCH net-next v5 0/4] vsock: Introduce SIOCINQ ioctl support
From: Xuewei Niu @ 2025-07-08 5:23 UTC (permalink / raw)
To: Stefano Garzarella, Xuewei Niu
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-hyperv, virtualization, netdev, linux-kernel,
fupan.lfp
In-Reply-To: <yx44jpqxyi5yujwgdvyzajsjyf6rjqht5ypvp7q72imc6cfs2e@7yzhohzyilpq>
On 2025/7/7 21:44, Stefano Garzarella wrote:
> On Sun, Jul 06, 2025 at 12:36:28PM +0800, Xuewei Niu wrote:
>> Introduce SIOCINQ ioctl support for vsock, indicating the length of unread
>> bytes.
>>
>> Similar with SIOCOUTQ ioctl, the information is transport-dependent.
>>
>> The first patch adds SIOCINQ ioctl support in AF_VSOCK.
>>
>> Thanks to @dexuan, the second patch is to fix the issue where hyper-v
>> `hvs_stream_has_data()` doesn't return the readable bytes.
>>
>> The third patch wraps the ioctl into `ioctl_int()`, which implements a
>> retry mechanism to prevent immediate failure.
>>
>> 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.
>>
>> v2->v3:
>> https://lore.kernel.org/netdev/20250613031152.1076725-1-niuxuewei.nxw@antgroup.com/
>> - Update commit messages following the guidelines
>> - Remove `unread_bytes` callback and reuse `vsock_stream_has_data()`
>> - Move the tests to the end of array
>> - Split the refactoring patch
>> - Include <sys/ioctl.h> in the util.c
>>
>> v3->v4:
>> https://lore.kernel.org/netdev/20250617045347.1233128-1-niuxuewei.nxw@antgroup.com/
>> - Hyper-v `hvs_stream_has_data()` returns the readable bytes
>> - Skip testing the null value for `actual` (int pointer)
>> - Rename `ioctl_int()` to `vsock_ioctl_int()`
>> - Fix a typo and a format issue in comments
>> - Remove the `RECEIVED` barrier.
>> - The return type of `vsock_ioctl_int()` has been changed to bool
>>
>> v4->v5:
>> https://lore.kernel.org/netdev/20250630075727.210462-1-niuxuewei.nxw@antgroup.com/
>> - Put the hyper-v fix before the SIOCINQ ioctl implementation.
>> - Remove my SOB from the hyper-v fix patch.
>
> Has I mentioned, that was not the issue, but the wrong Author.
I see it now. I'll update the author in v6.
> There are also other issue, not sure how you're sending them, but I guess there are some issues with you `git format-patch` configuration:
I was using my personal email. I have changed to the right email now.
Hope everything goes fine with the next version.
Thanks,
Xuewei
>
> $ ./scripts/checkpatch.pl -g net-next..HEAD --codespell
> -----------------------------------------------------------------------------------
> Commit ed36075e04ec ("hv_sock: Return the readable bytes in hvs_stream_has_data()")
> -----------------------------------------------------------------------------------
> WARNING: 'multpile' may be misspelled - perhaps 'multiple'?
> #23:
> Note: there may be multpile incoming hv_sock packets pending in the
> ^^^^^^^^
>
> ERROR: Missing Signed-off-by: line by nominal patch author 'Xuewei Niu <niuxuewei97@gmail.com>'
>
> total: 1 errors, 1 warnings, 0 checks, 29 lines checked
>
> NOTE: For some of the reported defects, checkpatch may be able to
> mechanically convert to the typical style using --fix or --fix-inplace.
>
> Commit ed36075e04ec ("hv_sock: Return the readable bytes in hvs_stream_has_data()") has style problems, please review.
> ------------------------------------------------------------
> Commit 4e5c39e373fa ("vsock: Add support for SIOCINQ ioctl")
> ------------------------------------------------------------
> WARNING: From:/Signed-off-by: email address mismatch: 'From: Xuewei Niu <niuxuewei97@gmail.com>' != 'Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>'
>
> total: 0 errors, 1 warnings, 0 checks, 28 lines checked
>
> NOTE: For some of the reported defects, checkpatch may be able to
> mechanically convert to the typical style using --fix or --fix-inplace.
>
> Commit 4e5c39e373fa ("vsock: Add support for SIOCINQ ioctl") has style problems, please review.
> ------------------------------------------------------------------------
> Commit 3eb323b2d9f4 ("test/vsock: Add retry mechanism to ioctl wrapper")
> ------------------------------------------------------------------------
> WARNING: From:/Signed-off-by: email address mismatch: 'From: Xuewei Niu <niuxuewei97@gmail.com>' != 'Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>'
>
> total: 0 errors, 1 warnings, 62 lines checked
>
> NOTE: For some of the reported defects, checkpatch may be able to
> mechanically convert to the typical style using --fix or --fix-inplace.
>
> Commit 3eb323b2d9f4 ("test/vsock: Add retry mechanism to ioctl wrapper") has style problems, please review.
>
> NOTE: If any of the errors are false positives, please report
> them to the maintainer, see CHECKPATCH in MAINTAINERS.
>
>> - Move the `need_refill` initialization into the `case 1` block.
>> - Remove the `actual` argument from `vsock_ioctl_int()`.
>> - Replace `TIOCINQ` with `SIOCINQ`.
>>
>> ---
>> Xuewei Niu (4):
>> hv_sock: Return the readable bytes in hvs_stream_has_data()
>> vsock: Add support for SIOCINQ ioctl
>> test/vsock: Add retry mechanism to ioctl wrapper
>> test/vsock: Add ioctl SIOCINQ tests
>>
>> net/vmw_vsock/af_vsock.c | 22 +++++++++++
>> net/vmw_vsock/hyperv_transport.c | 17 +++++++--
>> tools/testing/vsock/util.c | 30 ++++++++++-----
>> tools/testing/vsock/util.h | 1 +
>> tools/testing/vsock/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
>> 5 files changed, 137 insertions(+), 12 deletions(-)
>> ---
>> base-commit: 5f712c3877f99d5b5e4d011955c6467ae0e535a6
>> change-id: 20250703-siocinq-9e2907939806
>>
>> Best regards,
>> --
>> Xuewei Niu <niuxuewei.nxw@antgroup.com>
>>
^ permalink raw reply
* [PATCH] PCI/MSI: Initialize the prepare descriptor by default
From: Naman Jain @ 2025-07-08 5:18 UTC (permalink / raw)
To: Bjorn Helgaas, Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Shivamurthy Shastri, Shradha Gupta
Cc: Naman Jain, linux-pci, linux-kernel, linux-hyperv, Roman Kisel
Plug the default MSI-X prepare descriptor for non-implemented ops by
default to workaround the inability of Hyper-V vPCI module to setup
the MSI-X descriptors properly; especially for dynamically allocated
MSI-X.
Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
---
drivers/pci/msi/irqdomain.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
index 765312c92d9b..655e99b9c8cc 100644
--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -84,6 +84,8 @@ static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info)
} else {
if (ops->set_desc == NULL)
ops->set_desc = pci_msi_domain_set_desc;
+ if (ops->prepare_desc == NULL)
+ ops->prepare_desc = pci_msix_prepare_desc;
}
}
base-commit: 26ffb3d6f02cd0935fb9fa3db897767beee1cb2a
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox