linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Drivers: hv: vmbus: Miscellaneous adjustments
@ 2016-07-01 23:25 kys
  2016-07-01 23:26 ` [PATCH 1/3] Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels kys
  0 siblings, 1 reply; 4+ messages in thread
From: kys @ 2016-07-01 23:25 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
	leann.ogasawara
  Cc: K. Y. Srinivasan

From: K. Y. Srinivasan <kys@microsoft.com>

Some miscellaneous adjustments to the vmbus driver.

K. Y. Srinivasan (3):
  Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels
  Drivers: hv: vmbus: Reduce the delay between retries in
    vmbus_post_msg()
  Drivers: hv: vmbus: Implement a mechanism to tag the channel for low
    latency

 drivers/hv/channel.c      |   25 ++++++++++---------------
 drivers/hv/channel_mgmt.c |    2 ++
 drivers/hv/connection.c   |    8 ++++----
 drivers/hv/hyperv_vmbus.h |    3 ++-
 drivers/hv/ring_buffer.c  |   15 ++++++++++++---
 include/linux/hyperv.h    |   35 +++++++++++++++++++++++++++++++++++
 6 files changed, 65 insertions(+), 23 deletions(-)

-- 
1.7.4.1

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

* [PATCH 1/3] Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels
  2016-07-01 23:25 [PATCH 0/3] Drivers: hv: vmbus: Miscellaneous adjustments kys
@ 2016-07-01 23:26 ` kys
  2016-07-01 23:26   ` [PATCH 2/3] Drivers: hv: vmbus: Reduce the delay between retries in vmbus_post_msg() kys
  2016-07-01 23:26   ` [PATCH 3/3] Drivers: hv: vmbus: Implement a mechanism to tag the channel for low latency kys
  0 siblings, 2 replies; 4+ messages in thread
From: kys @ 2016-07-01 23:26 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
	leann.ogasawara
  Cc: K. Y. Srinivasan

From: K. Y. Srinivasan <kys@microsoft.com>

For synthetic NIC channels, enable explicit signaling policy as netvsc wants to
explicitly control when the host is to be signaled.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 drivers/hv/channel.c      |   18 ++++--------------
 drivers/hv/channel_mgmt.c |    2 ++
 drivers/hv/hyperv_vmbus.h |    3 ++-
 drivers/hv/ring_buffer.c  |   15 ++++++++++++---
 4 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index a68830c..da022d3 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -657,7 +657,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
 	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs,
-				  &signal, lock);
+				  &signal, lock, channel->signal_policy);
 
 	/*
 	 * Signalling the host is conditional on many factors:
@@ -678,11 +678,6 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
 	 * mechanism which can hurt the performance otherwise.
 	 */
 
-	if (channel->signal_policy)
-		signal = true;
-	else
-		kick_q = true;
-
 	if (((ret == 0) && kick_q && signal) ||
 	    (ret && !is_hvsock_channel(channel)))
 		vmbus_setevent(channel);
@@ -775,7 +770,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
 	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
-				  &signal, lock);
+				  &signal, lock, channel->signal_policy);
 
 	/*
 	 * Signalling the host is conditional on many factors:
@@ -793,11 +788,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
 	 * enough condition that it should not matter.
 	 */
 
-	if (channel->signal_policy)
-		signal = true;
-	else
-		kick_q = true;
-
 	if (((ret == 0) && kick_q && signal) || (ret))
 		vmbus_setevent(channel);
 
@@ -859,7 +849,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
 	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
-				  &signal, lock);
+				  &signal, lock, channel->signal_policy);
 
 	if (ret == 0 && signal)
 		vmbus_setevent(channel);
@@ -924,7 +914,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
 	bufferlist[2].iov_len = (packetlen_aligned - packetlen);
 
 	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
-				  &signal, lock);
+				  &signal, lock, channel->signal_policy);
 
 	if (ret == 0 && signal)
 		vmbus_setevent(channel);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index b6c1211..8345869 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -406,6 +406,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 	}
 
 	dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type);
+	if (dev_type == HV_NIC)
+		set_channel_signal_state(newchannel, HV_SIGNAL_POLICY_EXPLICIT);
 
 	init_vp_index(newchannel, dev_type);
 
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index dfa9fac..ddcc348 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -529,7 +529,8 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
 
 int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
 		    struct kvec *kv_list,
-		    u32 kv_count, bool *signal, bool lock);
+		    u32 kv_count, bool *signal, bool lock,
+		    enum hv_signal_policy policy);
 
 int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
 		       void *buffer, u32 buflen, u32 *buffer_actual_len,
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index fe586bf..e3edcae 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -66,12 +66,20 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)
  *	   arrived.
  */
 
-static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
+static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi,
+			      enum hv_signal_policy policy)
 {
 	virt_mb();
 	if (READ_ONCE(rbi->ring_buffer->interrupt_mask))
 		return false;
 
+	/*
+	 * When the client wants to control signaling,
+	 * we only honour the host interrupt mask.
+	 */
+	if (policy == HV_SIGNAL_POLICY_EXPLICIT)
+		return true;
+
 	/* check interrupt_mask before read_index */
 	virt_rmb();
 	/*
@@ -264,7 +272,8 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
 
 /* Write to the ring buffer. */
 int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
-		    struct kvec *kv_list, u32 kv_count, bool *signal, bool lock)
+		    struct kvec *kv_list, u32 kv_count, bool *signal, bool lock,
+		    enum hv_signal_policy policy)
 {
 	int i = 0;
 	u32 bytes_avail_towrite;
@@ -326,7 +335,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
 	if (lock)
 		spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 
-	*signal = hv_need_to_signal(old_write, outring_info);
+	*signal = hv_need_to_signal(old_write, outring_info, policy);
 	return 0;
 }
 
