linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible
@ 2016-06-10  9:47 Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 1/4] Drivers: hv: cleanup vmbus_open() for wrap around mappings Vitaly Kuznetsov
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Vitaly Kuznetsov @ 2016-06-10  9:47 UTC (permalink / raw)
  To: devel; +Cc: linux-kernel, K. Y. Srinivasan, Haiyang Zhang

K. Y.,

I'd like to accompany your netvsc performance improvement work by making
in-place consumption of VMBus packets always possible. Currently we forbid
it when a packet 'wraps around' the ring so we can't provide a single
pointer to it.

The idea if this series is dead simple: let's make a single virtual mapping
for two copies (actually, two sets of pages which consist the ring buffer)
of the ring buffer. With such a mapping we can always provide a pointers
for in-place consumption to drivers. Copy path can also benefit from such
mappings as we eliminate the need for conditional checking in copy_to/
copy_from functions and use a single memcpy().

Lightly tested with 'netvsc: Use the new in-place consumption APIs in the
rx path' patch and with storvsc driver.

Vitaly Kuznetsov (4):
  Drivers: hv: cleanup vmbus_open() for wrap around mappings
  Drivers: hv: ring_buffer: wrap around mappings for ring buffers
  Drivers: hv: ring_buffer: use wrap around mappings in
    hv_copy{from,to}_ringbuffer()
  Drivers: hv: ring_buffer: count on wrap around mappings in
    get_next_pkt_raw()

 drivers/hv/channel.c      | 68 ++++++++++++++++++++++++-----------------------
 drivers/hv/hyperv_vmbus.h |  4 +--
 drivers/hv/ring_buffer.c  | 61 ++++++++++++++++++++++++------------------
 include/linux/hyperv.h    | 32 ++++++++--------------
 4 files changed, 83 insertions(+), 82 deletions(-)

-- 
2.5.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] Drivers: hv: cleanup vmbus_open() for wrap around mappings
  2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
@ 2016-06-10  9:47 ` Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 2/4] Drivers: hv: ring_buffer: wrap around mappings for ring buffers Vitaly Kuznetsov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vitaly Kuznetsov @ 2016-06-10  9:47 UTC (permalink / raw)
  To: devel; +Cc: linux-kernel, K. Y. Srinivasan, Haiyang Zhang

In preparation for doing wrap around mappings for ring buffers cleanup
vmbus_open() function:
- check that ring sizes are PAGE_SIZE aligned (they are for all in-kernel
  drivers now);
- kfree(open_info) on error only after we kzalloc() it (not an issue as it
  is valid to call kfree(NULL);
- rename poorly named labels;
- use alloc_pages() instead of __get_free_pages() as we need struct page
  pointer for future.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 drivers/hv/channel.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 56dd261..a5a3734 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -76,6 +76,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 	unsigned long t;
 	struct page *page;
 
+	if (send_ringbuffer_size % PAGE_SIZE ||
+	    recv_ringbuffer_size % PAGE_SIZE)
+		return -EINVAL;
+
 	spin_lock_irqsave(&newchannel->lock, flags);
 	if (newchannel->state == CHANNEL_OPEN_STATE) {
 		newchannel->state = CHANNEL_OPENING_STATE;
@@ -95,17 +99,16 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 				recv_ringbuffer_size));
 
 	if (!page)
-		out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
-					       get_order(send_ringbuffer_size +
-					       recv_ringbuffer_size));
-	else
-		out = (void *)page_address(page);
+		page = alloc_pages(GFP_KERNEL|__GFP_ZERO,
+				   get_order(send_ringbuffer_size +
+					     recv_ringbuffer_size));
 
-	if (!out) {
+	if (!page) {
 		err = -ENOMEM;
-		goto error0;
+		goto error_set_chnstate;
 	}
 
+	out = page_address(page);
 	in = (void *)((unsigned long)out + send_ringbuffer_size);
 
 	newchannel->ringbuffer_pages = out;
@@ -117,14 +120,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 
 	if (ret != 0) {
 		err = ret;
-		goto error0;
+		goto error_free_pages;
 	}
 
 	ret = hv_ringbuffer_init(
 		&newchannel->inbound, in, recv_ringbuffer_size);
 	if (ret != 0) {
 		err = ret;
-		goto error0;
+		goto error_free_pages;
 	}
 
 
@@ -139,7 +142,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 
 	if (ret != 0) {
 		err = ret;
-		goto error0;
+		goto error_free_pages;
 	}
 
 	/* Create and init the channel open message */
@@ -148,7 +151,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 			   GFP_KERNEL);
 	if (!open_info) {
 		err = -ENOMEM;
-		goto error_gpadl;
+		goto error_free_gpadl;
 	}
 
 	init_completion(&open_info->waitevent);
@@ -164,7 +167,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 
 	if (userdatalen > MAX_USER_DEFINED_BYTES) {
 		err = -EINVAL;
-		goto error_gpadl;
+		goto error_free_gpadl;
 	}
 
 	if (userdatalen)
@@ -180,13 +183,13 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 
 	if (ret != 0) {
 		err = ret;
-		goto error1;
+		goto error_clean_msglist;
 	}
 
 	t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
 	if (t == 0) {
 		err = -ETIMEDOUT;
-		goto error1;
+		goto error_clean_msglist;
 	}
 
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
@@ -195,25 +198,25 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
 
 	if (open_info->response.open_result.status) {
 		err = -EAGAIN;
-		goto error_gpadl;
+		goto error_free_gpadl;
 	}
 
 	newchannel->state = CHANNEL_OPENED_STATE;
 	kfree(open_info);
 	return 0;
 
-error1:
+error_clean_msglist:
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
 	list_del(&open_info->msglistentry);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
-error_gpadl:
+error_free_gpadl:
 	vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
-
-error0:
+	kfree(open_info);
+error_free_pages:
 	free_pages((unsigned long)out,
 		get_order(send_ringbuffer_size + recv_ringbuffer_size));
-	kfree(open_info);
+error_set_chnstate:
 	newchannel->state = CHANNEL_OPEN_STATE;
 	return err;
 }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] Drivers: hv: ring_buffer: wrap around mappings for ring buffers
  2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 1/4] Drivers: hv: cleanup vmbus_open() for wrap around mappings Vitaly Kuznetsov
@ 2016-06-10  9:47 ` Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 3/4] Drivers: hv: ring_buffer: use wrap around mappings in hv_copy{from,to}_ringbuffer() Vitaly Kuznetsov
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vitaly Kuznetsov @ 2016-06-10  9:47 UTC (permalink / raw)
  To: devel; +Cc: linux-kernel, K. Y. Srinivasan, Haiyang Zhang

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>
---
 drivers/hv/channel.c      | 29 ++++++++++++++---------------
 drivers/hv/hyperv_vmbus.h |  4 ++--
 drivers/hv/ring_buffer.c  | 39 +++++++++++++++++++++++++++++++++------
 3 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index a5a3734..a990a3f 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -70,7 +70,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;
 	unsigned long t;
