mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 09:16:29 +00:00
kernel: Add patches to fix VMBus channel ID re-use
On some hv_sock workloads which quickly open/close many connections occasionally, channel IDs would get re-used while still having work pending. This can cause a kernel crash on a NULL pointer exception. The three patches added to the 4.9.x and 4.10.x kernels fixes these bugs. The patches are being prepared to be upstreamed, but for now we cherry-picked them from the developers tree. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
parent
eaef1ca8fb
commit
87c4092b26
@ -1,7 +1,7 @@
|
|||||||
From f8892ad868fdcd96ccf6edc93ed61d8a97af88e4 Mon Sep 17 00:00:00 2001
|
From f8892ad868fdcd96ccf6edc93ed61d8a97af88e4 Mon Sep 17 00:00:00 2001
|
||||||
From: Dexuan Cui <decui@microsoft.com>
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
Date: Thu, 21 Jul 2016 16:04:38 -0600
|
Date: Thu, 21 Jul 2016 16:04:38 -0600
|
||||||
Subject: [PATCH 1/3] hv_sock: introduce Hyper-V Sockets
|
Subject: [PATCH 1/6] hv_sock: introduce Hyper-V Sockets
|
||||||
|
|
||||||
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
|
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
|
||||||
mechanism between the host and the guest. It's somewhat like TCP over
|
mechanism between the host and the guest. It's somewhat like TCP over
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 268b402c42c140328224ff994d1d76053f3113f9 Mon Sep 17 00:00:00 2001
|
From 268b402c42c140328224ff994d1d76053f3113f9 Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sat, 28 Jan 2017 12:37:17 -0700
|
Date: Sat, 28 Jan 2017 12:37:17 -0700
|
||||||
Subject: [PATCH 2/3] Drivers: hv: vmbus: Use all supported IC versions to
|
Subject: [PATCH 2/6] Drivers: hv: vmbus: Use all supported IC versions to
|
||||||
negotiate
|
negotiate
|
||||||
|
|
||||||
Previously, we were assuming that each IC protocol version was tied to a
|
Previously, we were assuming that each IC protocol version was tied to a
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 1dc474194b72f224081c90311887317415f987dc Mon Sep 17 00:00:00 2001
|
From 1dc474194b72f224081c90311887317415f987dc Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sat, 28 Jan 2017 12:37:18 -0700
|
Date: Sat, 28 Jan 2017 12:37:18 -0700
|
||||||
Subject: [PATCH 3/3] Drivers: hv: Log the negotiated IC versions.
|
Subject: [PATCH 3/6] Drivers: hv: Log the negotiated IC versions.
|
||||||
|
|
||||||
Log the negotiated IC versions.
|
Log the negotiated IC versions.
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
From 686f341e764920ada0163bedf354924250ed32d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Sun, 26 Mar 2017 16:42:20 +0800
|
||||||
|
Subject: [PATCH 4/6] vmbus: fix missed ring events on boot
|
||||||
|
|
||||||
|
During initialization, the channel initialization code schedules the
|
||||||
|
tasklet to scan the VMBUS receive event page (i.e. simulates an
|
||||||
|
interrupt). The problem was that it invokes the tasklet on a different
|
||||||
|
CPU from where it normally runs and therefore if an event is present,
|
||||||
|
it will clear the bit but not find the associated channel.
|
||||||
|
|
||||||
|
This can lead to missed events, typically stuck tasks, during bootup
|
||||||
|
when sub channels are being initialized. Typically seen as stuck
|
||||||
|
boot with 8 or more CPU's.
|
||||||
|
|
||||||
|
This patch is not necessary for upstream (4.11 and later) since
|
||||||
|
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
|
||||||
|
This changed vmbus code to get rid of common tasklet which
|
||||||
|
caused the problem.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Fixes: 638fea33aee8 ("Drivers: hv: vmbus: fix the race when querying & updating the percpu list")
|
||||||
|
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit 5cf3a72a111cecc7da759542c56560ce509159d7)
|
||||||
|
---
|
||||||
|
drivers/hv/channel_mgmt.c | 13 +++++++++++--
|
||||||
|
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||||
|
index feca5d2e7b25..3fda63bf60ab 100644
|
||||||
|
--- a/drivers/hv/channel_mgmt.c
|
||||||
|
+++ b/drivers/hv/channel_mgmt.c
|
||||||
|
@@ -389,8 +389,17 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel)
|
||||||
|
tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||||
|
tasklet_enable(tasklet);
|
||||||
|
|
||||||
|
- /* In case there is any pending event */
|
||||||
|
- tasklet_schedule(tasklet);
|
||||||
|
+ /*
|
||||||
|
+ * In case there is any pending event schedule a rescan
|
||||||
|
+ * but must be on the correct CPU for the channel.
|
||||||
|
+ */
|
||||||
|
+ if (channel->target_cpu == get_cpu())
|
||||||
|
+ tasklet_schedule(tasklet);
|
||||||
|
+ else
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ (smp_call_func_t)tasklet_schedule,
|
||||||
|
+ tasklet, false);
|
||||||
|
+ put_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
@ -0,0 +1,59 @@
|
|||||||
|
From e3de49b1a6a80b33f792caf62cc33048dcbaed91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Wed, 29 Mar 2017 18:37:10 +0800
|
||||||
|
Subject: [PATCH 5/6] vmbus: remove "goto error_clean_msglist" in vmbus_open()
|
||||||
|
|
||||||
|
This is just a cleanup patch to simplify the code a little.
|
||||||
|
No semantic change.
|
||||||
|
|
||||||
|
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit 2c89f21cbdfd39299482cd6068094097a45f13b3)
|
||||||
|
---
|
||||||
|
drivers/hv/channel.c | 18 +++++++-----------
|
||||||
|
1 file changed, 7 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||||
|
index 1606e7f08f4b..1caed01954f6 100644
|
||||||
|
--- a/drivers/hv/channel.c
|
||||||
|
+++ b/drivers/hv/channel.c
|
||||||
|
@@ -184,17 +184,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
ret = vmbus_post_msg(open_msg,
|
||||||
|
sizeof(struct vmbus_channel_open_channel), true);
|
||||||
|
|
||||||
|
- if (ret != 0) {
|
||||||
|
- err = ret;
|
||||||
|
- goto error_clean_msglist;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- wait_for_completion(&open_info->waitevent);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ wait_for_completion(&open_info->waitevent);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
list_del(&open_info->msglistentry);
|
||||||
|
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ err = ret;
|
||||||
|
+ goto error_free_gpadl;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (newchannel->rescind) {
|
||||||
|
err = -ENODEV;
|
||||||
|
goto error_free_gpadl;
|
||||||
|
@@ -209,11 +210,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
kfree(open_info);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
-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_free_gpadl:
|
||||||
|
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||||
|
kfree(open_info);
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
@ -0,0 +1,177 @@
|
|||||||
|
From e609da809e493b72eb28c0ad215edea8ddf54fb5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Fri, 24 Mar 2017 20:53:18 +0800
|
||||||
|
Subject: [PATCH 6/6] vmbus: dynamically enqueue/dequeue the channel on
|
||||||
|
vmbus_open/close
|
||||||
|
|
||||||
|
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit bee4910daa4aed57ce60d2e2350e3cc120c383ca)
|
||||||
|
---
|
||||||
|
drivers/hv/channel.c | 16 ++++++++++---
|
||||||
|
drivers/hv/channel_mgmt.c | 58 ++++++++++++++++++++---------------------------
|
||||||
|
include/linux/hyperv.h | 3 +++
|
||||||
|
3 files changed, 40 insertions(+), 37 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||||
|
index 1caed01954f6..5bbcc964dbf7 100644
|
||||||
|
--- a/drivers/hv/channel.c
|
||||||
|
+++ b/drivers/hv/channel.c
|
||||||
|
@@ -181,6 +181,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
&vmbus_connection.chn_msg_list);
|
||||||
|
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
|
||||||
|
+ hv_event_tasklet_disable(newchannel);
|
||||||
|
+ hv_percpu_channel_enq(newchannel);
|
||||||
|
+ hv_event_tasklet_enable(newchannel);
|
||||||
|
+
|
||||||
|
ret = vmbus_post_msg(open_msg,
|
||||||
|
sizeof(struct vmbus_channel_open_channel), true);
|
||||||
|
|
||||||
|
@@ -193,23 +197,27 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
err = ret;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newchannel->rescind) {
|
||||||
|
err = -ENODEV;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open_info->response.open_result.status) {
|
||||||
|
err = -EAGAIN;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
newchannel->state = CHANNEL_OPENED_STATE;
|
||||||
|
kfree(open_info);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+error_deq_channel:
|
||||||
|
+ hv_event_tasklet_disable(newchannel);
|
||||||
|
+ hv_percpu_channel_deq(newchannel);
|
||||||
|
+ hv_event_tasklet_enable(newchannel);
|
||||||
|
error_free_gpadl:
|
||||||
|
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||||
|
kfree(open_info);
|
||||||
|
@@ -555,6 +563,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ hv_percpu_channel_deq(channel);
|
||||||
|
+
|
||||||
|
channel->state = CHANNEL_OPEN_STATE;
|
||||||
|
channel->sc_creation_callback = NULL;
|
||||||
|
/* Stop callback and cancel the timer asap */
|
||||||
|
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||||
|
index 3fda63bf60ab..e2fbfa290f1c 100644
|
||||||
|
--- a/drivers/hv/channel_mgmt.c
|
||||||
|
+++ b/drivers/hv/channel_mgmt.c
|
||||||
|
@@ -376,6 +376,30 @@ static void vmbus_release_relid(u32 relid)
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
|
||||||
|
+{
|
||||||
|
+ if (channel->target_cpu != get_cpu())
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ percpu_channel_enq,
|
||||||
|
+ channel, true);
|
||||||
|
+ else
|
||||||
|
+ percpu_channel_enq(channel);
|
||||||
|
+ put_cpu();
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
|
||||||
|
+{
|
||||||
|
+ if (channel->target_cpu != get_cpu())
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ percpu_channel_deq,
|
||||||
|
+ channel, true);
|
||||||
|
+ else
|
||||||
|
+ percpu_channel_deq(channel);
|
||||||
|
+ put_cpu();
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void hv_event_tasklet_disable(struct vmbus_channel *channel)
|
||||||
|
{
|
||||||
|
struct tasklet_struct *tasklet;
|
||||||
|
@@ -410,17 +434,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||||
|
BUG_ON(!channel->rescind);
|
||||||
|
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(channel);
|
||||||
|
- if (channel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(channel->target_cpu,
|
||||||
|
- percpu_channel_deq, channel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_deq(channel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(channel);
|
||||||
|
-
|
||||||
|
if (channel->primary_channel == NULL) {
|
||||||
|
list_del(&channel->listentry);
|
||||||
|
|
||||||
|
@@ -513,18 +526,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
|
|
||||||
|
init_vp_index(newchannel, dev_type);
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(newchannel);
|
||||||
|
- if (newchannel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(newchannel->target_cpu,
|
||||||
|
- percpu_channel_enq,
|
||||||
|
- newchannel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_enq(newchannel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(newchannel);
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* This state is used to indicate a successful open
|
||||||
|
* so that when we do close the channel normally, we
|
||||||
|
@@ -573,17 +574,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
|
list_del(&newchannel->listentry);
|
||||||
|
mutex_unlock(&vmbus_connection.channel_mutex);
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(newchannel);
|
||||||
|
- if (newchannel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(newchannel->target_cpu,
|
||||||
|
- percpu_channel_deq, newchannel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_deq(newchannel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(newchannel);
|
||||||
|
-
|
||||||
|
vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||||
|
|
||||||
|
err_free_chan:
|
||||||
|
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||||
|
index 41e5ed87f833..0792d16f4b3e 100644
|
||||||
|
--- a/include/linux/hyperv.h
|
||||||
|
+++ b/include/linux/hyperv.h
|
||||||
|
@@ -1467,6 +1467,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
|
||||||
|
void hv_event_tasklet_disable(struct vmbus_channel *channel);
|
||||||
|
void hv_event_tasklet_enable(struct vmbus_channel *channel);
|
||||||
|
|
||||||
|
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
|
||||||
|
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
|
||||||
|
+
|
||||||
|
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||||
|
|
||||||
|
void vmbus_setevent(struct vmbus_channel *channel);
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 687435d249d10985e1c6d6d6cc143e8004e8b976 Mon Sep 17 00:00:00 2001
|
From 687435d249d10985e1c6d6d6cc143e8004e8b976 Mon Sep 17 00:00:00 2001
|
||||||
From: Dexuan Cui <decui@microsoft.com>
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
Date: Sat, 23 Jul 2016 01:35:51 +0000
|
Date: Sat, 23 Jul 2016 01:35:51 +0000
|
||||||
Subject: [PATCH 1/7] hv_sock: introduce Hyper-V Sockets
|
Subject: [PATCH 01/10] hv_sock: introduce Hyper-V Sockets
|
||||||
|
|
||||||
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
|
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
|
||||||
mechanism between the host and the guest. It's somewhat like TCP over
|
mechanism between the host and the guest. It's somewhat like TCP over
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 554ba8b0c4d9aa719d239b2f97eb59075c6c33d9 Mon Sep 17 00:00:00 2001
|
From 554ba8b0c4d9aa719d239b2f97eb59075c6c33d9 Mon Sep 17 00:00:00 2001
|
||||||
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
|
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
|
||||||
Date: Mon, 23 May 2016 18:55:45 +0100
|
Date: Mon, 23 May 2016 18:55:45 +0100
|
||||||
Subject: [PATCH 2/7] vmbus: Don't spam the logs with unknown GUIDs
|
Subject: [PATCH 02/10] vmbus: Don't spam the logs with unknown GUIDs
|
||||||
|
|
||||||
With Hyper-V sockets device types are introduced on the fly. The pr_info()
|
With Hyper-V sockets device types are introduced on the fly. The pr_info()
|
||||||
then prints a message on every connection, which is way too verbose. Since
|
then prints a message on every connection, which is way too verbose. Since
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
From a9c848779876b7b98a6c588494cd20010894fbf1 Mon Sep 17 00:00:00 2001
|
From a9c848779876b7b98a6c588494cd20010894fbf1 Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sun, 6 Nov 2016 13:14:07 -0800
|
Date: Sun, 6 Nov 2016 13:14:07 -0800
|
||||||
Subject: [PATCH 3/7] Drivers: hv: utils: Fix the mapping between host version
|
Subject: [PATCH 03/10] Drivers: hv: utils: Fix the mapping between host
|
||||||
and protocol to use
|
version and protocol to use
|
||||||
|
|
||||||
We should intentionally declare the protocols to use for every known host
|
We should intentionally declare the protocols to use for every known host
|
||||||
and default to using the latest protocol if the host is unknown or new.
|
and default to using the latest protocol if the host is unknown or new.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From ccab2062a98a38bd5ff2d57e184229345ff057ff Mon Sep 17 00:00:00 2001
|
From ccab2062a98a38bd5ff2d57e184229345ff057ff Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sun, 6 Nov 2016 13:14:10 -0800
|
Date: Sun, 6 Nov 2016 13:14:10 -0800
|
||||||
Subject: [PATCH 4/7] Drivers: hv: vss: Improve log messages.
|
Subject: [PATCH 04/10] Drivers: hv: vss: Improve log messages.
|
||||||
|
|
||||||
Adding log messages to help troubleshoot error cases and transaction
|
Adding log messages to help troubleshoot error cases and transaction
|
||||||
handling.
|
handling.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From d303deabd611b45b7574015c06ad2d7408235e77 Mon Sep 17 00:00:00 2001
|
From d303deabd611b45b7574015c06ad2d7408235e77 Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sun, 6 Nov 2016 13:14:11 -0800
|
Date: Sun, 6 Nov 2016 13:14:11 -0800
|
||||||
Subject: [PATCH 5/7] Drivers: hv: vss: Operation timeouts should match host
|
Subject: [PATCH 05/10] Drivers: hv: vss: Operation timeouts should match host
|
||||||
expectation
|
expectation
|
||||||
|
|
||||||
Increase the timeout of backup operations. When system is under I/O load,
|
Increase the timeout of backup operations. When system is under I/O load,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From bd8b51edd59a3326bf6457fd939e5503ff3f8efb Mon Sep 17 00:00:00 2001
|
From bd8b51edd59a3326bf6457fd939e5503ff3f8efb Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sat, 28 Jan 2017 12:37:17 -0700
|
Date: Sat, 28 Jan 2017 12:37:17 -0700
|
||||||
Subject: [PATCH 6/7] Drivers: hv: vmbus: Use all supported IC versions to
|
Subject: [PATCH 06/10] Drivers: hv: vmbus: Use all supported IC versions to
|
||||||
negotiate
|
negotiate
|
||||||
|
|
||||||
Previously, we were assuming that each IC protocol version was tied to a
|
Previously, we were assuming that each IC protocol version was tied to a
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From d692ce39b600298e6c60481d46c284c3c1bf975f Mon Sep 17 00:00:00 2001
|
From d692ce39b600298e6c60481d46c284c3c1bf975f Mon Sep 17 00:00:00 2001
|
||||||
From: Alex Ng <alexng@messages.microsoft.com>
|
From: Alex Ng <alexng@messages.microsoft.com>
|
||||||
Date: Sat, 28 Jan 2017 12:37:18 -0700
|
Date: Sat, 28 Jan 2017 12:37:18 -0700
|
||||||
Subject: [PATCH 7/7] Drivers: hv: Log the negotiated IC versions.
|
Subject: [PATCH 07/10] Drivers: hv: Log the negotiated IC versions.
|
||||||
|
|
||||||
Log the negotiated IC versions.
|
Log the negotiated IC versions.
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
From c68a516460f877753f6617d81455f42911d4bf66 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Sun, 26 Mar 2017 16:42:20 +0800
|
||||||
|
Subject: [PATCH 08/10] vmbus: fix missed ring events on boot
|
||||||
|
|
||||||
|
During initialization, the channel initialization code schedules the
|
||||||
|
tasklet to scan the VMBUS receive event page (i.e. simulates an
|
||||||
|
interrupt). The problem was that it invokes the tasklet on a different
|
||||||
|
CPU from where it normally runs and therefore if an event is present,
|
||||||
|
it will clear the bit but not find the associated channel.
|
||||||
|
|
||||||
|
This can lead to missed events, typically stuck tasks, during bootup
|
||||||
|
when sub channels are being initialized. Typically seen as stuck
|
||||||
|
boot with 8 or more CPU's.
|
||||||
|
|
||||||
|
This patch is not necessary for upstream (4.11 and later) since
|
||||||
|
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
|
||||||
|
This changed vmbus code to get rid of common tasklet which
|
||||||
|
caused the problem.
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Fixes: 638fea33aee8 ("Drivers: hv: vmbus: fix the race when querying & updating the percpu list")
|
||||||
|
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit 5cf3a72a111cecc7da759542c56560ce509159d7)
|
||||||
|
---
|
||||||
|
drivers/hv/channel_mgmt.c | 13 +++++++++++--
|
||||||
|
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||||
|
index e7949b64bfbc..2fe024e86209 100644
|
||||||
|
--- a/drivers/hv/channel_mgmt.c
|
||||||
|
+++ b/drivers/hv/channel_mgmt.c
|
||||||
|
@@ -388,8 +388,17 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel)
|
||||||
|
tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||||
|
tasklet_enable(tasklet);
|
||||||
|
|
||||||
|
- /* In case there is any pending event */
|
||||||
|
- tasklet_schedule(tasklet);
|
||||||
|
+ /*
|
||||||
|
+ * In case there is any pending event schedule a rescan
|
||||||
|
+ * but must be on the correct CPU for the channel.
|
||||||
|
+ */
|
||||||
|
+ if (channel->target_cpu == get_cpu())
|
||||||
|
+ tasklet_schedule(tasklet);
|
||||||
|
+ else
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ (smp_call_func_t)tasklet_schedule,
|
||||||
|
+ tasklet, false);
|
||||||
|
+ put_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 55ddc3b37ec5d311e5fff71cacb224d5c87803f3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Wed, 29 Mar 2017 18:37:10 +0800
|
||||||
|
Subject: [PATCH 09/10] vmbus: remove "goto error_clean_msglist" in
|
||||||
|
vmbus_open()
|
||||||
|
|
||||||
|
This is just a cleanup patch to simplify the code a little.
|
||||||
|
No semantic change.
|
||||||
|
|
||||||
|
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit 2c89f21cbdfd39299482cd6068094097a45f13b3)
|
||||||
|
---
|
||||||
|
drivers/hv/channel.c | 18 +++++++-----------
|
||||||
|
1 file changed, 7 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||||
|
index 1606e7f08f4b..1caed01954f6 100644
|
||||||
|
--- a/drivers/hv/channel.c
|
||||||
|
+++ b/drivers/hv/channel.c
|
||||||
|
@@ -184,17 +184,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
ret = vmbus_post_msg(open_msg,
|
||||||
|
sizeof(struct vmbus_channel_open_channel), true);
|
||||||
|
|
||||||
|
- if (ret != 0) {
|
||||||
|
- err = ret;
|
||||||
|
- goto error_clean_msglist;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- wait_for_completion(&open_info->waitevent);
|
||||||
|
+ if (ret == 0)
|
||||||
|
+ wait_for_completion(&open_info->waitevent);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
list_del(&open_info->msglistentry);
|
||||||
|
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ err = ret;
|
||||||
|
+ goto error_free_gpadl;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (newchannel->rescind) {
|
||||||
|
err = -ENODEV;
|
||||||
|
goto error_free_gpadl;
|
||||||
|
@@ -209,11 +210,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
kfree(open_info);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
-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_free_gpadl:
|
||||||
|
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||||
|
kfree(open_info);
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
@ -0,0 +1,177 @@
|
|||||||
|
From 83ba0bff619dc73f2aa6385ed3e039bb7641550a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Date: Fri, 24 Mar 2017 20:53:18 +0800
|
||||||
|
Subject: [PATCH 10/10] vmbus: dynamically enqueue/dequeue the channel on
|
||||||
|
vmbus_open/close
|
||||||
|
|
||||||
|
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||||
|
Origin: git@github.com:dcui/linux.git
|
||||||
|
(cherry picked from commit bee4910daa4aed57ce60d2e2350e3cc120c383ca)
|
||||||
|
---
|
||||||
|
drivers/hv/channel.c | 16 ++++++++++---
|
||||||
|
drivers/hv/channel_mgmt.c | 58 ++++++++++++++++++++---------------------------
|
||||||
|
include/linux/hyperv.h | 3 +++
|
||||||
|
3 files changed, 40 insertions(+), 37 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||||
|
index 1caed01954f6..5bbcc964dbf7 100644
|
||||||
|
--- a/drivers/hv/channel.c
|
||||||
|
+++ b/drivers/hv/channel.c
|
||||||
|
@@ -181,6 +181,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
&vmbus_connection.chn_msg_list);
|
||||||
|
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||||
|
|
||||||
|
+ hv_event_tasklet_disable(newchannel);
|
||||||
|
+ hv_percpu_channel_enq(newchannel);
|
||||||
|
+ hv_event_tasklet_enable(newchannel);
|
||||||
|
+
|
||||||
|
ret = vmbus_post_msg(open_msg,
|
||||||
|
sizeof(struct vmbus_channel_open_channel), true);
|
||||||
|
|
||||||
|
@@ -193,23 +197,27 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
err = ret;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newchannel->rescind) {
|
||||||
|
err = -ENODEV;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open_info->response.open_result.status) {
|
||||||
|
err = -EAGAIN;
|
||||||
|
- goto error_free_gpadl;
|
||||||
|
+ goto error_deq_channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
newchannel->state = CHANNEL_OPENED_STATE;
|
||||||
|
kfree(open_info);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+error_deq_channel:
|
||||||
|
+ hv_event_tasklet_disable(newchannel);
|
||||||
|
+ hv_percpu_channel_deq(newchannel);
|
||||||
|
+ hv_event_tasklet_enable(newchannel);
|
||||||
|
error_free_gpadl:
|
||||||
|
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||||
|
kfree(open_info);
|
||||||
|
@@ -555,6 +563,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ hv_percpu_channel_deq(channel);
|
||||||
|
+
|
||||||
|
channel->state = CHANNEL_OPEN_STATE;
|
||||||
|
channel->sc_creation_callback = NULL;
|
||||||
|
/* Stop callback and cancel the timer asap */
|
||||||
|
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||||
|
index 2fe024e86209..b2bdcfb49144 100644
|
||||||
|
--- a/drivers/hv/channel_mgmt.c
|
||||||
|
+++ b/drivers/hv/channel_mgmt.c
|
||||||
|
@@ -375,6 +375,30 @@ static void vmbus_release_relid(u32 relid)
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
|
||||||
|
+{
|
||||||
|
+ if (channel->target_cpu != get_cpu())
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ percpu_channel_enq,
|
||||||
|
+ channel, true);
|
||||||
|
+ else
|
||||||
|
+ percpu_channel_enq(channel);
|
||||||
|
+ put_cpu();
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
|
||||||
|
+{
|
||||||
|
+ if (channel->target_cpu != get_cpu())
|
||||||
|
+ smp_call_function_single(channel->target_cpu,
|
||||||
|
+ percpu_channel_deq,
|
||||||
|
+ channel, true);
|
||||||
|
+ else
|
||||||
|
+ percpu_channel_deq(channel);
|
||||||
|
+ put_cpu();
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void hv_event_tasklet_disable(struct vmbus_channel *channel)
|
||||||
|
{
|
||||||
|
struct tasklet_struct *tasklet;
|
||||||
|
@@ -409,17 +433,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||||
|
BUG_ON(!channel->rescind);
|
||||||
|
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(channel);
|
||||||
|
- if (channel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(channel->target_cpu,
|
||||||
|
- percpu_channel_deq, channel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_deq(channel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(channel);
|
||||||
|
-
|
||||||
|
if (channel->primary_channel == NULL) {
|
||||||
|
list_del(&channel->listentry);
|
||||||
|
|
||||||
|
@@ -512,18 +525,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
|
|
||||||
|
init_vp_index(newchannel, dev_type);
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(newchannel);
|
||||||
|
- if (newchannel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(newchannel->target_cpu,
|
||||||
|
- percpu_channel_enq,
|
||||||
|
- newchannel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_enq(newchannel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(newchannel);
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* This state is used to indicate a successful open
|
||||||
|
* so that when we do close the channel normally, we
|
||||||
|
@@ -572,17 +573,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
|
list_del(&newchannel->listentry);
|
||||||
|
mutex_unlock(&vmbus_connection.channel_mutex);
|
||||||
|
|
||||||
|
- hv_event_tasklet_disable(newchannel);
|
||||||
|
- if (newchannel->target_cpu != get_cpu()) {
|
||||||
|
- put_cpu();
|
||||||
|
- smp_call_function_single(newchannel->target_cpu,
|
||||||
|
- percpu_channel_deq, newchannel, true);
|
||||||
|
- } else {
|
||||||
|
- percpu_channel_deq(newchannel);
|
||||||
|
- put_cpu();
|
||||||
|
- }
|
||||||
|
- hv_event_tasklet_enable(newchannel);
|
||||||
|
-
|
||||||
|
vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||||
|
|
||||||
|
err_free_chan:
|
||||||
|
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||||
|
index 956acfc93487..9ee292b28e41 100644
|
||||||
|
--- a/include/linux/hyperv.h
|
||||||
|
+++ b/include/linux/hyperv.h
|
||||||
|
@@ -1461,6 +1461,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
|
||||||
|
void hv_event_tasklet_disable(struct vmbus_channel *channel);
|
||||||
|
void hv_event_tasklet_enable(struct vmbus_channel *channel);
|
||||||
|
|
||||||
|
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
|
||||||
|
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
|
||||||
|
+
|
||||||
|
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||||
|
|
||||||
|
void vmbus_setevent(struct vmbus_channel *channel);
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user