-- 
1.7.4.1

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

* [PATCH 2/3] Drivers: hv: vmbus: Reduce the delay between retries in vmbus_post_msg()
  2016-07-01 23:26 ` [PATCH 1/3] Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels kys
@ 2016-07-01 23:26   ` kys
  2016-07-01 23:26   ` [PATCH 3/3] Drivers: hv: vmbus: Implement a mechanism to tag the channel for low latency kys
  1 sibling, 0 replies; 4+ messages in thread
From: kys @ 2016-07-01 23:26 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
	leann.ogasawara
  Cc: K. Y. Srinivasan

From: K. Y. Srinivasan <kys@microsoft.com>

The current delay between retries is unnecessarily high and is negatively
affecting the time it takes to boot the system.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 drivers/hv/connection.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index fcf8a02..78e6368 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -439,7 +439,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
 	union hv_connection_id conn_id;
 	int ret = 0;
 	int retries = 0;
-	u32 msec = 1;
+	u32 usec = 1;
 
 	conn_id.asu32 = 0;
 	conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
@@ -472,9 +472,9 @@ int vmbus_post_msg(void *buffer, size_t buflen)
 		}
 
 		retries++;
-		msleep(msec);
-		if (msec < 2048)
-			msec *= 2;
+		udelay(usec);
+		if (usec < 2048)
+			usec *= 2;
 	}
 	return ret;
 }
-- 
1.7.4.1

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

* [PATCH 3/3] Drivers: hv: vmbus: Implement a mechanism to tag the channel for low latency
  2016-07-01 23:26 ` [PATCH 1/3] Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels kys
  2016-07-01 23:26   ` [PATCH 2/3] Drivers: hv: vmbus: Reduce the delay between retries in vmbus_post_msg() kys
@ 2016-07-01 23:26   ` kys
  1 sibling, 0 replies; 4+ messages in thread
From: kys @ 2016-07-01 23:26 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
	leann.ogasawara
  Cc: K. Y. Srinivasan

From: K. Y. Srinivasan <kys@microsoft.com>

On Hyper-V, performance critical channels use the monitor
mechanism to signal the host when the guest posts mesages
for the host. This mechanism minimizes the hypervisor intercepts
and also makes the host more efficient in that each time the
host is woken up, it processes a batch of messages as opposed to
just one. The goal here is improve the throughput and this is at
the expense of increased latency.
Implement a mechanism to let the client driver decide if latency
is important.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 drivers/hv/channel.c   |    7 ++++++-
 include/linux/hyperv.h |   35 +++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index da022d3..e3a0048 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -43,7 +43,12 @@ static void vmbus_setevent(struct vmbus_channel *channel)
 {
 	struct hv_monitor_page *monitorpage;
 
-	if (channel->offermsg.monitor_allocated) {
+	/*
+	 * For channels marked as in "low latency" mode
+	 * bypass the monitor page mechanism.
+	 */
+	if ((channel->offermsg.monitor_allocated) &&
+	    (!channel->low_latency)) {
 		/* Each u32 represents 32 channels */
 		sync_set_bit(channel->offermsg.child_relid & 31,
 			(unsigned long *) vmbus_connection.send_int_page +
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index b10954a..362acf0 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -850,6 +850,31 @@ struct vmbus_channel {
 	 * ring lock to preserve the current behavior.
 	 */
 	bool acquire_ring_lock;
+	/*
+	 * For performance critical channels (storage, networking
+	 * etc,), Hyper-V has a mechanism to enhance the throughput
+	 * at the expense of latency:
+	 * When the host is to be signaled, we just set a bit in a shared page
+	 * and this bit will be inspected by the hypervisor within a certain
+	 * window and if the bit is set, the host will be signaled. The window
+	 * of time is the monitor latency - currently around 100 usecs. This
+	 * mechanism improves throughput by:
+	 *
+	 * A) Making the host more efficient - each time it wakes up,
+	 *    potentially it will process morev number of packets. The
+	 *    monitor latency allows a batch to build up.
+	 * B) By deferring the hypercall to signal, we will also minimize
+	 *    the interrupts.
+	 *
+	 * Clearly, these optimizations improve throughput at the expense of
+	 * latency. Furthermore, since the channel is shared for both
+	 * control and data messages, control messages currently suffer
+	 * unnecessary latency adversley impacting performance and boot
+	 * time. To fix this issue, permit tagging the channel as being
+	 * in "low latency" mode. In this mode, we will bypass the monitor
+	 * mechanism.
+	 */
+	bool low_latency;
 
 };
 
@@ -891,6 +916,16 @@ static inline void set_channel_pending_send_size(struct vmbus_channel *c,
 	c->outbound.ring_buffer->pending_send_sz = size;
 }
 
+static inline void set_low_latency_mode(struct vmbus_channel *c)
+{
+	c->low_latency = true;
+}
+
+static inline void clear_low_latency_mode(struct vmbus_channel *c)
+{
+	c->low_latency = false;
+}
+
 void vmbus_onmessage(void *context);
 
 int vmbus_request_offers(void);
-- 
1.7.4.1

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

end of thread, other threads:[~2016-07-01 21:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-01 23:25 [PATCH 0/3] Drivers: hv: vmbus: Miscellaneous adjustments kys
2016-07-01 23:26 ` [PATCH 1/3] Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels kys
2016-07-01 23:26   ` [PATCH 2/3] Drivers: hv: vmbus: Reduce the delay between retries in vmbus_post_msg() kys
2016-07-01 23:26   ` [PATCH 3/3] Drivers: hv: vmbus: Implement a mechanism to tag the channel for low latency kys

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).