@@ -108,23 +107,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;
@@ -135,10 +132,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;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 718b5c7..daaeb69 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -522,8 +522,8 @@ extern unsigned int host_info_edx;
 /* Interface */
 
 
-int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
-		   u32 buflen);
+int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
+		       struct page *pages, u32 pagecnt);
 
 void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
 
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index fe586bf..a84c45a 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -27,6 +27,8 @@
 #include <linux/mm.h>
 #include <linux/hyperv.h>
 #include <linux/uio.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "hyperv_vmbus.h"
 
@@ -235,22 +237,46 @@ void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 
 /* Initialize the ring buffer. */
 int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
-		   void *buffer, u32 buflen)
+		       struct page *pages, u32 page_cnt)
 {
-	if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
-		return -EINVAL;
+	int i;
+	struct page **pages_wraparound;
+
+	BUILD_BUG_ON((sizeof(struct hv_ring_buffer) != PAGE_SIZE));
 
 	memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
 
-	ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
+	/*
+	 * First page holds struct hv_ring_buffer, do wraparound mapping for
+	 * the rest.
+	 */
+	pages_wraparound = kzalloc(sizeof(struct page *) * (page_cnt * 2 - 1),
+				   GFP_KERNEL);
+	if (!pages_wraparound)
+		return -ENOMEM;
+
+	pages_wraparound[0] = pages;
+	for (i = 0; i < 2 * (page_cnt - 1); i++)
+		pages_wraparound[i + 1] = &pages[i % (page_cnt - 1) + 1];
+
+	ring_info->ring_buffer = (struct hv_ring_buffer *)
+		vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, PAGE_KERNEL);
+
+	kfree(pages_wraparound);
+
+
+	if (!ring_info->ring_buffer)
+		return -ENOMEM;
+
 	ring_info->ring_buffer->read_index =
 		ring_info->ring_buffer->write_index = 0;
 
 	/* Set the feature bit for enabling flow control. */
 	ring_info->ring_buffer->feature_bits.value = 1;
 
-	ring_info->ring_size = buflen;
-	ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
+	ring_info->ring_size = page_cnt << PAGE_SHIFT;
+	ring_info->ring_datasize = ring_info->ring_size -
+		sizeof(struct hv_ring_buffer);
 
 	spin_lock_init(&ring_info->ring_lock);
 
