From: Emerson Busson <emersonbusson@gmail.com>
To: mhklinux@outlook.com
Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
decui@microsoft.com, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
linux-hyperv@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH v2 09/14] hv: use owned VMBus buffers in NetVSC and UIO
Date: Wed, 7 Oct 2026 16:07:47 -0300 [thread overview]
Message-ID: <20261007190752.336426-10-emersonbusson@gmail.com> (raw)
In-Reply-To: <20261007190752.336426-1-emersonbusson@gmail.com>
Move the remaining buffer consumers to the allocation, GPADL and release
entry points that carry one descriptor throughout their lifetime.
Preserve established exported signatures throughout the series. Ring
confidentiality comes from co_ring_buffer; external-buffer compatibility
uses co_external_memory, while UIO buffers explicitly require
host-visible backing.
Signed-off-by: Emerson Busson <emersonbusson@gmail.com>
---
drivers/hv/channel.c | 4 +--
drivers/net/hyperv/netvsc.c | 52 +++++++++++-------------------------
drivers/uio/uio_hv_generic.c | 32 +++++++---------------
include/linux/hyperv.h | 8 +++---
4 files changed, 32 insertions(+), 64 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index aa33a0f08a7f..7eb9ea814ef4 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -1035,11 +1035,10 @@ EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
* @channel: a channel
* @kbuffer: from kmalloc or vmalloc; must already be decrypted by the caller
* @size: page-size multiple
- * @leak: set when a GPADL message may have reached the host but completion is
- * uncertain; the caller must retain the backing pages
* @gpadl: output gpadl
*
* The caller is responsible for re-encrypting the buffer before freeing it.
+ * Ownership of the backing pages stays with the caller's vmbus_buffer.
*/
int vmbus_establish_gpadl_caller_decrypted(struct vmbus_channel *channel,
void *kbuffer, u32 size,
@@ -1282,6 +1281,7 @@ int vmbus_alloc_buffer_owned(struct vmbus_channel *channel, u32 size,
return -ENOMEM;
}
EXPORT_SYMBOL_GPL(vmbus_alloc_buffer_owned);
+
/*
* vmbus_alloc_buffer - compatibility allocator for callers managing lifetime.
* New callers that need retained GPADL and mmap ownership should use
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index ffba1443396a..fd8aa7a3dcb3 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -243,7 +243,6 @@ static void netvsc_revoke_recv_buf(struct hv_device *device,
if (ret != 0) {
netdev_err(ndev, "unable to send "
"revoke receive buffer to netvsp\n");
- net_device->recv_buffer.leak = true;
return;
}
net_device->recv_section_cnt = 0;
@@ -295,7 +294,6 @@ static void netvsc_revoke_send_buf(struct hv_device *device,
if (ret != 0) {
netdev_err(ndev, "unable to send "
"revoke send buffer to netvsp\n");
- net_device->send_buffer.leak = true;
return;
}
net_device->send_section_cnt = 0;
@@ -308,18 +306,14 @@ static void netvsc_teardown_recv_gpadl(struct hv_device *device,
{
int ret;
- if (net_device->recv_buffer.leak)
- return;
-
if (net_device->recv_buffer.gpadl.gpadl_handle) {
- ret = vmbus_teardown_gpadl(device->channel,
- &net_device->recv_buffer.gpadl);
+ ret = vmbus_teardown_gpadl_owned(device->channel,
+ &net_device->recv_buffer);
/* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
*/
if (ret != 0) {
- net_device->recv_buffer.leak = true;
netdev_err(ndev,
"unable to teardown receive buffer's gpadl\n");
return;
@@ -333,18 +327,14 @@ static void netvsc_teardown_send_gpadl(struct hv_device *device,
{
int ret;
- if (net_device->send_buffer.leak)
- return;
-
if (net_device->send_buffer.gpadl.gpadl_handle) {
- ret = vmbus_teardown_gpadl(device->channel,
- &net_device->send_buffer.gpadl);
+ ret = vmbus_teardown_gpadl_owned(device->channel,
+ &net_device->send_buffer);
/* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
*/
if (ret != 0) {
- net_device->send_buffer.leak = true;
netdev_err(ndev,
"unable to teardown send buffer's gpadl\n");
return;
@@ -385,15 +375,13 @@ static int netvsc_init_buf(struct hv_device *device,
buf_size = min_t(unsigned int, buf_size,
NETVSC_RECEIVE_BUFFER_SIZE_LEGACY);
- net_device->recv_buffer.addr =
- vmbus_alloc_buffer(device->channel, buf_size,
- &net_device->recv_buffer.chunks,
- &net_device->recv_buffer.chunk_cnt);
- if (!net_device->recv_buffer.addr) {
+ ret = vmbus_alloc_buffer_owned(device->channel, buf_size,
+ device->channel->co_external_memory,
+ &net_device->recv_buffer);
+ if (ret) {
netdev_err(ndev,
"unable to allocate receive buffer of size %u\n",
buf_size);
- ret = -ENOMEM;
goto cleanup;
}
@@ -404,11 +392,8 @@ static int netvsc_init_buf(struct hv_device *device,
* channel. Note: This call uses the vmbus connection rather
* than the channel to establish the gpadl handle.
*/
- ret = vmbus_establish_gpadl_caller_decrypted(device->channel,
- net_device->recv_buffer.addr,
- buf_size,
- &net_device->recv_buffer.gpadl);
- net_device->recv_buffer.leak |= net_device->recv_buffer.gpadl.leak;
+ ret = vmbus_establish_gpadl_owned(device->channel,
+ &net_device->recv_buffer);
if (ret != 0) {
netdev_err(ndev,
"unable to establish receive buffer's gpadl\n");
@@ -496,14 +481,12 @@ static int netvsc_init_buf(struct hv_device *device,
buf_size = device_info->send_sections * device_info->send_section_size;
buf_size = round_up(buf_size, PAGE_SIZE);
- net_device->send_buffer.addr =
- vmbus_alloc_buffer(device->channel, buf_size,
- &net_device->send_buffer.chunks,
- &net_device->send_buffer.chunk_cnt);
- if (!net_device->send_buffer.addr) {
+ ret = vmbus_alloc_buffer_owned(device->channel, buf_size,
+ device->channel->co_external_memory,
+ &net_device->send_buffer);
+ if (ret) {
netdev_err(ndev, "unable to allocate send buffer of size %u\n",
buf_size);
- ret = -ENOMEM;
goto cleanup;
}
net_device->send_buf_size = buf_size;
@@ -512,11 +495,8 @@ static int netvsc_init_buf(struct hv_device *device,
* channel. Note: This call uses the vmbus connection rather
* than the channel to establish the gpadl handle.
*/
- ret = vmbus_establish_gpadl_caller_decrypted(device->channel,
- net_device->send_buffer.addr,
- buf_size,
- &net_device->send_buffer.gpadl);
- net_device->send_buffer.leak |= net_device->send_buffer.gpadl.leak;
+ ret = vmbus_establish_gpadl_owned(device->channel,
+ &net_device->send_buffer);
if (ret != 0) {
netdev_err(ndev,
"unable to establish send buffer's gpadl\n");
diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
index 2cb95b4786ca..b40e80e19c6c 100644
--- a/drivers/uio/uio_hv_generic.c
+++ b/drivers/uio/uio_hv_generic.c
@@ -196,11 +196,11 @@ static void
hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata)
{
if (pdata->send_buffer.gpadl.gpadl_handle)
- vmbus_teardown_gpadl(dev->channel, &pdata->send_buffer.gpadl);
+ vmbus_teardown_gpadl_owned(dev->channel, &pdata->send_buffer);
vmbus_release_buffer(&pdata->send_buffer);
if (pdata->recv_buffer.gpadl.gpadl_handle)
- vmbus_teardown_gpadl(dev->channel, &pdata->recv_buffer.gpadl);
+ vmbus_teardown_gpadl_owned(dev->channel, &pdata->recv_buffer);
vmbus_release_buffer(&pdata->recv_buffer);
}
@@ -298,18 +298,12 @@ hv_uio_probe(struct hv_device *dev,
pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
if (channel->device_id == HV_NIC) {
- pdata->recv_buffer.addr =
- vzalloc(RECV_BUFFER_SIZE);
- if (!pdata->recv_buffer.addr) {
- ret = -ENOMEM;
+ ret = vmbus_alloc_buffer_owned(channel, RECV_BUFFER_SIZE, false,
+ &pdata->recv_buffer);
+ if (ret)
goto fail_free_ring;
- }
- ret = vmbus_establish_gpadl(channel,
- pdata->recv_buffer.addr,
- RECV_BUFFER_SIZE,
- &pdata->recv_buffer.gpadl);
- pdata->recv_buffer.leak |= pdata->recv_buffer.gpadl.leak;
+ ret = vmbus_establish_gpadl_owned(channel, &pdata->recv_buffer);
if (ret)
goto fail_close;
@@ -322,18 +316,12 @@ hv_uio_probe(struct hv_device *dev,
pdata->info.mem[RECV_BUF_MAP].size = RECV_BUFFER_SIZE;
pdata->info.mem[RECV_BUF_MAP].memtype = UIO_MEM_VIRTUAL;
- pdata->send_buffer.addr =
- vzalloc(SEND_BUFFER_SIZE);
- if (!pdata->send_buffer.addr) {
- ret = -ENOMEM;
+ ret = vmbus_alloc_buffer_owned(channel, SEND_BUFFER_SIZE, false,
+ &pdata->send_buffer);
+ if (ret)
goto fail_close;
- }
- ret = vmbus_establish_gpadl(channel,
- pdata->send_buffer.addr,
- SEND_BUFFER_SIZE,
- &pdata->send_buffer.gpadl);
- pdata->send_buffer.leak |= pdata->send_buffer.gpadl.leak;
+ ret = vmbus_establish_gpadl_owned(channel, &pdata->send_buffer);
if (ret)
goto fail_close;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 90bdbacee054..0f482ed5c776 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1216,9 +1216,9 @@ extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
u64 requestid);
extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
- void *kbuffer,
- u32 size,
- struct vmbus_gpadl *gpadl);
+ void *kbuffer,
+ u32 size,
+ struct vmbus_gpadl *gpadl);
extern int vmbus_establish_gpadl_caller_decrypted(struct vmbus_channel *channel,
void *kbuffer,
@@ -1226,7 +1226,7 @@ extern int vmbus_establish_gpadl_caller_decrypted(struct vmbus_channel *channel,
struct vmbus_gpadl *gpadl);
extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
- struct vmbus_gpadl *gpadl);
+ struct vmbus_gpadl *gpadl);
extern void *vmbus_alloc_buffer(struct vmbus_channel *channel,
u32 size,
--
2.43.0
next prev parent reply other threads:[~2026-10-07 19:08 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 19:07 [PATCH v2 0/14] hv: vmbus: make rings and host-visible buffers survive buddy fragmentation Emerson Busson
2026-10-07 19:07 ` [PATCH v2 01/14] hv: vmbus: convert ring backing through the chunk allocator Emerson Busson
2026-10-07 19:07 ` [PATCH v2 02/14] hv: vmbus: validate chunk buffer allocation and cleanup Emerson Busson
2026-10-08 21:17 ` kernel test robot
2026-10-07 19:07 ` [PATCH v2 03/14] uio: hv_generic: describe buffers for owned allocation Emerson Busson
2026-10-07 19:07 ` [PATCH v2 04/14] hv: vmbus: add KUnit tests for GPADL post failure injection Emerson Busson
2026-10-07 19:07 ` [PATCH v2 05/14] hv: vmbus: add KUnit test for order-zero allocation fallback Emerson Busson
2026-10-07 19:07 ` [PATCH v2 06/14] hv: vmbus: cover all shared-page policy combinations Emerson Busson
2026-10-07 19:07 ` [PATCH v2 07/14] hv: vmbus: distinguish host rescind from local channel unload Emerson Busson
2026-10-07 19:07 ` [PATCH v2 08/14] hv: vmbus: retain backing until ownership and references clear Emerson Busson
2026-10-07 19:07 ` Emerson Busson [this message]
2026-10-07 19:07 ` [PATCH v2 10/14] hv: vmbus: pin buffer pages across UIO mmap to close the reclaim race Emerson Busson
2026-10-08 16:49 ` kernel test robot
2026-10-08 17:51 ` Nathan Chancellor
2026-10-08 17:02 ` kernel test robot
2026-10-07 19:07 ` [PATCH v2 11/14] hv: vmbus: vmalloc requestor metadata Emerson Busson
2026-10-07 19:07 ` [PATCH v2 12/14] hv: netvsc: allocate RNDIS request descriptors with kvzalloc_obj() Emerson Busson
2026-10-07 19:07 ` [PATCH v2 13/14] hv: netvsc: handle a NULL request address on empty completions Emerson Busson
2026-10-07 19:07 ` [PATCH v2 14/14] hv: netvsc: use kvzalloc for device state Emerson Busson
2026-10-08 16:55 ` [PATCH v2 0/14] hv: vmbus: make rings and host-visible buffers survive buddy fragmentation Easwar Hariharan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007190752.336426-10-emersonbusson@gmail.com \
--to=emersonbusson@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=decui@microsoft.com \
--cc=edumazet@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=haiyangz@microsoft.com \
--cc=kuba@kernel.org \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhklinux@outlook.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=wei.liu@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®