mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 18:11:35 +00:00
Merge pull request #83 from ijc25/hyperv-sockets
hyperv-socks: Backport patches.
This commit is contained in:
commit
2d492afe50
@ -1197,6 +1197,7 @@ CONFIG_OPENVSWITCH_VXLAN=y
|
||||
CONFIG_VSOCKETS=y
|
||||
CONFIG_VIRTIO_VSOCKETS=y
|
||||
CONFIG_VIRTIO_VSOCKETS_COMMON=y
|
||||
CONFIG_HYPERV_SOCK=y
|
||||
CONFIG_NETLINK_MMAP=y
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_MPLS=y
|
||||
@ -1225,6 +1226,7 @@ CONFIG_NET_FLOW_LIMIT=y
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_AF_RXRPC is not set
|
||||
# CONFIG_AF_KCM is not set
|
||||
CONFIG_FIB_RULES=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
# CONFIG_WIMAX is not set
|
||||
|
@ -1,7 +1,7 @@
|
||||
From d8f7730e3211cdb16cd9d26143121aeb05f22509 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 17 Dec 2015 16:53:43 +0800
|
||||
Subject: [PATCH 1/9] virtio: make find_vqs() checkpatch.pl-friendly
|
||||
Subject: [PATCH 01/25] virtio: make find_vqs() checkpatch.pl-friendly
|
||||
|
||||
checkpatch.pl wants arrays of strings declared as follows:
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0260029492a1503e871236767ed86e2fc3862cc2 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Lawall <julia.lawall@lip6.fr>
|
||||
Date: Sat, 21 Nov 2015 18:39:17 +0100
|
||||
Subject: [PATCH 2/9] VSOCK: constify vmci_transport_notify_ops structures
|
||||
Subject: [PATCH 02/25] VSOCK: constify vmci_transport_notify_ops structures
|
||||
|
||||
The vmci_transport_notify_ops structures are never modified, so declare
|
||||
them as const.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 6a585c01a353551a69af45bf31606f13115480d1 Mon Sep 17 00:00:00 2001
|
||||
From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
|
||||
Date: Tue, 22 Mar 2016 17:05:52 +0100
|
||||
Subject: [PATCH 3/9] AF_VSOCK: Shrink the area influenced by prepare_to_wait
|
||||
Subject: [PATCH 03/25] AF_VSOCK: Shrink the area influenced by prepare_to_wait
|
||||
|
||||
When a thread is prepared for waiting by calling prepare_to_wait, sleeping
|
||||
is not allowed until either the wait has taken place or finish_wait has
|
||||
|
@ -1,7 +1,7 @@
|
||||
From a3f136168f164f66de1de277a08b76f54b289d5a Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 17 Dec 2015 11:10:21 +0800
|
||||
Subject: [PATCH 4/9] VSOCK: transport-specific vsock_transport functions
|
||||
Subject: [PATCH 04/25] VSOCK: transport-specific vsock_transport functions
|
||||
|
||||
struct vsock_transport contains function pointers called by AF_VSOCK
|
||||
core code. The transport may want its own transport-specific function
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 4018aa8a812fd6f1a64e3d227550bf5752127314 Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:27:00 +0800
|
||||
Subject: [PATCH 5/9] VSOCK: Introduce virtio_vsock_common.ko
|
||||
Subject: [PATCH 05/25] VSOCK: Introduce virtio_vsock_common.ko
|
||||
|
||||
This module contains the common code and header files for the following
|
||||
virtio_transporto and vhost_vsock kernel modules.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From ccaac837ceb4a9582bb57f71e0cac791f7336b19 Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:28:48 +0800
|
||||
Subject: [PATCH 6/9] VSOCK: Introduce virtio_transport.ko
|
||||
Subject: [PATCH 06/25] VSOCK: Introduce virtio_transport.ko
|
||||
|
||||
VM sockets virtio transport implementation. This driver runs in the
|
||||
guest.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From f52efbc874c742a671939ea6408c59545025007d Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:29:21 +0800
|
||||
Subject: [PATCH 7/9] VSOCK: Introduce vhost_vsock.ko
|
||||
Subject: [PATCH 07/25] VSOCK: Introduce vhost_vsock.ko
|
||||
|
||||
VM sockets vhost transport implementation. This driver runs on the
|
||||
host.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e8c8f5299fd202db5d56a10f1dc0a4e464e9a211 Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:30:19 +0800
|
||||
Subject: [PATCH 8/9] VSOCK: Add Makefile and Kconfig
|
||||
Subject: [PATCH 08/25] VSOCK: Add Makefile and Kconfig
|
||||
|
||||
Enable virtio-vsock and vhost-vsock.
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
From 550ec4c8f90f2bf99c1bcb13b2f8476780f42418 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Campbell <ian.campbell@docker.com>
|
||||
Date: Mon, 4 Apr 2016 14:50:10 +0100
|
||||
Subject: [PATCH 9/9] VSOCK: Only allow host network namespace to use AF_VSOCK.
|
||||
Subject: [PATCH 09/25] VSOCK: Only allow host network namespace to use
|
||||
AF_VSOCK.
|
||||
|
||||
The VSOCK addressing schema does not really lend itself to simply creating an
|
||||
alternative end point address within a namespace.
|
||||
|
@ -0,0 +1,87 @@
|
||||
From 1f7906c43fe139e15c19f35a4493a7ca61a6463f Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:47 -0800
|
||||
Subject: [PATCH 10/25] Drivers: hv: vmbus: serialize process_chn_event() and
|
||||
vmbus_close_internal()
|
||||
|
||||
process_chn_event(), running in the tasklet, can race with
|
||||
vmbus_close_internal() in the case of SMP guest, e.g., when the former is
|
||||
accessing channel->inbound.ring_buffer, the latter could be freeing the
|
||||
ring_buffer pages.
|
||||
|
||||
To resolve the race, we can serialize them by disabling the tasklet when
|
||||
the latter is running here.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 63d55b2aeb5e4faa170316fee73c3c47ea9268c7)
|
||||
---
|
||||
drivers/hv/channel.c | 21 +++++++++++++++++++--
|
||||
1 file changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 9098f13..6a90c69 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/hyperv.h>
|
||||
#include <linux/uio.h>
|
||||
+#include <linux/interrupt.h>
|
||||
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
@@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg)
|
||||
static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
{
|
||||
struct vmbus_channel_close_channel *msg;
|
||||
+ struct tasklet_struct *tasklet;
|
||||
int ret;
|
||||
|
||||
+ /*
|
||||
+ * process_chn_event(), running in the tasklet, can race
|
||||
+ * with vmbus_close_internal() in the case of SMP guest, e.g., when
|
||||
+ * the former is accessing channel->inbound.ring_buffer, the latter
|
||||
+ * could be freeing the ring_buffer pages.
|
||||
+ *
|
||||
+ * To resolve the race, we can serialize them by disabling the
|
||||
+ * tasklet when the latter is running here.
|
||||
+ */
|
||||
+ tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||
+ tasklet_disable(tasklet);
|
||||
+
|
||||
channel->state = CHANNEL_OPEN_STATE;
|
||||
channel->sc_creation_callback = NULL;
|
||||
/* Stop callback and cancel the timer asap */
|
||||
@@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
* If we failed to post the close msg,
|
||||
* it is perhaps better to leak memory.
|
||||
*/
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* Tear down the gpadl for the channel's ring buffer */
|
||||
@@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
* If we failed to teardown gpadl,
|
||||
* it is perhaps better to leak memory.
|
||||
*/
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
if (channel->rescind)
|
||||
hv_process_channel_removal(channel,
|
||||
channel->offermsg.child_relid);
|
||||
+out:
|
||||
+ tasklet_enable(tasklet);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 00375a20748490730b2f004bfe44e83abecec5f1 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:48 -0800
|
||||
Subject: [PATCH 11/25] Drivers: hv: vmbus: do sanity check of channel state in
|
||||
vmbus_close_internal()
|
||||
|
||||
This fixes an incorrect assumption of channel state in the function.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 64b7faf903dae2df94d89edf2c688b16751800e4)
|
||||
---
|
||||
drivers/hv/channel.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 6a90c69..b3c14ca 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -512,6 +512,18 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||
tasklet_disable(tasklet);
|
||||
|
||||
+ /*
|
||||
+ * In case a device driver's probe() fails (e.g.,
|
||||
+ * util_probe() -> vmbus_open() returns -ENOMEM) and the device is
|
||||
+ * rescinded later (e.g., we dynamically disble an Integrated Service
|
||||
+ * in Hyper-V Manager), the driver's remove() invokes vmbus_close():
|
||||
+ * here we should skip most of the below cleanup work.
|
||||
+ */
|
||||
+ if (channel->state != CHANNEL_OPENED_STATE) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
channel->state = CHANNEL_OPEN_STATE;
|
||||
channel->sc_creation_callback = NULL;
|
||||
/* Stop callback and cancel the timer asap */
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,122 @@
|
||||
From 53cd041cabf572ec98d5b911abfff1a3baf1ccaa Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:49 -0800
|
||||
Subject: [PATCH 12/25] Drivers: hv: vmbus: fix rescind-offer handling for
|
||||
device without a driver
|
||||
|
||||
In the path vmbus_onoffer_rescind() -> vmbus_device_unregister() ->
|
||||
device_unregister() -> ... -> __device_release_driver(), we can see for a
|
||||
device without a driver loaded: dev->driver is NULL, so
|
||||
dev->bus->remove(dev), namely vmbus_remove(), isn't invoked.
|
||||
|
||||
As a result, vmbus_remove() -> hv_process_channel_removal() isn't invoked
|
||||
and some cleanups(like sending a CHANNELMSG_RELID_RELEASED message to the
|
||||
host) aren't done.
|
||||
|
||||
We can demo the issue this way:
|
||||
1. rmmod hv_utils;
|
||||
2. disable the Heartbeat Integration Service in Hyper-V Manager and lsvmbus
|
||||
shows the device disappears.
|
||||
3. re-enable the Heartbeat in Hyper-V Manager and modprobe hv_utils, but
|
||||
lsvmbus shows the device can't appear again.
|
||||
This is because, the host thinks the VM hasn't released the relid, so can't
|
||||
re-offer the device to the VM.
|
||||
|
||||
We can fix the issue by moving hv_process_channel_removal()
|
||||
from vmbus_close_internal() to vmbus_device_release(), since the latter is
|
||||
always invoked on device_unregister(), whether or not the dev has a driver
|
||||
loaded.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 34c6801e3310ad286c7bb42bc88d42926b8f99bf)
|
||||
---
|
||||
drivers/hv/channel.c | 6 ------
|
||||
drivers/hv/channel_mgmt.c | 6 +++---
|
||||
drivers/hv/vmbus_drv.c | 15 +++------------
|
||||
3 files changed, 6 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index b3c14ca..2889d97 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -575,12 +575,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
free_pages((unsigned long)channel->ringbuffer_pages,
|
||||
get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
|
||||
|
||||
- /*
|
||||
- * If the channel has been rescinded; process device removal.
|
||||
- */
|
||||
- if (channel->rescind)
|
||||
- hv_process_channel_removal(channel,
|
||||
- channel->offermsg.child_relid);
|
||||
out:
|
||||
tasklet_enable(tasklet);
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 652afd1..bd2e9f6 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -191,6 +191,8 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
if (channel == NULL)
|
||||
return;
|
||||
|
||||
+ BUG_ON(!channel->rescind);
|
||||
+
|
||||
if (channel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
smp_call_function_single(channel->target_cpu,
|
||||
@@ -230,9 +232,7 @@ void vmbus_free_channels(void)
|
||||
|
||||
list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list,
|
||||
listentry) {
|
||||
- /* if we don't set rescind to true, vmbus_close_internal()
|
||||
- * won't invoke hv_process_channel_removal().
|
||||
- */
|
||||
+ /* hv_process_channel_removal() needs this */
|
||||
channel->rescind = true;
|
||||
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index f19b6f7..7e46a48 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -602,23 +602,11 @@ static int vmbus_remove(struct device *child_device)
|
||||
{
|
||||
struct hv_driver *drv;
|
||||
struct hv_device *dev = device_to_hv_device(child_device);
|
||||
- u32 relid = dev->channel->offermsg.child_relid;
|
||||
|
||||
if (child_device->driver) {
|
||||
drv = drv_to_hv_drv(child_device->driver);
|
||||
if (drv->remove)
|
||||
drv->remove(dev);
|
||||
- else {
|
||||
- hv_process_channel_removal(dev->channel, relid);
|
||||
- pr_err("remove not set for driver %s\n",
|
||||
- dev_name(child_device));
|
||||
- }
|
||||
- } else {
|
||||
- /*
|
||||
- * We don't have a driver for this device; deal with the
|
||||
- * rescind message by removing the channel.
|
||||
- */
|
||||
- hv_process_channel_removal(dev->channel, relid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -653,7 +641,10 @@ static void vmbus_shutdown(struct device *child_device)
|
||||
static void vmbus_device_release(struct device *device)
|
||||
{
|
||||
struct hv_device *hv_dev = device_to_hv_device(device);
|
||||
+ struct vmbus_channel *channel = hv_dev->channel;
|
||||
|
||||
+ hv_process_channel_removal(channel,
|
||||
+ channel->offermsg.child_relid);
|
||||
kfree(hv_dev);
|
||||
|
||||
}
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,74 @@
|
||||
From 613d19efd48c06602018c0e7c6b4bf8d191105cd Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:50 -0800
|
||||
Subject: [PATCH 13/25] Drivers: hv: vmbus: release relid on error in
|
||||
vmbus_process_offer()
|
||||
|
||||
We want to simplify vmbus_onoffer_rescind() by not invoking
|
||||
hv_process_channel_removal(NULL, ...).
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit f52078cf5711ce47c113a58702b35c8ff5f212f5)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 21 +++++++++++++++------
|
||||
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index bd2e9f6..df76a71 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -177,19 +177,22 @@ static void percpu_channel_deq(void *arg)
|
||||
}
|
||||
|
||||
|
||||
-void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
+static void vmbus_release_relid(u32 relid)
|
||||
{
|
||||
struct vmbus_channel_relid_released msg;
|
||||
- unsigned long flags;
|
||||
- struct vmbus_channel *primary_channel;
|
||||
|
||||
memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
|
||||
msg.child_relid = relid;
|
||||
msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
|
||||
vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
|
||||
+}
|
||||
|
||||
- if (channel == NULL)
|
||||
- return;
|
||||
+void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ struct vmbus_channel *primary_channel;
|
||||
+
|
||||
+ vmbus_release_relid(relid);
|
||||
|
||||
BUG_ON(!channel->rescind);
|
||||
|
||||
@@ -336,6 +339,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
return;
|
||||
|
||||
err_deq_chan:
|
||||
+ vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||
+
|
||||
spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
list_del(&newchannel->listentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
|
||||
@@ -585,7 +590,11 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
channel = relid2channel(rescind->child_relid);
|
||||
|
||||
if (channel == NULL) {
|
||||
- hv_process_channel_removal(NULL, rescind->child_relid);
|
||||
+ /*
|
||||
+ * This is very impossible, because in
|
||||
+ * vmbus_process_offer(), we have already invoked
|
||||
+ * vmbus_release_relid() on error.
|
||||
+ */
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,116 @@
|
||||
From b9a136e91171bea99a140195ccb4bbea2a65551d Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:51 -0800
|
||||
Subject: [PATCH 14/25] Drivers: hv: vmbus: channge
|
||||
vmbus_connection.channel_lock to mutex
|
||||
|
||||
spinlock is unnecessary here.
|
||||
mutex is enough.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit d6f591e339d23f434efda11917da511870891472)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 12 ++++++------
|
||||
drivers/hv/connection.c | 7 +++----
|
||||
drivers/hv/hyperv_vmbus.h | 2 +-
|
||||
3 files changed, 10 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index df76a71..bd4f084 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -206,9 +206,9 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
}
|
||||
|
||||
if (channel->primary_channel == NULL) {
|
||||
- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
list_del(&channel->listentry);
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
primary_channel = channel;
|
||||
} else {
|
||||
@@ -253,7 +253,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
unsigned long flags;
|
||||
|
||||
/* Make sure this is a new offer */
|
||||
- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
|
||||
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
|
||||
if (!uuid_le_cmp(channel->offermsg.offer.if_type,
|
||||
@@ -269,7 +269,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
list_add_tail(&newchannel->listentry,
|
||||
&vmbus_connection.chn_list);
|
||||
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
if (!fnew) {
|
||||
/*
|
||||
@@ -341,9 +341,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
err_deq_chan:
|
||||
vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||
|
||||
- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
list_del(&newchannel->listentry);
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
if (newchannel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
|
||||
index 4fc2e88..521f48e 100644
|
||||
--- a/drivers/hv/connection.c
|
||||
+++ b/drivers/hv/connection.c
|
||||
@@ -146,7 +146,7 @@ int vmbus_connect(void)
|
||||
spin_lock_init(&vmbus_connection.channelmsg_lock);
|
||||
|
||||
INIT_LIST_HEAD(&vmbus_connection.chn_list);
|
||||
- spin_lock_init(&vmbus_connection.channel_lock);
|
||||
+ mutex_init(&vmbus_connection.channel_mutex);
|
||||
|
||||
/*
|
||||
* Setup the vmbus event connection for channel interrupt
|
||||
@@ -282,11 +282,10 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
{
|
||||
struct vmbus_channel *channel;
|
||||
struct vmbus_channel *found_channel = NULL;
|
||||
- unsigned long flags;
|
||||
struct list_head *cur, *tmp;
|
||||
struct vmbus_channel *cur_sc;
|
||||
|
||||
- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
|
||||
if (channel->offermsg.child_relid == relid) {
|
||||
found_channel = channel;
|
||||
@@ -305,7 +304,7 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
}
|
||||
}
|
||||
}
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
return found_channel;
|
||||
}
|
||||
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
|
||||
index 3782636..d9937be 100644
|
||||
--- a/drivers/hv/hyperv_vmbus.h
|
||||
+++ b/drivers/hv/hyperv_vmbus.h
|
||||
@@ -678,7 +678,7 @@ struct vmbus_connection {
|
||||
|
||||
/* List of channels */
|
||||
struct list_head chn_list;
|
||||
- spinlock_t channel_lock;
|
||||
+ struct mutex channel_mutex;
|
||||
|
||||
struct workqueue_struct *work_queue;
|
||||
};
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 37e0f1616a680b0b209c3555812c0691dacd74e0 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:37 -0800
|
||||
Subject: [PATCH 15/25] Drivers: hv: vmbus: add a helper function to set a
|
||||
channel's pending send size
|
||||
|
||||
This will be used by the coming net/hvsock driver.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 3c75354d043ad546148d6992e40033ecaefc5ea5)
|
||||
---
|
||||
include/linux/hyperv.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index ae6a711..fda6310 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -792,6 +792,12 @@ static inline void *get_per_channel_state(struct vmbus_channel *c)
|
||||
return c->per_channel_state;
|
||||
}
|
||||
|
||||
+static inline void set_channel_pending_send_size(struct vmbus_channel *c,
|
||||
+ u32 size)
|
||||
+{
|
||||
+ c->outbound.ring_buffer->pending_send_sz = size;
|
||||
+}
|
||||
+
|
||||
void vmbus_onmessage(void *context);
|
||||
|
||||
int vmbus_request_offers(void);
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 7d695c9e75755b005a7f45f99dfd7d3bb641e3a8 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:38 -0800
|
||||
Subject: [PATCH 16/25] Drivers: hv: vmbus: define the new offer type for
|
||||
Hyper-V socket (hvsock)
|
||||
|
||||
A helper function is also added.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit e8d6ca023efce3bd80050dcd9e708ee3cf8babd4)
|
||||
---
|
||||
include/linux/hyperv.h | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index fda6310..9fb2130 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -237,6 +237,7 @@ struct vmbus_channel_offer {
|
||||
#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100
|
||||
#define VMBUS_CHANNEL_PARENT_OFFER 0x200
|
||||
#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400
|
||||
+#define VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER 0x2000
|
||||
|
||||
struct vmpacket_descriptor {
|
||||
u16 type;
|
||||
@@ -771,6 +772,12 @@ struct vmbus_channel {
|
||||
enum hv_signal_policy signal_policy;
|
||||
};
|
||||
|
||||
+static inline bool is_hvsock_channel(const struct vmbus_channel *c)
|
||||
+{
|
||||
+ return !!(c->offermsg.offer.chn_flags &
|
||||
+ VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER);
|
||||
+}
|
||||
+
|
||||
static inline void set_channel_signal_state(struct vmbus_channel *c,
|
||||
enum hv_signal_policy policy)
|
||||
{
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 8507cfd5b7af092d5cc5e99ff9852b3bc46c48c0 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:39 -0800
|
||||
Subject: [PATCH 17/25] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid
|
||||
unnecessary signaling
|
||||
|
||||
When the hvsock channel's outbound ringbuffer is full (i.e.,
|
||||
hv_ringbuffer_write() returns -EAGAIN), we should avoid the unnecessary
|
||||
signaling the host.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 5f363bc38f810d238d1e8b19998625ddec3b8138)
|
||||
---
|
||||
drivers/hv/channel.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 2889d97..a7f9e3e 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -659,6 +659,9 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
|
||||
* If we cannot write to the ring-buffer; signal the host
|
||||
* even if we may not have written anything. This is a rare
|
||||
* enough condition that it should not matter.
|
||||
+ * NOTE: in this case, the hvsock channel is an exception, because
|
||||
+ * it looks the host side's hvsock implementation has a throttling
|
||||
+ * mechanism which can hurt the performance otherwise.
|
||||
*/
|
||||
|
||||
if (channel->signal_policy)
|
||||
@@ -666,7 +669,8 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
|
||||
else
|
||||
kick_q = true;
|
||||
|
||||
- if (((ret == 0) && kick_q && signal) || (ret))
|
||||
+ if (((ret == 0) && kick_q && signal) ||
|
||||
+ (ret && !is_hvsock_channel(channel)))
|
||||
vmbus_setevent(channel);
|
||||
|
||||
return ret;
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,101 @@
|
||||
From 746cdb5f4c824ef3af9d12909818a077a0cf303c Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:40 -0800
|
||||
Subject: [PATCH 18/25] Drivers: hv: vmbus: define a new VMBus message type for
|
||||
hvsock
|
||||
|
||||
A function to send the type of message is also added.
|
||||
|
||||
The coming net/hvsock driver will use this function to proactively request
|
||||
the host to offer a VMBus channel for a new hvsock connection.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 5c23a1a5c60b0f472cfa61cd7d8279f8aaeb5b64)
|
||||
---
|
||||
drivers/hv/channel.c | 15 +++++++++++++++
|
||||
drivers/hv/channel_mgmt.c | 4 ++++
|
||||
include/linux/hyperv.h | 13 +++++++++++++
|
||||
3 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index a7f9e3e..239b072 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -219,6 +219,21 @@ error0:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_open);
|
||||
|
||||
+/* Used for Hyper-V Socket: a guest client's connect() to the host */
|
||||
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
|
||||
+ const uuid_le *shv_host_servie_id)
|
||||
+{
|
||||
+ struct vmbus_channel_tl_connect_request conn_msg;
|
||||
+
|
||||
+ memset(&conn_msg, 0, sizeof(conn_msg));
|
||||
+ conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST;
|
||||
+ conn_msg.guest_endpoint_id = *shv_guest_servie_id;
|
||||
+ conn_msg.host_service_id = *shv_host_servie_id;
|
||||
+
|
||||
+ return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
|
||||
+
|
||||
/*
|
||||
* create_gpadl_header - Creates a gpadl for the specified buffer
|
||||
*/
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index bd4f084..4d61f41 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -820,6 +820,10 @@ struct vmbus_channel_message_table_entry
|
||||
{CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response},
|
||||
{CHANNELMSG_UNLOAD, 0, NULL},
|
||||
{CHANNELMSG_UNLOAD_RESPONSE, 1, vmbus_unload_response},
|
||||
+ {CHANNELMSG_18, 0, NULL},
|
||||
+ {CHANNELMSG_19, 0, NULL},
|
||||
+ {CHANNELMSG_20, 0, NULL},
|
||||
+ {CHANNELMSG_TL_CONNECT_REQUEST, 0, NULL},
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 9fb2130..3f485a4 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -394,6 +394,10 @@ enum vmbus_channel_message_type {
|
||||
CHANNELMSG_VERSION_RESPONSE = 15,
|
||||
CHANNELMSG_UNLOAD = 16,
|
||||
CHANNELMSG_UNLOAD_RESPONSE = 17,
|
||||
+ CHANNELMSG_18 = 18,
|
||||
+ CHANNELMSG_19 = 19,
|
||||
+ CHANNELMSG_20 = 20,
|
||||
+ CHANNELMSG_TL_CONNECT_REQUEST = 21,
|
||||
CHANNELMSG_COUNT
|
||||
};
|
||||
|
||||
@@ -564,6 +568,13 @@ struct vmbus_channel_initiate_contact {
|
||||
u64 monitor_page2;
|
||||
} __packed;
|
||||
|
||||
+/* Hyper-V socket: guest's connect()-ing to host */
|
||||
+struct vmbus_channel_tl_connect_request {
|
||||
+ struct vmbus_channel_message_header header;
|
||||
+ uuid_le guest_endpoint_id;
|
||||
+ uuid_le host_service_id;
|
||||
+} __packed;
|
||||
+
|
||||
struct vmbus_channel_version_response {
|
||||
struct vmbus_channel_message_header header;
|
||||
u8 version_supported;
|
||||
@@ -1276,4 +1287,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||
|
||||
extern __u32 vmbus_proto_version;
|
||||
|
||||
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
|
||||
+ const uuid_le *shv_host_servie_id);
|
||||
#endif /* _HYPERV_H */
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,64 @@
|
||||
From fb6b14a429dae008b7fee772a1e27cb09db459b7 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:41 -0800
|
||||
Subject: [PATCH 19/25] Drivers: hv: vmbus: add a hvsock flag in struct
|
||||
hv_driver
|
||||
|
||||
Only the coming hv_sock driver has a "true" value for this flag.
|
||||
|
||||
We treat the hvsock offers/channels as special VMBus devices.
|
||||
Since the hv_sock driver handles all the hvsock offers/channels, we need to
|
||||
tweak vmbus_match() for hv_sock driver, so we introduce this flag.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 8981da320a11217589aa3c50f9e891bcdef07ece)
|
||||
---
|
||||
drivers/hv/vmbus_drv.c | 4 ++++
|
||||
include/linux/hyperv.h | 14 ++++++++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index 7e46a48..7d607ad 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -563,6 +563,10 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
|
||||
struct hv_driver *drv = drv_to_hv_drv(driver);
|
||||
struct hv_device *hv_dev = device_to_hv_device(device);
|
||||
|
||||
+ /* The hv_sock driver handles all hv_sock offers. */
|
||||
+ if (is_hvsock_channel(hv_dev->channel))
|
||||
+ return drv->hvsock;
|
||||
+
|
||||
if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
|
||||
return 1;
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 3f485a4..9ee79af 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -966,6 +966,20 @@ extern void vmbus_ontimer(unsigned long data);
|
||||
struct hv_driver {
|
||||
const char *name;
|
||||
|
||||
+ /*
|
||||
+ * A hvsock offer, which has a VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER
|
||||
+ * channel flag, actually doesn't mean a synthetic device because the
|
||||
+ * offer's if_type/if_instance can change for every new hvsock
|
||||
+ * connection.
|
||||
+ *
|
||||
+ * However, to facilitate the notification of new-offer/rescind-offer
|
||||
+ * from vmbus driver to hvsock driver, we can handle hvsock offer as
|
||||
+ * a special vmbus device, and hence we need the below flag to
|
||||
+ * indicate if the driver is the hvsock driver or not: we need to
|
||||
+ * specially treat the hvosck offer & driver in vmbus_match().
|
||||
+ */
|
||||
+ bool hvsock;
|
||||
+
|
||||
/* the device type supported by this driver */
|
||||
uuid_le dev_type;
|
||||
const struct hv_vmbus_device_id *id_table;
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,72 @@
|
||||
From 4a2d55757c137c2e574500227cb2efe77a26ee3a Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:42 -0800
|
||||
Subject: [PATCH 20/25] Drivers: hv: vmbus: add a per-channel rescind callback
|
||||
|
||||
This will be used by the coming hv_sock driver.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 499e8401a515d04daa986b995da710d2b9737764)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 11 +++++++++++
|
||||
include/linux/hyperv.h | 9 +++++++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 4d61f41..421e3dd 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -603,6 +603,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
spin_unlock_irqrestore(&channel->lock, flags);
|
||||
|
||||
if (channel->device_obj) {
|
||||
+ if (channel->chn_rescind_callback) {
|
||||
+ channel->chn_rescind_callback(channel);
|
||||
+ return;
|
||||
+ }
|
||||
/*
|
||||
* We will have to unregister this device from the
|
||||
* driver core.
|
||||
@@ -972,3 +976,10 @@ bool vmbus_are_subchannels_present(struct vmbus_channel *primary)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);
|
||||
+
|
||||
+void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
|
||||
+ void (*chn_rescind_cb)(struct vmbus_channel *))
|
||||
+{
|
||||
+ channel->chn_rescind_callback = chn_rescind_cb;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vmbus_set_chn_rescind_callback);
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 9ee79af..09e9ec1 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -742,6 +742,12 @@ struct vmbus_channel {
|
||||
void (*sc_creation_callback)(struct vmbus_channel *new_sc);
|
||||
|
||||
/*
|
||||
+ * Channel rescind callback. Some channels (the hvsock ones), need to
|
||||
+ * register a callback which is invoked in vmbus_onoffer_rescind().
|
||||
+ */
|
||||
+ void (*chn_rescind_callback)(struct vmbus_channel *channel);
|
||||
+
|
||||
+ /*
|
||||
* The spinlock to protect the structure. It is being used to protect
|
||||
* test-and-set access to various attributes of the structure as well
|
||||
* as all sc_list operations.
|
||||
@@ -827,6 +833,9 @@ int vmbus_request_offers(void);
|
||||
void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
|
||||
void (*sc_cr_cb)(struct vmbus_channel *new_sc));
|
||||
|
||||
+void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
|
||||
+ void (*chn_rescind_cb)(struct vmbus_channel *));
|
||||
+
|
||||
/*
|
||||
* Retrieve the (sub) channel on which to send an outgoing request.
|
||||
* When a primary channel has multiple sub-channels, we choose a
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
@ -0,0 +1,153 @@
|
||||
From b6c9f23164d3e7460d8983d27f2df194ab5e9a0b Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:43 -0800
|
||||
Subject: [PATCH 21/25] Drivers: hv: vmbus: add an API
|
||||
vmbus_hvsock_device_unregister()
|
||||
|
||||
The hvsock driver needs this API to release all the resources related
|
||||
to the channel.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 85d9aa705184a4504d0330017e3956fcdae8a9d6)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 33 ++++++++++++++++++++++++++++-----
|
||||
drivers/hv/connection.c | 4 ++--
|
||||
include/linux/hyperv.h | 2 ++
|
||||
3 files changed, 32 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 421e3dd..0fe9665 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -195,6 +195,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
vmbus_release_relid(relid);
|
||||
|
||||
BUG_ON(!channel->rescind);
|
||||
+ BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||
|
||||
if (channel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
@@ -206,9 +207,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
}
|
||||
|
||||
if (channel->primary_channel == NULL) {
|
||||
- mutex_lock(&vmbus_connection.channel_mutex);
|
||||
list_del(&channel->listentry);
|
||||
- mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
primary_channel = channel;
|
||||
} else {
|
||||
@@ -251,6 +250,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
struct vmbus_channel *channel;
|
||||
bool fnew = true;
|
||||
unsigned long flags;
|
||||
+ int ret;
|
||||
|
||||
/* Make sure this is a new offer */
|
||||
mutex_lock(&vmbus_connection.channel_mutex);
|
||||
@@ -330,7 +330,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
* binding which eventually invokes the device driver's AddDevice()
|
||||
* method.
|
||||
*/
|
||||
- if (vmbus_device_register(newchannel->device_obj) != 0) {
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
+ ret = vmbus_device_register(newchannel->device_obj);
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
+
|
||||
+ if (ret != 0) {
|
||||
pr_err("unable to add child device object (relid %d)\n",
|
||||
newchannel->offermsg.child_relid);
|
||||
kfree(newchannel->device_obj);
|
||||
@@ -587,6 +591,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
struct device *dev;
|
||||
|
||||
rescind = (struct vmbus_channel_rescind_offer *)hdr;
|
||||
+
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
channel = relid2channel(rescind->child_relid);
|
||||
|
||||
if (channel == NULL) {
|
||||
@@ -595,7 +601,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
* vmbus_process_offer(), we have already invoked
|
||||
* vmbus_release_relid() on error.
|
||||
*/
|
||||
- return;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&channel->lock, flags);
|
||||
@@ -605,7 +611,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
if (channel->device_obj) {
|
||||
if (channel->chn_rescind_callback) {
|
||||
channel->chn_rescind_callback(channel);
|
||||
- return;
|
||||
+ goto out;
|
||||
}
|
||||
/*
|
||||
* We will have to unregister this device from the
|
||||
@@ -620,8 +626,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
hv_process_channel_removal(channel,
|
||||
channel->offermsg.child_relid);
|
||||
}
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
}
|
||||
|
||||
+void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
|
||||
+{
|
||||
+ mutex_lock(&vmbus_connection.channel_mutex);
|
||||
+
|
||||
+ BUG_ON(!is_hvsock_channel(channel));
|
||||
+
|
||||
+ channel->rescind = true;
|
||||
+ vmbus_device_unregister(channel->device_obj);
|
||||
+
|
||||
+ mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
|
||||
+
|
||||
+
|
||||
/*
|
||||
* vmbus_onoffers_delivered -
|
||||
* This is invoked when all offers have been delivered.
|
||||
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
|
||||
index 521f48e..09c08b5 100644
|
||||
--- a/drivers/hv/connection.c
|
||||
+++ b/drivers/hv/connection.c
|
||||
@@ -285,7 +285,8 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
struct list_head *cur, *tmp;
|
||||
struct vmbus_channel *cur_sc;
|
||||
|
||||
- mutex_lock(&vmbus_connection.channel_mutex);
|
||||
+ BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||
+
|
||||
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
|
||||
if (channel->offermsg.child_relid == relid) {
|
||||
found_channel = channel;
|
||||
@@ -304,7 +305,6 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
}
|
||||
}
|
||||
}
|
||||
- mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
return found_channel;
|
||||
}
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 09e9ec1..af7ee0a 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1043,6 +1043,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
|
||||
const char *mod_name);
|
||||
void vmbus_driver_unregister(struct hv_driver *hv_driver);
|
||||
|
||||
+void vmbus_hvsock_device_unregister(struct vmbus_channel *channel);
|
||||
+
|
||||
int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
resource_size_t min, resource_size_t max,
|
||||
resource_size_t size, resource_size_t align,
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,52 @@
|
||||
From 4e7679280dd0ad8e28f9ebeea70127ed4385222a Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 21 Mar 2016 02:51:09 -0700
|
||||
Subject: [PATCH 23/25] net: add the AF_KCM entries to family name tables
|
||||
|
||||
This is for the recent kcm driver, which introduces AF_KCM(41) in
|
||||
b7ac4eb(kcm: Kernel Connection Multiplexor module).
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Cc: Signed-off-by: Tom Herbert <tom@herbertland.com>
|
||||
Origin: https://patchwork.ozlabs.org/patch/600006
|
||||
---
|
||||
net/core/sock.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/net/core/sock.c b/net/core/sock.c
|
||||
index 0d91f7d..925def4 100644
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -263,7 +263,8 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
|
||||
"sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
|
||||
"sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
|
||||
"sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" ,
|
||||
- "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX"
|
||||
+ "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" ,
|
||||
+ "sk_lock-AF_MAX"
|
||||
};
|
||||
static const char *const af_family_slock_key_strings[AF_MAX+1] = {
|
||||
"slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
|
||||
@@ -279,7 +280,8 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
|
||||
"slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
|
||||
"slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
|
||||
"slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" ,
|
||||
- "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX"
|
||||
+ "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" ,
|
||||
+ "slock-AF_MAX"
|
||||
};
|
||||
static const char *const af_family_clock_key_strings[AF_MAX+1] = {
|
||||
"clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
|
||||
@@ -295,7 +297,8 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
|
||||
"clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
|
||||
"clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
|
||||
"clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" ,
|
||||
- "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX"
|
||||
+ "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" ,
|
||||
+ "clock-AF_MAX"
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
1730
alpine/kernel/patches/0024-hv_sock-introduce-Hyper-V-Sockets.patch
Normal file
1730
alpine/kernel/patches/0024-hv_sock-introduce-Hyper-V-Sockets.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,49 @@
|
||||
From 0198717a05de80bc7769ed1d2c3a0cdf3c40fd7c Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 21 Mar 2016 02:53:08 -0700
|
||||
Subject: [PATCH 25/25] net: add the AF_HYPERV entries to family name tables
|
||||
|
||||
This is for the hv_sock driver, which introduces AF_HYPERV(42).
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
|
||||
Origin: https://patchwork.ozlabs.org/patch/600009
|
||||
---
|
||||
net/core/sock.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/net/core/sock.c b/net/core/sock.c
|
||||
index 925def4..323f7a3 100644
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -264,7 +264,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
|
||||
"sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
|
||||
"sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" ,
|
||||
"sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" ,
|
||||
- "sk_lock-AF_MAX"
|
||||
+ "sk_lock-AF_HYPERV", "sk_lock-AF_MAX"
|
||||
};
|
||||
static const char *const af_family_slock_key_strings[AF_MAX+1] = {
|
||||
"slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
|
||||
@@ -281,7 +281,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
|
||||
"slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
|
||||
"slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" ,
|
||||
"slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" ,
|
||||
- "slock-AF_MAX"
|
||||
+ "slock-AF_HYPERV", "slock-AF_MAX"
|
||||
};
|
||||
static const char *const af_family_clock_key_strings[AF_MAX+1] = {
|
||||
"clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
|
||||
@@ -298,7 +298,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
|
||||
"clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
|
||||
"clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" ,
|
||||
"clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" ,
|
||||
- "clock-AF_MAX"
|
||||
+ "clock-AF_HYPERV", "clock-AF_MAX"
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
2.8.0.rc3
|
||||
|
Loading…
Reference in New Issue
Block a user