@@ -260,6 +286,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 /* Cleanup the ring buffer. */
 void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
 {
+	vunmap(ring_info->ring_buffer);
 }
 
 /* Write to the ring buffer. */
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] Drivers: hv: ring_buffer: use wrap around mappings in hv_copy{from,to}_ringbuffer()
  2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 1/4] Drivers: hv: cleanup vmbus_open() for wrap around mappings Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 2/4] Drivers: hv: ring_buffer: wrap around mappings for ring buffers Vitaly Kuznetsov
@ 2016-06-10  9:47 ` Vitaly Kuznetsov
  2016-06-10  9:47 ` [PATCH 4/4] Drivers: hv: ring_buffer: count on wrap around mappings in get_next_pkt_raw() Vitaly Kuznetsov
  2016-06-10 13:30 ` [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible KY Srinivasan
  4 siblings, 0 replies; 6+ messages in thread
From: Vitaly Kuznetsov @ 2016-06-10  9:47 UTC (permalink / raw)
  To: devel; +Cc: linux-kernel, K. Y. Srinivasan, Haiyang Zhang

With wrap around mappings for ring buffers we can always use a single
memcpy() to do the job.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 drivers/hv/ring_buffer.c | 24 +++---------------------
 1 file changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index a84c45a..53e912a 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -164,18 +164,7 @@ static u32 hv_copyfrom_ringbuffer(
 	void *ring_buffer = hv_get_ring_buffer(ring_info);
 	u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
 
-	u32 frag_len;
-
-	/* wrap-around detected at the src */
-	if (destlen > ring_buffer_size - start_read_offset) {
-		frag_len = ring_buffer_size - start_read_offset;
-
-		memcpy(dest, ring_buffer + start_read_offset, frag_len);
-		memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
-	} else
-
-		memcpy(dest, ring_buffer + start_read_offset, destlen);
-
+	memcpy(dest, ring_buffer + start_read_offset, destlen);
 
 	start_read_offset += destlen;
 	start_read_offset %= ring_buffer_size;
@@ -196,15 +185,8 @@ static u32 hv_copyto_ringbuffer(
 {
 	void *ring_buffer = hv_get_ring_buffer(ring_info);
 	u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
-	u32 frag_len;
-
-	/* wrap-around detected! */
-	if (srclen > ring_buffer_size - start_write_offset) {
-		frag_len = ring_buffer_size - start_write_offset;
-		memcpy(ring_buffer + start_write_offset, src, frag_len);
-		memcpy(ring_buffer, src + frag_len, srclen - frag_len);
-	} else
-		memcpy(ring_buffer + start_write_offset, src, srclen);
+
+	memcpy(ring_buffer + start_write_offset, src, srclen);
 
 	start_write_offset += srclen;
 	start_write_offset %= ring_buffer_size;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] Drivers: hv: ring_buffer: count on wrap around mappings in get_next_pkt_raw()
  2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
                   ` (2 preceding siblings ...)
  2016-06-10  9:47 ` [PATCH 3/4] Drivers: hv: ring_buffer: use wrap around mappings in hv_copy{from,to}_ringbuffer() Vitaly Kuznetsov
@ 2016-06-10  9:47 ` Vitaly Kuznetsov
  2016-06-10 13:30 ` [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible KY Srinivasan
  4 siblings, 0 replies; 6+ messages in thread
From: Vitaly Kuznetsov @ 2016-06-10  9:47 UTC (permalink / raw)
  To: devel; +Cc: linux-kernel, K. Y. Srinivasan, Haiyang Zhang

With wrap around mappings in place we can always provide drivers with
direct links to packets on the ring buffer, even when they wrap around.
Do the required updates to get_next_pkt_raw()/put_pkt_raw()

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 include/linux/hyperv.h | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index b10954a..25d14df 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1431,31 +1431,23 @@ static inline struct vmpacket_descriptor *
 get_next_pkt_raw(struct vmbus_channel *channel)
 {
 	struct hv_ring_buffer_info *ring_info = &channel->inbound;
-	u32 read_loc = ring_info->priv_read_index;
+	u32 priv_read_loc = ring_info->priv_read_index;
 	void *ring_buffer = hv_get_ring_buffer(ring_info);
-	struct vmpacket_descriptor *cur_desc;
-	u32 packetlen;
 	u32 dsize = ring_info->ring_datasize;
-	u32 delta = read_loc - ring_info->ring_buffer->read_index;
+	/*
+	 * delta is the difference between what is available to read and
+	 * what was already consumed in place. We commit read index after
+	 * the whole batch is processed.
+	 */
+	u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ?
+		priv_read_loc - ring_info->ring_buffer->read_index :
+		(dsize - ring_info->ring_buffer->read_index) + priv_read_loc;
 	u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
 
 	if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
 		return NULL;
 
-	if ((read_loc + sizeof(*cur_desc)) > dsize)
-		return NULL;
-
-	cur_desc = ring_buffer + read_loc;
-	packetlen = cur_desc->len8 << 3;
-
-	/*
-	 * If the packet under consideration is wrapping around,
-	 * return failure.
-	 */
-	if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > (dsize - 1))
-		return NULL;
-
-	return cur_desc;
+	return ring_buffer + priv_read_loc;
 }
 
 /*
@@ -1467,16 +1459,14 @@ static inline void put_pkt_raw(struct vmbus_channel *channel,
 				struct vmpacket_descriptor *desc)
 {
 	struct hv_ring_buffer_info *ring_info = &channel->inbound;
-	u32 read_loc = ring_info->priv_read_index;
 	u32 packetlen = desc->len8 << 3;
 	u32 dsize = ring_info->ring_datasize;
 
-	if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > dsize)
-		BUG();
 	/*
 	 * Include the packet trailer.
 	 */
 	ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
+	ring_info->priv_read_index %= dsize;
 }
 
 /*
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible
  2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
                   ` (3 preceding siblings ...)
  2016-06-10  9:47 ` [PATCH 4/4] Drivers: hv: ring_buffer: count on wrap around mappings in get_next_pkt_raw() Vitaly Kuznetsov
@ 2016-06-10 13:30 ` KY Srinivasan
  4 siblings, 0 replies; 6+ messages in thread
