diff options
author | Vitaly Kuznetsov <vkuznets@redhat.com> | 2016-09-02 15:58:20 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-09-02 18:22:51 +0300 |
commit | 9988ce685676cebe0b14dc128f00e1ae9cd1a4fa (patch) | |
tree | 5f7e2212bca74c839e686068b74ca3b3dec5d739 /drivers/hv/channel.c | |
parent | 98f531b10d23e3c28e8d34c0e88822a81231b3c2 (diff) | |
download | linux-9988ce685676cebe0b14dc128f00e1ae9cd1a4fa.tar.xz |
Drivers: hv: ring_buffer: wrap around mappings for ring buffers
Make it possible to always use a single memcpy() or to provide a direct
link to a packet on the ring buffer by creating virtual mapping for two
copies of the ring buffer with vmap(). Utilize currently empty
hv_ringbuffer_cleanup() to do the unmap.
While on it, replace sizeof(struct hv_ring_buffer) check
in hv_ringbuffer_init() with BUILD_BUG_ON() as it is a compile time check.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Tested-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/channel.c')
-rw-r--r-- | drivers/hv/channel.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 15e833004fc3..16f91c8490fe 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -75,7 +75,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, { struct vmbus_channel_open_channel *open_msg; struct vmbus_channel_msginfo *open_info = NULL; - void *in, *out; unsigned long flags; int ret, err = 0; struct page *page; @@ -112,23 +111,21 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto error_set_chnstate; } - out = page_address(page); - in = (void *)((unsigned long)out + send_ringbuffer_size); - - newchannel->ringbuffer_pages = out; + newchannel->ringbuffer_pages = page_address(page); newchannel->ringbuffer_pagecount = (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT; - ret = hv_ringbuffer_init( - &newchannel->outbound, out, send_ringbuffer_size); + ret = hv_ringbuffer_init(&newchannel->outbound, page, + send_ringbuffer_size >> PAGE_SHIFT); if (ret != 0) { err = ret; goto error_free_pages; } - ret = hv_ringbuffer_init( - &newchannel->inbound, in, recv_ringbuffer_size); + ret = hv_ringbuffer_init(&newchannel->inbound, + &page[send_ringbuffer_size >> PAGE_SHIFT], + recv_ringbuffer_size >> PAGE_SHIFT); if (ret != 0) { err = ret; goto error_free_pages; @@ -139,10 +136,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel->ringbuffer_gpadlhandle = 0; ret = vmbus_establish_gpadl(newchannel, - newchannel->outbound.ring_buffer, - send_ringbuffer_size + - recv_ringbuffer_size, - &newchannel->ringbuffer_gpadlhandle); + page_address(page), + send_ringbuffer_size + + recv_ringbuffer_size, + &newchannel->ringbuffer_gpadlhandle); if (ret != 0) { err = ret; @@ -214,8 +211,10 @@ error_free_gpadl: vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle); kfree(open_info); error_free_pages: - free_pages((unsigned long)out, - get_order(send_ringbuffer_size + recv_ringbuffer_size)); + hv_ringbuffer_cleanup(&newchannel->outbound); + hv_ringbuffer_cleanup(&newchannel->inbound); + __free_pages(page, + get_order(send_ringbuffer_size + recv_ringbuffer_size)); error_set_chnstate: newchannel->state = CHANNEL_OPEN_STATE; return err; |