From: KY Srinivasan @ 2016-06-10 13:30 UTC (permalink / raw)
  To: Vitaly Kuznetsov, devel; +Cc: linux-kernel, Haiyang Zhang



> -----Original Message-----
> From: Vitaly Kuznetsov [mailto:vkuznets@redhat.com]
> Sent: Friday, June 10, 2016 2:47 AM
> To: devel@linuxdriverproject.org
> Cc: linux-kernel@vger.kernel.org; KY Srinivasan <kys@microsoft.com>; Haiyang
> Zhang <haiyangz@microsoft.com>
> Subject: [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption
> always possible
> 
> K. Y.,
> 
> I'd like to accompany your netvsc performance improvement work by making
> in-place consumption of VMBus packets always possible. Currently we forbid
> it when a packet 'wraps around' the ring so we can't provide a single
> pointer to it.
> 
> The idea if this series is dead simple: let's make a single virtual mapping
> for two copies (actually, two sets of pages which consist the ring buffer)
> of the ring buffer. With such a mapping we can always provide a pointers
> for in-place consumption to drivers. Copy path can also benefit from such
> mappings as we eliminate the need for conditional checking in copy_to/
> copy_from functions and use a single memcpy().
> 
> Lightly tested with 'netvsc: Use the new in-place consumption APIs in the
> rx path' patch and with storvsc driver.

Thank you Vitaly. We will further test it.

K. Y
> 
> Vitaly Kuznetsov (4):
>   Drivers: hv: cleanup vmbus_open() for wrap around mappings
>   Drivers: hv: ring_buffer: wrap around mappings for ring buffers
>   Drivers: hv: ring_buffer: use wrap around mappings in
>     hv_copy{from,to}_ringbuffer()
>   Drivers: hv: ring_buffer: count on wrap around mappings in
>     get_next_pkt_raw()
> 
>  drivers/hv/channel.c      | 68 ++++++++++++++++++++++++-----------------------
>  drivers/hv/hyperv_vmbus.h |  4 +--
>  drivers/hv/ring_buffer.c  | 61 ++++++++++++++++++++++++------------------
>  include/linux/hyperv.h    | 32 ++++++++--------------
>  4 files changed, 83 insertions(+), 82 deletions(-)
> 
> --
> 2.5.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-06-10 13:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-10  9:47 [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible Vitaly Kuznetsov
2016-06-10  9:47 ` [PATCH 1/4] Drivers: hv: cleanup vmbus_open() for wrap around mappings Vitaly Kuznetsov
2016-06-10  9:47 ` [PATCH 2/4] Drivers: hv: ring_buffer: wrap around mappings for ring buffers Vitaly Kuznetsov
2016-06-10  9:47 ` [PATCH 3/4] Drivers: hv: ring_buffer: use wrap around mappings in hv_copy{from,to}_ringbuffer() Vitaly Kuznetsov
2016-06-10  9:47 ` [PATCH 4/4] Drivers: hv: ring_buffer: count on wrap around mappings in get_next_pkt_raw() Vitaly Kuznetsov
2016-06-10 13:30 ` [PATCH 0/4] Drivers: hv: ring_buffer: make in-place consumption always possible KY Srinivasan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).