mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-09-06 09:21:28 +00:00
Merge pull request #133 from rneugeba/vmbus-up
kernel: cherry-pick more VMBus patches, fix for yet another kernel crash
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
From 31adb74f5668e7e44615a2854742f8726a818533 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 17 Dec 2015 16:53:43 +0800
|
||||
Subject: [PATCH 01/28] virtio: make find_vqs() checkpatch.pl-friendly
|
||||
Subject: [PATCH 01/40] virtio: make find_vqs() checkpatch.pl-friendly
|
||||
|
||||
checkpatch.pl wants arrays of strings declared as follows:
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 4b274b13e7dfe4ac54072f324738c487a36b78b8 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 02/28] VSOCK: constify vmci_transport_notify_ops structures
|
||||
Subject: [PATCH 02/40] 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 31fb7962193b46e8f7e24ac350e3efc486f0fd90 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 03/28] AF_VSOCK: Shrink the area influenced by prepare_to_wait
|
||||
Subject: [PATCH 03/40] 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 891b9c6111fc77750b261cc03f8ac7a80441701a Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 17 Dec 2015 11:10:21 +0800
|
||||
Subject: [PATCH 04/28] VSOCK: transport-specific vsock_transport functions
|
||||
Subject: [PATCH 04/40] 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 a27fee87d915bfb9edf720f9068c3aed6649aa0c Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:27:00 +0800
|
||||
Subject: [PATCH 05/28] VSOCK: Introduce virtio_vsock_common.ko
|
||||
Subject: [PATCH 05/40] 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 19cfdea4fa3fa9136c234ac695f628fce73b40c2 Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:28:48 +0800
|
||||
Subject: [PATCH 06/28] VSOCK: Introduce virtio_transport.ko
|
||||
Subject: [PATCH 06/40] VSOCK: Introduce virtio_transport.ko
|
||||
|
||||
VM sockets virtio transport implementation. This driver runs in the
|
||||
guest.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From fd467c3335938b8eca0489008c390ad16a01aee7 Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:29:21 +0800
|
||||
Subject: [PATCH 07/28] VSOCK: Introduce vhost_vsock.ko
|
||||
Subject: [PATCH 07/40] VSOCK: Introduce vhost_vsock.ko
|
||||
|
||||
VM sockets vhost transport implementation. This driver runs on the
|
||||
host.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 5d2849bde15e969b8cf1eb2f5e818b62ec2181ec Mon Sep 17 00:00:00 2001
|
||||
From: Asias He <asias@redhat.com>
|
||||
Date: Thu, 13 Jun 2013 18:30:19 +0800
|
||||
Subject: [PATCH 08/28] VSOCK: Add Makefile and Kconfig
|
||||
Subject: [PATCH 08/40] VSOCK: Add Makefile and Kconfig
|
||||
|
||||
Enable virtio-vsock and vhost-vsock.
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 81b78a051aa8c61743abcc266eb9c7511dd19a62 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 09/28] VSOCK: Only allow host network namespace to use
|
||||
Subject: [PATCH 09/40] VSOCK: Only allow host network namespace to use
|
||||
AF_VSOCK.
|
||||
|
||||
The VSOCK addressing schema does not really lend itself to simply creating an
|
||||
|
@@ -0,0 +1,63 @@
|
||||
From b5a27dd334aa0f8e857e751c81f79b1ed482459c Mon Sep 17 00:00:00 2001
|
||||
From: Jake Oshins <jakeo@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:41 -0800
|
||||
Subject: [PATCH 10/40] drivers:hv: Define the channel type for Hyper-V PCI
|
||||
Express pass-through
|
||||
|
||||
This defines the channel type for PCI front-ends in Hyper-V VMs.
|
||||
|
||||
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 3053c762444a83ec6a8777f9476668b23b8ab180)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 3 +++
|
||||
include/linux/hyperv.h | 11 +++++++++++
|
||||
2 files changed, 14 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 652afd1..a77646b 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -358,6 +358,7 @@ enum {
|
||||
SCSI,
|
||||
NIC,
|
||||
ND_NIC,
|
||||
+ PCIE,
|
||||
MAX_PERF_CHN,
|
||||
};
|
||||
|
||||
@@ -375,6 +376,8 @@ static const struct hv_vmbus_device_id hp_devs[] = {
|
||||
{ HV_NIC_GUID, },
|
||||
/* NetworkDirect Guest RDMA */
|
||||
{ HV_ND_GUID, },
|
||||
+ /* PCI Express Pass Through */
|
||||
+ { HV_PCIE_GUID, },
|
||||
};
|
||||
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index ae6a711..10dda1e 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1156,6 +1156,17 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * PCI Express Pass Through
|
||||
+ * {44C4F61D-4444-4400-9D52-802E27EDE19F}
|
||||
+ */
|
||||
+
|
||||
+#define HV_PCIE_GUID \
|
||||
+ .guid = { \
|
||||
+ 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
|
||||
+ 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
* Common header for Hyper-V ICs
|
||||
*/
|
||||
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,297 @@
|
||||
From 02c6472ed9ae7498a0510d76dd4840349f4c7e92 Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:43 -0800
|
||||
Subject: [PATCH 11/40] Drivers: hv: vmbus: Use uuid_le type consistently
|
||||
|
||||
Consistently use uuid_le type in the Hyper-V driver code.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit af3ff643ea91ba64dd8d0b1cbed54d44512f96cd)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 2 +-
|
||||
drivers/hv/vmbus_drv.c | 10 ++---
|
||||
include/linux/hyperv.h | 92 ++++++++++++++---------------------------
|
||||
include/linux/mod_devicetable.h | 2 +-
|
||||
scripts/mod/file2alias.c | 2 +-
|
||||
5 files changed, 40 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index a77646b..38470aa 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -408,7 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
|
||||
struct cpumask *alloced_mask;
|
||||
|
||||
for (i = IDE; i < MAX_PERF_CHN; i++) {
|
||||
- if (!memcmp(type_guid->b, hp_devs[i].guid,
|
||||
+ if (!memcmp(type_guid->b, &hp_devs[i].guid,
|
||||
sizeof(uuid_le))) {
|
||||
perf_chn = true;
|
||||
break;
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index f19b6f7..e64934e 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -531,7 +531,7 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||
|
||||
static const uuid_le null_guid;
|
||||
|
||||
-static inline bool is_null_guid(const __u8 *guid)
|
||||
+static inline bool is_null_guid(const uuid_le *guid)
|
||||
{
|
||||
if (memcmp(guid, &null_guid, sizeof(uuid_le)))
|
||||
return false;
|
||||
@@ -544,9 +544,9 @@ static inline bool is_null_guid(const __u8 *guid)
|
||||
*/
|
||||
static const struct hv_vmbus_device_id *hv_vmbus_get_id(
|
||||
const struct hv_vmbus_device_id *id,
|
||||
- const __u8 *guid)
|
||||
+ const uuid_le *guid)
|
||||
{
|
||||
- for (; !is_null_guid(id->guid); id++)
|
||||
+ for (; !is_null_guid(&id->guid); id++)
|
||||
if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
|
||||
return id;
|
||||
|
||||
@@ -563,7 +563,7 @@ 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);
|
||||
|
||||
- if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
|
||||
+ if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -580,7 +580,7 @@ static int vmbus_probe(struct device *child_device)
|
||||
struct hv_device *dev = device_to_hv_device(child_device);
|
||||
const struct hv_vmbus_device_id *dev_id;
|
||||
|
||||
- dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
|
||||
+ dev_id = hv_vmbus_get_id(drv->id_table, &dev->dev_type);
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev, dev_id);
|
||||
if (ret != 0)
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 10dda1e..4712d7d 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1012,6 +1012,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
.guid = { g0, g1, g2, g3, g4, g5, g6, g7, \
|
||||
g8, g9, ga, gb, gc, gd, ge, gf },
|
||||
|
||||
+
|
||||
+
|
||||
/*
|
||||
* GUID definitions of various offer types - services offered to the guest.
|
||||
*/
|
||||
@@ -1021,118 +1023,94 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
* {f8615163-df3e-46c5-913f-f2d2f965ed0e}
|
||||
*/
|
||||
#define HV_NIC_GUID \
|
||||
- .guid = { \
|
||||
- 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \
|
||||
- 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \
|
||||
- }
|
||||
+ .guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \
|
||||
+ 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e)
|
||||
|
||||
/*
|
||||
* IDE GUID
|
||||
* {32412632-86cb-44a2-9b5c-50d1417354f5}
|
||||
*/
|
||||
#define HV_IDE_GUID \
|
||||
- .guid = { \
|
||||
- 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
|
||||
- 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \
|
||||
+ 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
|
||||
|
||||
/*
|
||||
* SCSI GUID
|
||||
* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
|
||||
*/
|
||||
#define HV_SCSI_GUID \
|
||||
- .guid = { \
|
||||
- 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
|
||||
- 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \
|
||||
- }
|
||||
+ .guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \
|
||||
+ 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
|
||||
|
||||
/*
|
||||
* Shutdown GUID
|
||||
* {0e0b6031-5213-4934-818b-38d90ced39db}
|
||||
*/
|
||||
#define HV_SHUTDOWN_GUID \
|
||||
- .guid = { \
|
||||
- 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \
|
||||
- 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \
|
||||
+ 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb)
|
||||
|
||||
/*
|
||||
* Time Synch GUID
|
||||
* {9527E630-D0AE-497b-ADCE-E80AB0175CAF}
|
||||
*/
|
||||
#define HV_TS_GUID \
|
||||
- .guid = { \
|
||||
- 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \
|
||||
- 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \
|
||||
+ 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
|
||||
|
||||
/*
|
||||
* Heartbeat GUID
|
||||
* {57164f39-9115-4e78-ab55-382f3bd5422d}
|
||||
*/
|
||||
#define HV_HEART_BEAT_GUID \
|
||||
- .guid = { \
|
||||
- 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \
|
||||
- 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \
|
||||
+ 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
|
||||
|
||||
/*
|
||||
* KVP GUID
|
||||
* {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}
|
||||
*/
|
||||
#define HV_KVP_GUID \
|
||||
- .guid = { \
|
||||
- 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \
|
||||
- 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \
|
||||
+ 0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6)
|
||||
|
||||
/*
|
||||
* Dynamic memory GUID
|
||||
* {525074dc-8985-46e2-8057-a307dc18a502}
|
||||
*/
|
||||
#define HV_DM_GUID \
|
||||
- .guid = { \
|
||||
- 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \
|
||||
- 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \
|
||||
+ 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
|
||||
|
||||
/*
|
||||
* Mouse GUID
|
||||
* {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}
|
||||
*/
|
||||
#define HV_MOUSE_GUID \
|
||||
- .guid = { \
|
||||
- 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \
|
||||
- 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \
|
||||
- }
|
||||
+ .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \
|
||||
+ 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a)
|
||||
|
||||
/*
|
||||
* VSS (Backup/Restore) GUID
|
||||
*/
|
||||
#define HV_VSS_GUID \
|
||||
- .guid = { \
|
||||
- 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \
|
||||
- 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \
|
||||
+ 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40)
|
||||
/*
|
||||
* Synthetic Video GUID
|
||||
* {DA0A7802-E377-4aac-8E77-0558EB1073F8}
|
||||
*/
|
||||
#define HV_SYNTHVID_GUID \
|
||||
- .guid = { \
|
||||
- 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \
|
||||
- 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \
|
||||
+ 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8)
|
||||
|
||||
/*
|
||||
* Synthetic FC GUID
|
||||
* {2f9bcc4a-0069-4af3-b76b-6fd0be528cda}
|
||||
*/
|
||||
#define HV_SYNTHFC_GUID \
|
||||
- .guid = { \
|
||||
- 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \
|
||||
- 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \
|
||||
+ 0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda)
|
||||
|
||||
/*
|
||||
* Guest File Copy Service
|
||||
@@ -1140,20 +1118,16 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
*/
|
||||
|
||||
#define HV_FCOPY_GUID \
|
||||
- .guid = { \
|
||||
- 0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \
|
||||
- 0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \
|
||||
+ 0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92)
|
||||
|
||||
/*
|
||||
* NetworkDirect. This is the guest RDMA service.
|
||||
* {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}
|
||||
*/
|
||||
#define HV_ND_GUID \
|
||||
- .guid = { \
|
||||
- 0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \
|
||||
- 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \
|
||||
+ 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01)
|
||||
|
||||
/*
|
||||
* PCI Express Pass Through
|
||||
@@ -1161,10 +1135,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
*/
|
||||
|
||||
#define HV_PCIE_GUID \
|
||||
- .guid = { \
|
||||
- 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
|
||||
- 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
|
||||
- }
|
||||
+ .guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \
|
||||
+ 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f)
|
||||
|
||||
/*
|
||||
* Common header for Hyper-V ICs
|
||||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
|
||||
index 64f36e0..6e4c645 100644
|
||||
--- a/include/linux/mod_devicetable.h
|
||||
+++ b/include/linux/mod_devicetable.h
|
||||
@@ -404,7 +404,7 @@ struct virtio_device_id {
|
||||
* For Hyper-V devices we use the device guid as the id.
|
||||
*/
|
||||
struct hv_vmbus_device_id {
|
||||
- __u8 guid[16];
|
||||
+ uuid_le guid;
|
||||
kernel_ulong_t driver_data; /* Data private to the driver */
|
||||
};
|
||||
|
||||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
|
||||
index 5b96206..8adca44 100644
|
||||
--- a/scripts/mod/file2alias.c
|
||||
+++ b/scripts/mod/file2alias.c
|
||||
@@ -917,7 +917,7 @@ static int do_vmbus_entry(const char *filename, void *symval,
|
||||
char guid_name[(sizeof(*guid) + 1) * 2];
|
||||
|
||||
for (i = 0; i < (sizeof(*guid) * 2); i += 2)
|
||||
- sprintf(&guid_name[i], "%02x", TO_NATIVE((*guid)[i/2]));
|
||||
+ sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2]));
|
||||
|
||||
strcpy(alias, "vmbus:");
|
||||
strcat(alias, guid_name);
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,55 @@
|
||||
From d8a7b4073f802509ad00164b1d6967ba9ebb9d7f Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Mon, 14 Dec 2015 16:01:44 -0800
|
||||
Subject: [PATCH 12/40] Drivers: hv: vmbus: Use uuid_le_cmp() for comparing
|
||||
GUIDs
|
||||
|
||||
Use uuid_le_cmp() for comparing GUIDs.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 4ae9250893485f380275e7d5cb291df87c4d9710)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 3 +--
|
||||
drivers/hv/vmbus_drv.c | 4 ++--
|
||||
2 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 38470aa..dc4fb0b 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -408,8 +408,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
|
||||
struct cpumask *alloced_mask;
|
||||
|
||||
for (i = IDE; i < MAX_PERF_CHN; i++) {
|
||||
- if (!memcmp(type_guid->b, &hp_devs[i].guid,
|
||||
- sizeof(uuid_le))) {
|
||||
+ if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) {
|
||||
perf_chn = true;
|
||||
break;
|
||||
}
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index e64934e..aa4d8cc 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -533,7 +533,7 @@ static const uuid_le null_guid;
|
||||
|
||||
static inline bool is_null_guid(const uuid_le *guid)
|
||||
{
|
||||
- if (memcmp(guid, &null_guid, sizeof(uuid_le)))
|
||||
+ if (uuid_le_cmp(*guid, null_guid))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(
|
||||
const uuid_le *guid)
|
||||
{
|
||||
for (; !is_null_guid(&id->guid); id++)
|
||||
- if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
|
||||
+ if (!uuid_le_cmp(id->guid, *guid))
|
||||
return id;
|
||||
|
||||
return NULL;
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From c4795172e48b3229b24b3816c4c0d822c2cd2b88 Mon Sep 17 00:00:00 2001
|
||||
From e24d6e93c8ee5110240547663c88b909fbed3575 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/28] Drivers: hv: vmbus: serialize process_chn_event() and
|
||||
Subject: [PATCH 13/40] Drivers: hv: vmbus: serialize process_chn_event() and
|
||||
vmbus_close_internal()
|
||||
|
||||
process_chn_event(), running in the tasklet, can race with
|
@@ -1,7 +1,7 @@
|
||||
From db7c4decfd08e194c3fe7647ebc0903c5fee33b7 Mon Sep 17 00:00:00 2001
|
||||
From d744926ed8c8f1b717d7ab04adf0d86aa78b1160 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/28] Drivers: hv: vmbus: do sanity check of channel state in
|
||||
Subject: [PATCH 14/40] Drivers: hv: vmbus: do sanity check of channel state in
|
||||
vmbus_close_internal()
|
||||
|
||||
This fixes an incorrect assumption of channel state in the function.
|
@@ -1,7 +1,7 @@
|
||||
From 92aa99cab10f5beb241635eee20fd1709fb63196 Mon Sep 17 00:00:00 2001
|
||||
From ae5614842c1b80193552aeabb57f6cc37c5ca848 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/28] Drivers: hv: vmbus: fix rescind-offer handling for
|
||||
Subject: [PATCH 15/40] Drivers: hv: vmbus: fix rescind-offer handling for
|
||||
device without a driver
|
||||
|
||||
In the path vmbus_onoffer_rescind() -> vmbus_device_unregister() ->
|
||||
@@ -55,7 +55,7 @@ index b3c14ca..2889d97 100644
|
||||
tasklet_enable(tasklet);
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 652afd1..bd2e9f6 100644
|
||||
index dc4fb0b..7903acc 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)
|
||||
@@ -79,7 +79,7 @@ index 652afd1..bd2e9f6 100644
|
||||
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index f19b6f7..7e46a48 100644
|
||||
index aa4d8cc..5a71b2a 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)
|
@@ -1,7 +1,7 @@
|
||||
From c0e232b85b7cf4387788962085fed314e01b5e8c Mon Sep 17 00:00:00 2001
|
||||
From 28d0ed01c7b183c6af5991351de65046c183f392 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/28] Drivers: hv: vmbus: release relid on error in
|
||||
Subject: [PATCH 16/40] Drivers: hv: vmbus: release relid on error in
|
||||
vmbus_process_offer()
|
||||
|
||||
We want to simplify vmbus_onoffer_rescind() by not invoking
|
||||
@@ -16,7 +16,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
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
|
||||
index 7903acc..9c9da3a 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -177,19 +177,22 @@ static void percpu_channel_deq(void *arg)
|
||||
@@ -56,7 +56,7 @@ index bd2e9f6..df76a71 100644
|
||||
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)
|
||||
@@ -587,7 +592,11 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
channel = relid2channel(rescind->child_relid);
|
||||
|
||||
if (channel == NULL) {
|
@@ -1,7 +1,7 @@
|
||||
From 2991041546570f369440c4837ae5ef0518e4d839 Mon Sep 17 00:00:00 2001
|
||||
From 9aa8a05fcf39739b23f8e2f502c3ffa370521cba 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/28] Drivers: hv: vmbus: channge
|
||||
Subject: [PATCH 17/40] Drivers: hv: vmbus: channge
|
||||
vmbus_connection.channel_lock to mutex
|
||||
|
||||
spinlock is unnecessary here.
|
||||
@@ -18,7 +18,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
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
|
||||
index 9c9da3a..d013171 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)
|
@@ -0,0 +1,126 @@
|
||||
From 86e233fbb4c41b03096f498b26cdbfbdf9e5723e Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Mon, 14 Dec 2015 19:02:00 -0800
|
||||
Subject: [PATCH 18/40] Drivers: hv: remove code duplication between
|
||||
vmbus_recvpacket()/vmbus_recvpacket_raw()
|
||||
|
||||
vmbus_recvpacket() and vmbus_recvpacket_raw() are almost identical but
|
||||
there are two discrepancies:
|
||||
1) vmbus_recvpacket() doesn't propagate errors from hv_ringbuffer_read()
|
||||
which looks like it is not desired.
|
||||
2) There is an error message printed in packetlen > bufferlen case in
|
||||
vmbus_recvpacket(). I'm removing it as it is usless for users to see
|
||||
such messages and /vmbus_recvpacket_raw() doesn't have it.
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 667d374064b0cc48b6122101b287908d1b392bdb)
|
||||
---
|
||||
drivers/hv/channel.c | 65 ++++++++++++++++++----------------------------------
|
||||
1 file changed, 22 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 2889d97..dd6de7f 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -922,8 +922,10 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
-int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
- u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
|
||||
+static inline int
|
||||
+__vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
+ u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
|
||||
+ bool raw)
|
||||
{
|
||||
struct vmpacket_descriptor desc;
|
||||
u32 packetlen;
|
||||
@@ -941,27 +943,34 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
return 0;
|
||||
|
||||
packetlen = desc.len8 << 3;
|
||||
- userlen = packetlen - (desc.offset8 << 3);
|
||||
+ if (!raw)
|
||||
+ userlen = packetlen - (desc.offset8 << 3);
|
||||
+ else
|
||||
+ userlen = packetlen;
|
||||
|
||||
*buffer_actual_len = userlen;
|
||||
|
||||
- if (userlen > bufferlen) {
|
||||
-
|
||||
- pr_err("Buffer too small - got %d needs %d\n",
|
||||
- bufferlen, userlen);
|
||||
- return -ETOOSMALL;
|
||||
- }
|
||||
+ if (userlen > bufferlen)
|
||||
+ return -ENOBUFS;
|
||||
|
||||
*requestid = desc.trans_id;
|
||||
|
||||
/* Copy over the packet to the user buffer */
|
||||
ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
|
||||
- (desc.offset8 << 3), &signal);
|
||||
+ raw ? 0 : desc.offset8 << 3, &signal);
|
||||
|
||||
if (signal)
|
||||
vmbus_setevent(channel);
|
||||
|
||||
- return 0;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
+ u32 bufferlen, u32 *buffer_actual_len,
|
||||
+ u64 *requestid)
|
||||
+{
|
||||
+ return __vmbus_recvpacket(channel, buffer, bufferlen,
|
||||
+ buffer_actual_len, requestid, false);
|
||||
}
|
||||
EXPORT_SYMBOL(vmbus_recvpacket);
|
||||
|
||||
@@ -972,37 +981,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
u32 bufferlen, u32 *buffer_actual_len,
|
||||
u64 *requestid)
|
||||
{
|
||||
- struct vmpacket_descriptor desc;
|
||||
- u32 packetlen;
|
||||
- int ret;
|
||||
- bool signal = false;
|
||||
-
|
||||
- *buffer_actual_len = 0;
|
||||
- *requestid = 0;
|
||||
-
|
||||
-
|
||||
- ret = hv_ringbuffer_peek(&channel->inbound, &desc,
|
||||
- sizeof(struct vmpacket_descriptor));
|
||||
- if (ret != 0)
|
||||
- return 0;
|
||||
-
|
||||
-
|
||||
- packetlen = desc.len8 << 3;
|
||||
-
|
||||
- *buffer_actual_len = packetlen;
|
||||
-
|
||||
- if (packetlen > bufferlen)
|
||||
- return -ENOBUFS;
|
||||
-
|
||||
- *requestid = desc.trans_id;
|
||||
-
|
||||
- /* Copy over the entire packet to the user buffer */
|
||||
- ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0,
|
||||
- &signal);
|
||||
-
|
||||
- if (signal)
|
||||
- vmbus_setevent(channel);
|
||||
-
|
||||
- return ret;
|
||||
+ return __vmbus_recvpacket(channel, buffer, bufferlen,
|
||||
+ buffer_actual_len, requestid, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,72 @@
|
||||
From 934477d473ecb1facd9f69cfc4b4591598f3b0ed Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 21 Dec 2015 12:21:22 -0800
|
||||
Subject: [PATCH 19/40] Drivers: hv: vmbus: fix the building warning with
|
||||
hyperv-keyboard
|
||||
|
||||
With the recent change af3ff643ea91ba64dd8d0b1cbed54d44512f96cd
|
||||
(Drivers: hv: vmbus: Use uuid_le type consistently), we always get this
|
||||
warning:
|
||||
|
||||
CC [M] drivers/input/serio/hyperv-keyboard.o
|
||||
drivers/input/serio/hyperv-keyboard.c:427:2: warning: missing braces around
|
||||
initializer [-Wmissing-braces]
|
||||
{ HV_KBD_GUID, },
|
||||
^
|
||||
drivers/input/serio/hyperv-keyboard.c:427:2: warning: (near initialization
|
||||
for .id_table[0].guid.b.) [-Wmissing-braces]
|
||||
|
||||
The patch fixes the warning.
|
||||
|
||||
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 2048157ad02e65f6327118dd4a7b9c9f1fd12f77)
|
||||
---
|
||||
drivers/input/serio/hyperv-keyboard.c | 10 ----------
|
||||
include/linux/hyperv.h | 8 ++++++++
|
||||
2 files changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
|
||||
index e74e5d6..c948866 100644
|
||||
--- a/drivers/input/serio/hyperv-keyboard.c
|
||||
+++ b/drivers/input/serio/hyperv-keyboard.c
|
||||
@@ -412,16 +412,6 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Keyboard GUID
|
||||
- * {f912ad6d-2b17-48ea-bd65-f927a61c7684}
|
||||
- */
|
||||
-#define HV_KBD_GUID \
|
||||
- .guid = { \
|
||||
- 0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \
|
||||
- 0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \
|
||||
- }
|
||||
-
|
||||
static const struct hv_vmbus_device_id id_table[] = {
|
||||
/* Keyboard guid */
|
||||
{ HV_KBD_GUID, },
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 4712d7d..9e2de6a 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1091,6 +1091,14 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
|
||||
0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a)
|
||||
|
||||
/*
|
||||
+ * Keyboard GUID
|
||||
+ * {f912ad6d-2b17-48ea-bd65-f927a61c7684}
|
||||
+ */
|
||||
+#define HV_KBD_GUID \
|
||||
+ .guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \
|
||||
+ 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84)
|
||||
+
|
||||
+/*
|
||||
* VSS (Backup/Restore) GUID
|
||||
*/
|
||||
#define HV_VSS_GUID \
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,42 @@
|
||||
From e952f2c22a0a2dbf6b56f732ce265aa6c9f461b2 Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Tue, 15 Dec 2015 16:27:27 -0800
|
||||
Subject: [PATCH 20/40] Drivers: hv: vmbus: Treat Fibre Channel devices as
|
||||
performance critical
|
||||
|
||||
For performance critical devices, we distribute the incoming
|
||||
channel interrupt load across available CPUs in the guest.
|
||||
Include Fibre channel devices in the set of devices for which
|
||||
we would distribute the interrupt load.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 879a650a273bc3efb9d472886b8ced12630ea8ed)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index d013171..1c1ad47 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -361,6 +361,7 @@ err_free_chan:
|
||||
enum {
|
||||
IDE = 0,
|
||||
SCSI,
|
||||
+ FC,
|
||||
NIC,
|
||||
ND_NIC,
|
||||
PCIE,
|
||||
@@ -377,6 +378,8 @@ static const struct hv_vmbus_device_id hp_devs[] = {
|
||||
{ HV_IDE_GUID, },
|
||||
/* Storage - SCSI */
|
||||
{ HV_SCSI_GUID, },
|
||||
+ /* Storage - FC */
|
||||
+ { HV_SYNTHFC_GUID, },
|
||||
/* Network */
|
||||
{ HV_NIC_GUID, },
|
||||
/* NetworkDirect Guest RDMA */
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,355 @@
|
||||
From cd2ba91482cea0e0979336c7e174224c39ab4537 Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Fri, 25 Dec 2015 20:00:30 -0800
|
||||
Subject: [PATCH 21/40] Drivers: hv: vmbus: Add vendor and device atttributes
|
||||
|
||||
Add vendor and device attributes to VMBUS devices. These will be used
|
||||
by Hyper-V tools as well user-level RDMA libraries that will use the
|
||||
vendor/device tuple to discover the RDMA device.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 7047f17d70fc0599563d30d0791692cb5fe42ae6)
|
||||
---
|
||||
Documentation/ABI/stable/sysfs-bus-vmbus | 14 +++
|
||||
drivers/hv/channel_mgmt.c | 166 +++++++++++++++++++++++--------
|
||||
drivers/hv/vmbus_drv.c | 21 ++++
|
||||
include/linux/hyperv.h | 28 ++++++
|
||||
4 files changed, 186 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus
|
||||
index 636e938..5d0125f 100644
|
||||
--- a/Documentation/ABI/stable/sysfs-bus-vmbus
|
||||
+++ b/Documentation/ABI/stable/sysfs-bus-vmbus
|
||||
@@ -27,3 +27,17 @@ Description: The mapping of which primary/sub channels are bound to which
|
||||
Virtual Processors.
|
||||
Format: <channel's child_relid:the bound cpu's number>
|
||||
Users: tools/hv/lsvmbus
|
||||
+
|
||||
+What: /sys/bus/vmbus/devices/vmbus_*/device
|
||||
+Date: Dec. 2015
|
||||
+KernelVersion: 4.5
|
||||
+Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
+Description: The 16 bit device ID of the device
|
||||
+Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||
+
|
||||
+What: /sys/bus/vmbus/devices/vmbus_*/vendor
|
||||
+Date: Dec. 2015
|
||||
+KernelVersion: 4.5
|
||||
+Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
+Description: The 16 bit vendor ID of the device
|
||||
+Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 1c1ad47..107d72f 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -32,8 +32,122 @@
|
||||
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
-static void init_vp_index(struct vmbus_channel *channel,
|
||||
- const uuid_le *type_guid);
|
||||
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type);
|
||||
+
|
||||
+static const struct vmbus_device vmbus_devs[] = {
|
||||
+ /* IDE */
|
||||
+ { .dev_type = HV_IDE,
|
||||
+ HV_IDE_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* SCSI */
|
||||
+ { .dev_type = HV_SCSI,
|
||||
+ HV_SCSI_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* Fibre Channel */
|
||||
+ { .dev_type = HV_FC,
|
||||
+ HV_SYNTHFC_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* Synthetic NIC */
|
||||
+ { .dev_type = HV_NIC,
|
||||
+ HV_NIC_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* Network Direct */
|
||||
+ { .dev_type = HV_ND,
|
||||
+ HV_ND_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* PCIE */
|
||||
+ { .dev_type = HV_PCIE,
|
||||
+ HV_PCIE_GUID,
|
||||
+ .perf_device = true,
|
||||
+ },
|
||||
+
|
||||
+ /* Synthetic Frame Buffer */
|
||||
+ { .dev_type = HV_FB,
|
||||
+ HV_SYNTHVID_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Synthetic Keyboard */
|
||||
+ { .dev_type = HV_KBD,
|
||||
+ HV_KBD_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Synthetic MOUSE */
|
||||
+ { .dev_type = HV_MOUSE,
|
||||
+ HV_MOUSE_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* KVP */
|
||||
+ { .dev_type = HV_KVP,
|
||||
+ HV_KVP_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Time Synch */
|
||||
+ { .dev_type = HV_TS,
|
||||
+ HV_TS_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Heartbeat */
|
||||
+ { .dev_type = HV_HB,
|
||||
+ HV_HEART_BEAT_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Shutdown */
|
||||
+ { .dev_type = HV_SHUTDOWN,
|
||||
+ HV_SHUTDOWN_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* File copy */
|
||||
+ { .dev_type = HV_FCOPY,
|
||||
+ HV_FCOPY_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Backup */
|
||||
+ { .dev_type = HV_BACKUP,
|
||||
+ HV_VSS_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Dynamic Memory */
|
||||
+ { .dev_type = HV_DM,
|
||||
+ HV_DM_GUID,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+
|
||||
+ /* Unknown GUID */
|
||||
+ { .dev_type = HV_UNKOWN,
|
||||
+ .perf_device = false,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static u16 hv_get_dev_type(const uuid_le *guid)
|
||||
+{
|
||||
+ u16 i;
|
||||
+
|
||||
+ for (i = HV_IDE; i < HV_UNKOWN; i++) {
|
||||
+ if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
|
||||
+ return i;
|
||||
+ }
|
||||
+ pr_info("Unknown GUID: %pUl\n", guid);
|
||||
+ return i;
|
||||
+}
|
||||
|
||||
/**
|
||||
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||
@@ -251,6 +365,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
struct vmbus_channel *channel;
|
||||
bool fnew = true;
|
||||
unsigned long flags;
|
||||
+ u16 dev_type;
|
||||
|
||||
/* Make sure this is a new offer */
|
||||
mutex_lock(&vmbus_connection.channel_mutex);
|
||||
@@ -288,7 +403,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
goto err_free_chan;
|
||||
}
|
||||
|
||||
- init_vp_index(newchannel, &newchannel->offermsg.offer.if_type);
|
||||
+ dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type);
|
||||
+
|
||||
+ init_vp_index(newchannel, dev_type);
|
||||
|
||||
if (newchannel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
@@ -325,6 +442,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
if (!newchannel->device_obj)
|
||||
goto err_deq_chan;
|
||||
|
||||
+ newchannel->device_obj->device_id = dev_type;
|
||||
/*
|
||||
* Add the new device to the bus. This will kick off device-driver
|
||||
* binding which eventually invokes the device driver's AddDevice()
|
||||
@@ -358,37 +476,6 @@ err_free_chan:
|
||||
free_channel(newchannel);
|
||||
}
|
||||
|
||||
-enum {
|
||||
- IDE = 0,
|
||||
- SCSI,
|
||||
- FC,
|
||||
- NIC,
|
||||
- ND_NIC,
|
||||
- PCIE,
|
||||
- MAX_PERF_CHN,
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * This is an array of device_ids (device types) that are performance critical.
|
||||
- * We attempt to distribute the interrupt load for these devices across
|
||||
- * all available CPUs.
|
||||
- */
|
||||
-static const struct hv_vmbus_device_id hp_devs[] = {
|
||||
- /* IDE */
|
||||
- { HV_IDE_GUID, },
|
||||
- /* Storage - SCSI */
|
||||
- { HV_SCSI_GUID, },
|
||||
- /* Storage - FC */
|
||||
- { HV_SYNTHFC_GUID, },
|
||||
- /* Network */
|
||||
- { HV_NIC_GUID, },
|
||||
- /* NetworkDirect Guest RDMA */
|
||||
- { HV_ND_GUID, },
|
||||
- /* PCI Express Pass Through */
|
||||
- { HV_PCIE_GUID, },
|
||||
-};
|
||||
-
|
||||
-
|
||||
/*
|
||||
* We use this state to statically distribute the channel interrupt load.
|
||||
*/
|
||||
@@ -405,22 +492,15 @@ static int next_numa_node_id;
|
||||
* For pre-win8 hosts or non-performance critical channels we assign the
|
||||
* first CPU in the first NUMA node.
|
||||
*/
|
||||
-static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid)
|
||||
+static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
||||
{
|
||||
u32 cur_cpu;
|
||||
- int i;
|
||||
- bool perf_chn = false;
|
||||
+ bool perf_chn = vmbus_devs[dev_type].perf_device;
|
||||
struct vmbus_channel *primary = channel->primary_channel;
|
||||
int next_node;
|
||||
struct cpumask available_mask;
|
||||
struct cpumask *alloced_mask;
|
||||
|
||||
- for (i = IDE; i < MAX_PERF_CHN; i++) {
|
||||
- if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) {
|
||||
- perf_chn = true;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
if ((vmbus_proto_version == VERSION_WS2008) ||
|
||||
(vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
|
||||
/*
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index 5a71b2a..3b83dfe 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -478,6 +478,24 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR_RO(channel_vp_mapping);
|
||||
|
||||
+static ssize_t vendor_show(struct device *dev,
|
||||
+ struct device_attribute *dev_attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct hv_device *hv_dev = device_to_hv_device(dev);
|
||||
+ return sprintf(buf, "0x%x\n", hv_dev->vendor_id);
|
||||
+}
|
||||
+static DEVICE_ATTR_RO(vendor);
|
||||
+
|
||||
+static ssize_t device_show(struct device *dev,
|
||||
+ struct device_attribute *dev_attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct hv_device *hv_dev = device_to_hv_device(dev);
|
||||
+ return sprintf(buf, "0x%x\n", hv_dev->device_id);
|
||||
+}
|
||||
+static DEVICE_ATTR_RO(device);
|
||||
+
|
||||
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
|
||||
static struct attribute *vmbus_attrs[] = {
|
||||
&dev_attr_id.attr,
|
||||
@@ -503,6 +521,8 @@ static struct attribute *vmbus_attrs[] = {
|
||||
&dev_attr_in_read_bytes_avail.attr,
|
||||
&dev_attr_in_write_bytes_avail.attr,
|
||||
&dev_attr_channel_vp_mapping.attr,
|
||||
+ &dev_attr_vendor.attr,
|
||||
+ &dev_attr_device.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(vmbus);
|
||||
@@ -957,6 +977,7 @@ struct hv_device *vmbus_device_create(const uuid_le *type,
|
||||
memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
|
||||
memcpy(&child_device_obj->dev_instance, instance,
|
||||
sizeof(uuid_le));
|
||||
+ child_device_obj->vendor_id = 0x1414; /* MSFT vendor ID */
|
||||
|
||||
|
||||
return child_device_obj;
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 9e2de6a..51c98fd 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -635,6 +635,32 @@ enum hv_signal_policy {
|
||||
HV_SIGNAL_POLICY_EXPLICIT,
|
||||
};
|
||||
|
||||
+enum vmbus_device_type {
|
||||
+ HV_IDE = 0,
|
||||
+ HV_SCSI,
|
||||
+ HV_FC,
|
||||
+ HV_NIC,
|
||||
+ HV_ND,
|
||||
+ HV_PCIE,
|
||||
+ HV_FB,
|
||||
+ HV_KBD,
|
||||
+ HV_MOUSE,
|
||||
+ HV_KVP,
|
||||
+ HV_TS,
|
||||
+ HV_HB,
|
||||
+ HV_SHUTDOWN,
|
||||
+ HV_FCOPY,
|
||||
+ HV_BACKUP,
|
||||
+ HV_DM,
|
||||
+ HV_UNKOWN,
|
||||
+};
|
||||
+
|
||||
+struct vmbus_device {
|
||||
+ u16 dev_type;
|
||||
+ uuid_le guid;
|
||||
+ bool perf_device;
|
||||
+};
|
||||
+
|
||||
struct vmbus_channel {
|
||||
/* Unique channel id */
|
||||
int id;
|
||||
@@ -961,6 +987,8 @@ struct hv_device {
|
||||
|
||||
/* the device instance id of this device */
|
||||
uuid_le dev_instance;
|
||||
+ u16 vendor_id;
|
||||
+ u16 device_id;
|
||||
|
||||
struct device device;
|
||||
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,49 @@
|
||||
From 38a40857bb22894545830b22fb593241f2fabf4d Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:34 -0800
|
||||
Subject: [PATCH 22/40] Drivers: hv: vmbus: avoid infinite loop in
|
||||
init_vp_index()
|
||||
|
||||
When we pick a CPU to use for a new subchannel we try find a non-used one
|
||||
on the appropriate NUMA node, we keep track of them with the
|
||||
primary->alloced_cpus_in_node mask. Under normal circumstances we don't run
|
||||
out of available CPUs but it is possible when we we don't initialize some
|
||||
cpus in Linux, e.g. when we boot with 'nr_cpus=' limitation.
|
||||
|
||||
Avoid the infinite loop in init_vp_index() by checking that we still have
|
||||
non-used CPUs in the alloced_cpus_in_node mask and resetting it in case
|
||||
we don't.
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 79fd8e706637a5c7c41f9498fe0fbfb437abfdc8)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 107d72f..af1d82e 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -549,6 +549,17 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
||||
cpumask_of_node(primary->numa_node));
|
||||
|
||||
cur_cpu = -1;
|
||||
+
|
||||
+ /*
|
||||
+ * Normally Hyper-V host doesn't create more subchannels than there
|
||||
+ * are VCPUs on the node but it is possible when not all present VCPUs
|
||||
+ * on the node are initialized by guest. Clear the alloced_cpus_in_node
|
||||
+ * to start over.
|
||||
+ */
|
||||
+ if (cpumask_equal(&primary->alloced_cpus_in_node,
|
||||
+ cpumask_of_node(primary->numa_node)))
|
||||
+ cpumask_clear(&primary->alloced_cpus_in_node);
|
||||
+
|
||||
while (true) {
|
||||
cur_cpu = cpumask_next(cur_cpu, &available_mask);
|
||||
if (cur_cpu >= nr_cpu_ids) {
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,99 @@
|
||||
From 22945cbc393c06b0b55c553623b595fc1e6d2598 Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:35 -0800
|
||||
Subject: [PATCH 23/40] Drivers: hv: vmbus: avoid scheduling in interrupt
|
||||
context in vmbus_initiate_unload()
|
||||
|
||||
We have to call vmbus_initiate_unload() on crash to make kdump work but
|
||||
the crash can also be happening in interrupt (e.g. Sysrq + c results in
|
||||
such) where we can't schedule or the following will happen:
|
||||
|
||||
[ 314.905786] bad: scheduling from the idle thread!
|
||||
|
||||
Just skipping the wait (and even adding some random wait here) won't help:
|
||||
to make host-side magic working we're supposed to receive CHANNELMSG_UNLOAD
|
||||
(and actually confirm the fact that we received it) but we can't use
|
||||
interrupt-base path (vmbus_isr()-> vmbus_on_msg_dpc()). Implement a simple
|
||||
busy wait ignoring all the other messages and use it if we're in an
|
||||
interrupt context.
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 415719160de3fae3bb9cbc617664649919cd00d0)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 43 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index af1d82e..d6c6114 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/completion.h>
|
||||
+#include <linux/delay.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv_vmbus.h"
|
||||
@@ -589,6 +590,40 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
||||
channel->target_vp = hv_context.vp_index[cur_cpu];
|
||||
}
|
||||
|
||||
+static void vmbus_wait_for_unload(void)
|
||||
+{
|
||||
+ int cpu = smp_processor_id();
|
||||
+ void *page_addr = hv_context.synic_message_page[cpu];
|
||||
+ struct hv_message *msg = (struct hv_message *)page_addr +
|
||||
+ VMBUS_MESSAGE_SINT;
|
||||
+ struct vmbus_channel_message_header *hdr;
|
||||
+ bool unloaded = false;
|
||||
+
|
||||
+ while (1) {
|
||||
+ if (msg->header.message_type == HVMSG_NONE) {
|
||||
+ mdelay(10);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ hdr = (struct vmbus_channel_message_header *)msg->u.payload;
|
||||
+ if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE)
|
||||
+ unloaded = true;
|
||||
+
|
||||
+ msg->header.message_type = HVMSG_NONE;
|
||||
+ /*
|
||||
+ * header.message_type needs to be written before we do
|
||||
+ * wrmsrl() below.
|
||||
+ */
|
||||
+ mb();
|
||||
+
|
||||
+ if (msg->header.message_flags.msg_pending)
|
||||
+ wrmsrl(HV_X64_MSR_EOM, 0);
|
||||
+
|
||||
+ if (unloaded)
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* vmbus_unload_response - Handler for the unload response.
|
||||
*/
|
||||
@@ -614,7 +649,14 @@ void vmbus_initiate_unload(void)
|
||||
hdr.msgtype = CHANNELMSG_UNLOAD;
|
||||
vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
|
||||
|
||||
- wait_for_completion(&vmbus_connection.unload_event);
|
||||
+ /*
|
||||
+ * vmbus_initiate_unload() is also called on crash and the crash can be
|
||||
+ * happening in an interrupt context, where scheduling is impossible.
|
||||
+ */
|
||||
+ if (!in_interrupt())
|
||||
+ wait_for_completion(&vmbus_connection.unload_event);
|
||||
+ else
|
||||
+ vmbus_wait_for_unload();
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 38bad476ce53b8b305d5629cfa5fe013c82f5a97 Mon Sep 17 00:00:00 2001
|
||||
From 73d794b62769667baebc92515da11aa2ef687bf3 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/28] Drivers: hv: vmbus: add a helper function to set a
|
||||
Subject: [PATCH 24/40] 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.
|
||||
@@ -15,10 +15,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index ae6a711..fda6310 100644
|
||||
index 51c98fd..934542a 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)
|
||||
@@ -818,6 +818,12 @@ static inline void *get_per_channel_state(struct vmbus_channel *c)
|
||||
return c->per_channel_state;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 34e3731c0ba650cc5e7c15517da15f76e438b031 Mon Sep 17 00:00:00 2001
|
||||
From 57b533b03fea1344ff846c76738cd919678778c1 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/28] Drivers: hv: vmbus: define the new offer type for
|
||||
Subject: [PATCH 25/40] Drivers: hv: vmbus: define the new offer type for
|
||||
Hyper-V socket (hvsock)
|
||||
|
||||
A helper function is also added.
|
||||
@@ -15,7 +15,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index fda6310..9fb2130 100644
|
||||
index 934542a..a4f105d 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -237,6 +237,7 @@ struct vmbus_channel_offer {
|
||||
@@ -26,7 +26,7 @@ index fda6310..9fb2130 100644
|
||||
|
||||
struct vmpacket_descriptor {
|
||||
u16 type;
|
||||
@@ -771,6 +772,12 @@ struct vmbus_channel {
|
||||
@@ -797,6 +798,12 @@ struct vmbus_channel {
|
||||
enum hv_signal_policy signal_policy;
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 53e57822a7f9d6c6fc221c21cfbbe9da2965c059 Mon Sep 17 00:00:00 2001
|
||||
From 3f1df935d1b5caad3f00a43eb50714375bc32547 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/28] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid
|
||||
Subject: [PATCH 26/40] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid
|
||||
unnecessary signaling
|
||||
|
||||
When the hvsock channel's outbound ringbuffer is full (i.e.,
|
||||
@@ -17,7 +17,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 2889d97..a7f9e3e 100644
|
||||
index dd6de7f..128dcf2 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,
|
@@ -1,7 +1,7 @@
|
||||
From 7e8defd74db9d20fc2c1b98946f5f1e5ad96e33c Mon Sep 17 00:00:00 2001
|
||||
From 75650dcb326987e017209a61107f341447a88de5 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/28] Drivers: hv: vmbus: define a new VMBus message type for
|
||||
Subject: [PATCH 27/40] Drivers: hv: vmbus: define a new VMBus message type for
|
||||
hvsock
|
||||
|
||||
A function to send the type of message is also added.
|
||||
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
3 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index a7f9e3e..239b072 100644
|
||||
index 128dcf2..415f6c7 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -219,6 +219,21 @@ error0:
|
||||
@@ -46,10 +46,10 @@ index a7f9e3e..239b072 100644
|
||||
* 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
|
||||
index d6c6114..60ca25b 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -820,6 +820,10 @@ struct vmbus_channel_message_table_entry
|
||||
@@ -958,6 +958,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},
|
||||
@@ -61,7 +61,7 @@ index bd4f084..4d61f41 100644
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 9fb2130..3f485a4 100644
|
||||
index a4f105d..191bc5d 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -394,6 +394,10 @@ enum vmbus_channel_message_type {
|
||||
@@ -89,7 +89,7 @@ index 9fb2130..3f485a4 100644
|
||||
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);
|
||||
@@ -1295,4 +1306,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||
|
||||
extern __u32 vmbus_proto_version;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 1d19451adec149cefc135c442b4cb2241d87607a Mon Sep 17 00:00:00 2001
|
||||
From f32ca7e520ca07ec5294e852248522c3ac0d145f 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/28] Drivers: hv: vmbus: add a hvsock flag in struct
|
||||
Subject: [PATCH 28/40] Drivers: hv: vmbus: add a hvsock flag in struct
|
||||
hv_driver
|
||||
|
||||
Only the coming hv_sock driver has a "true" value for this flag.
|
||||
@@ -20,10 +20,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index 7e46a48..7d607ad 100644
|
||||
index 3b83dfe..d76a65f 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)
|
||||
@@ -583,6 +583,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);
|
||||
|
||||
@@ -31,14 +31,14 @@ index 7e46a48..7d607ad 100644
|
||||
+ if (is_hvsock_channel(hv_dev->channel))
|
||||
+ return drv->hvsock;
|
||||
+
|
||||
if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
|
||||
if (hv_vmbus_get_id(drv->id_table, &hv_dev->dev_type))
|
||||
return 1;
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 3f485a4..9ee79af 100644
|
||||
index 191bc5d..05966e2 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -966,6 +966,20 @@ extern void vmbus_ontimer(unsigned long data);
|
||||
@@ -992,6 +992,20 @@ extern void vmbus_ontimer(unsigned long data);
|
||||
struct hv_driver {
|
||||
const char *name;
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From 89a360504f1683d1be642506a14c9f59ea2c9771 Mon Sep 17 00:00:00 2001
|
||||
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
|
||||
Date: Sun, 15 May 2016 10:56:16 +0100
|
||||
Subject: [PATCH 28/28] hv_sock: Don't touch the socket state when the other
|
||||
end closes
|
||||
|
||||
This cause a NULL pointer de-reference when the client closes the connection
|
||||
before accept() is called by the server.
|
||||
|
||||
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@gmail.com>
|
||||
---
|
||||
net/hv_sock/af_hvsock.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/net/hv_sock/af_hvsock.c b/net/hv_sock/af_hvsock.c
|
||||
index 013d684..0b7ab8a 100644
|
||||
--- a/net/hv_sock/af_hvsock.c
|
||||
+++ b/net/hv_sock/af_hvsock.c
|
||||
@@ -616,7 +616,6 @@ static void hvsock_close_connection(struct vmbus_channel *channel)
|
||||
if (!sk)
|
||||
goto out;
|
||||
|
||||
- sk->sk_socket->state = SS_UNCONNECTED;
|
||||
sk->sk_state = SS_UNCONNECTED;
|
||||
sock_set_flag(sk, SOCK_DONE);
|
||||
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 14935b1d81d62a8aee055d8b762a745338e445b2 Mon Sep 17 00:00:00 2001
|
||||
From 91bc38269cbba8c6ffc4db837f22267f72cfcd35 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/28] Drivers: hv: vmbus: add a per-channel rescind callback
|
||||
Subject: [PATCH 29/40] Drivers: hv: vmbus: add a per-channel rescind callback
|
||||
|
||||
This will be used by the coming hv_sock driver.
|
||||
|
||||
@@ -15,10 +15,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 4d61f41..421e3dd 100644
|
||||
index 60ca25b..76864c9 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)
|
||||
@@ -741,6 +741,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
spin_unlock_irqrestore(&channel->lock, flags);
|
||||
|
||||
if (channel->device_obj) {
|
||||
@@ -29,7 +29,7 @@ index 4d61f41..421e3dd 100644
|
||||
/*
|
||||
* We will have to unregister this device from the
|
||||
* driver core.
|
||||
@@ -972,3 +976,10 @@ bool vmbus_are_subchannels_present(struct vmbus_channel *primary)
|
||||
@@ -1110,3 +1114,10 @@ bool vmbus_are_subchannels_present(struct vmbus_channel *primary)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);
|
||||
@@ -41,10 +41,10 @@ index 4d61f41..421e3dd 100644
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(vmbus_set_chn_rescind_callback);
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 9ee79af..09e9ec1 100644
|
||||
index 05966e2..ad04017 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -742,6 +742,12 @@ struct vmbus_channel {
|
||||
@@ -768,6 +768,12 @@ struct vmbus_channel {
|
||||
void (*sc_creation_callback)(struct vmbus_channel *new_sc);
|
||||
|
||||
/*
|
||||
@@ -57,7 +57,7 @@ index 9ee79af..09e9ec1 100644
|
||||
* 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);
|
||||
@@ -853,6 +859,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));
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 080b343d4e73684e9c261350703a48771eeda231 Mon Sep 17 00:00:00 2001
|
||||
From 5ffa6fad55eaaa00feecefe483a7eb3aba155ae9 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/28] Drivers: hv: vmbus: add an API
|
||||
Subject: [PATCH 30/40] Drivers: hv: vmbus: add an API
|
||||
vmbus_hvsock_device_unregister()
|
||||
|
||||
The hvsock driver needs this API to release all the resources related
|
||||
@@ -18,10 +18,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
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
|
||||
index 76864c9..cf311be 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)
|
||||
@@ -310,6 +310,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
vmbus_release_relid(relid);
|
||||
|
||||
BUG_ON(!channel->rescind);
|
||||
@@ -29,7 +29,7 @@ index 421e3dd..0fe9665 100644
|
||||
|
||||
if (channel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
@@ -206,9 +207,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
@@ -321,9 +322,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
}
|
||||
|
||||
if (channel->primary_channel == NULL) {
|
||||
@@ -39,15 +39,15 @@ index 421e3dd..0fe9665 100644
|
||||
|
||||
primary_channel = channel;
|
||||
} else {
|
||||
@@ -251,6 +250,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
struct vmbus_channel *channel;
|
||||
@@ -367,6 +366,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
bool fnew = true;
|
||||
unsigned long flags;
|
||||
u16 dev_type;
|
||||
+ 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)
|
||||
@@ -449,7 +449,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
* binding which eventually invokes the device driver's AddDevice()
|
||||
* method.
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ index 421e3dd..0fe9665 100644
|
||||
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)
|
||||
@@ -725,6 +729,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
struct device *dev;
|
||||
|
||||
rescind = (struct vmbus_channel_rescind_offer *)hdr;
|
||||
@@ -69,7 +69,7 @@ index 421e3dd..0fe9665 100644
|
||||
channel = relid2channel(rescind->child_relid);
|
||||
|
||||
if (channel == NULL) {
|
||||
@@ -595,7 +601,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
@@ -733,7 +739,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
* vmbus_process_offer(), we have already invoked
|
||||
* vmbus_release_relid() on error.
|
||||
*/
|
||||
@@ -78,7 +78,7 @@ index 421e3dd..0fe9665 100644
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&channel->lock, flags);
|
||||
@@ -605,7 +611,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
@@ -743,7 +749,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);
|
||||
@@ -87,7 +87,7 @@ index 421e3dd..0fe9665 100644
|
||||
}
|
||||
/*
|
||||
* We will have to unregister this device from the
|
||||
@@ -620,8 +626,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
@@ -758,8 +764,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
hv_process_channel_removal(channel,
|
||||
channel->offermsg.child_relid);
|
||||
}
|
||||
@@ -136,10 +136,10 @@ index 521f48e..09c08b5 100644
|
||||
return found_channel;
|
||||
}
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 09e9ec1..af7ee0a 100644
|
||||
index ad04017..993318a 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,
|
||||
@@ -1071,6 +1071,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);
|
||||
|
@@ -0,0 +1,208 @@
|
||||
From e648c3f4c7a150cec1c794037af051c671358d18 Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Wed, 27 Jan 2016 22:29:45 -0800
|
||||
Subject: [PATCH 31/40] Drivers: hv: vmbus: Give control over how the ring
|
||||
access is serialized
|
||||
|
||||
On the channel send side, many of the VMBUS
|
||||
device drivers explicity serialize access to the
|
||||
outgoing ring buffer. Give more control to the
|
||||
VMBUS device drivers in terms how to serialize
|
||||
accesss to the outgoing ring buffer.
|
||||
The default behavior will be to aquire the
|
||||
ring lock to preserve the current behavior.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit fe760e4d64fe5c17c39e86c410d41f6587ee88bc)
|
||||
---
|
||||
drivers/hv/channel.c | 15 +++++++++++----
|
||||
drivers/hv/channel_mgmt.c | 1 +
|
||||
drivers/hv/hyperv_vmbus.h | 2 +-
|
||||
drivers/hv/ring_buffer.c | 13 ++++++++-----
|
||||
include/linux/hyperv.h | 16 ++++++++++++++++
|
||||
5 files changed, 37 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 415f6c7..57a1b65 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -639,6 +639,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
|
||||
u64 aligned_data = 0;
|
||||
int ret;
|
||||
bool signal = false;
|
||||
+ bool lock = channel->acquire_ring_lock;
|
||||
int num_vecs = ((bufferlen != 0) ? 3 : 1);
|
||||
|
||||
|
||||
@@ -658,7 +659,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);
|
||||
+ &signal, lock);
|
||||
|
||||
/*
|
||||
* Signalling the host is conditional on many factors:
|
||||
@@ -738,6 +739,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
|
||||
struct kvec bufferlist[3];
|
||||
u64 aligned_data = 0;
|
||||
bool signal = false;
|
||||
+ bool lock = channel->acquire_ring_lock;
|
||||
|
||||
if (pagecount > MAX_PAGE_BUFFER_COUNT)
|
||||
return -EINVAL;
|
||||
@@ -774,7 +776,8 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
|
||||
bufferlist[2].iov_base = &aligned_data;
|
||||
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
||||
|
||||
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
|
||||
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
||||
+ &signal, lock);
|
||||
|
||||
/*
|
||||
* Signalling the host is conditional on many factors:
|
||||
@@ -837,6 +840,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
||||
struct kvec bufferlist[3];
|
||||
u64 aligned_data = 0;
|
||||
bool signal = false;
|
||||
+ bool lock = channel->acquire_ring_lock;
|
||||
|
||||
packetlen = desc_size + bufferlen;
|
||||
packetlen_aligned = ALIGN(packetlen, sizeof(u64));
|
||||
@@ -856,7 +860,8 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
||||
bufferlist[2].iov_base = &aligned_data;
|
||||
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
||||
|
||||
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
|
||||
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
||||
+ &signal, lock);
|
||||
|
||||
if (ret == 0 && signal)
|
||||
vmbus_setevent(channel);
|
||||
@@ -881,6 +886,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
|
||||
struct kvec bufferlist[3];
|
||||
u64 aligned_data = 0;
|
||||
bool signal = false;
|
||||
+ bool lock = channel->acquire_ring_lock;
|
||||
u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
|
||||
multi_pagebuffer->len);
|
||||
|
||||
@@ -919,7 +925,8 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
|
||||
bufferlist[2].iov_base = &aligned_data;
|
||||
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
||||
|
||||
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
|
||||
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
||||
+ &signal, lock);
|
||||
|
||||
if (ret == 0 && signal)
|
||||
vmbus_setevent(channel);
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index cf311be..b40f429 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -259,6 +259,7 @@ static struct vmbus_channel *alloc_channel(void)
|
||||
return NULL;
|
||||
|
||||
channel->id = atomic_inc_return(&chan_num);
|
||||
+ channel->acquire_ring_lock = true;
|
||||
spin_lock_init(&channel->inbound_lock);
|
||||
spin_lock_init(&channel->lock);
|
||||
|
||||
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
|
||||
index d9937be..b925fa3 100644
|
||||
--- a/drivers/hv/hyperv_vmbus.h
|
||||
+++ b/drivers/hv/hyperv_vmbus.h
|
||||
@@ -612,7 +612,7 @@ 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);
|
||||
+ u32 kv_count, bool *signal, bool lock);
|
||||
|
||||
int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
|
||||
u32 buflen);
|
||||
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
|
||||
index 70a1a9a..89a428f 100644
|
||||
--- a/drivers/hv/ring_buffer.c
|
||||
+++ b/drivers/hv/ring_buffer.c
|
||||
@@ -388,7 +388,7 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
|
||||
*
|
||||
*/
|
||||
int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
- struct kvec *kv_list, u32 kv_count, bool *signal)
|
||||
+ struct kvec *kv_list, u32 kv_count, bool *signal, bool lock)
|
||||
{
|
||||
int i = 0;
|
||||
u32 bytes_avail_towrite;
|
||||
@@ -398,14 +398,15 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
u32 next_write_location;
|
||||
u32 old_write;
|
||||
u64 prev_indices = 0;
|
||||
- unsigned long flags;
|
||||
+ unsigned long flags = 0;
|
||||
|
||||
for (i = 0; i < kv_count; i++)
|
||||
totalbytes_towrite += kv_list[i].iov_len;
|
||||
|
||||
totalbytes_towrite += sizeof(u64);
|
||||
|
||||
- spin_lock_irqsave(&outring_info->ring_lock, flags);
|
||||
+ if (lock)
|
||||
+ spin_lock_irqsave(&outring_info->ring_lock, flags);
|
||||
|
||||
hv_get_ringbuffer_availbytes(outring_info,
|
||||
&bytes_avail_toread,
|
||||
@@ -416,7 +417,8 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
/* Otherwise, the next time around, we think the ring buffer */
|
||||
/* is empty since the read index == write index */
|
||||
if (bytes_avail_towrite <= totalbytes_towrite) {
|
||||
- spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
+ if (lock)
|
||||
+ spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
@@ -447,7 +449,8 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
hv_set_next_write_location(outring_info, next_write_location);
|
||||
|
||||
|
||||
- spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
+ if (lock)
|
||||
+ spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
|
||||
*signal = hv_need_to_signal(old_write, outring_info);
|
||||
return 0;
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 993318a..6c9695e 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -813,8 +813,24 @@ struct vmbus_channel {
|
||||
* signaling control.
|
||||
*/
|
||||
enum hv_signal_policy signal_policy;
|
||||
+ /*
|
||||
+ * On the channel send side, many of the VMBUS
|
||||
+ * device drivers explicity serialize access to the
|
||||
+ * outgoing ring buffer. Give more control to the
|
||||
+ * VMBUS device drivers in terms how to serialize
|
||||
+ * accesss to the outgoing ring buffer.
|
||||
+ * The default behavior will be to aquire the
|
||||
+ * ring lock to preserve the current behavior.
|
||||
+ */
|
||||
+ bool acquire_ring_lock;
|
||||
+
|
||||
};
|
||||
|
||||
+static inline void set_channel_lock_state(struct vmbus_channel *c, bool state)
|
||||
+{
|
||||
+ c->acquire_ring_lock = state;
|
||||
+}
|
||||
+
|
||||
static inline bool is_hvsock_channel(const struct vmbus_channel *c)
|
||||
{
|
||||
return !!(c->offermsg.offer.chn_flags &
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,100 @@
|
||||
From 801ca93a137e97e204c04bf648901f73d38fabc9 Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Fri, 26 Feb 2016 15:13:16 -0800
|
||||
Subject: [PATCH 32/40] Drivers: hv: vmbus: avoid wait_for_completion() on
|
||||
crash
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
wait_for_completion() may sleep, it enables interrupts and this
|
||||
is something we really want to avoid on crashes because interrupt
|
||||
handlers can cause other crashes. Switch to the recently introduced
|
||||
vmbus_wait_for_unload() doing busy wait instead.
|
||||
|
||||
Reported-by: Radim Krcmar <rkrcmar@redhat.com>
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Reviewed-by: Radim Kr.má<rkrcmar@redhat.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit 75ff3a8a9168df750b5bd0589e897a6c0517a9f1)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 4 ++--
|
||||
drivers/hv/connection.c | 2 +-
|
||||
drivers/hv/hyperv_vmbus.h | 2 +-
|
||||
drivers/hv/vmbus_drv.c | 4 ++--
|
||||
4 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index b40f429..f70e352 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -641,7 +641,7 @@ static void vmbus_unload_response(struct vmbus_channel_message_header *hdr)
|
||||
complete(&vmbus_connection.unload_event);
|
||||
}
|
||||
|
||||
-void vmbus_initiate_unload(void)
|
||||
+void vmbus_initiate_unload(bool crash)
|
||||
{
|
||||
struct vmbus_channel_message_header hdr;
|
||||
|
||||
@@ -658,7 +658,7 @@ void vmbus_initiate_unload(void)
|
||||
* vmbus_initiate_unload() is also called on crash and the crash can be
|
||||
* happening in an interrupt context, where scheduling is impossible.
|
||||
*/
|
||||
- if (!in_interrupt())
|
||||
+ if (!crash)
|
||||
wait_for_completion(&vmbus_connection.unload_event);
|
||||
else
|
||||
vmbus_wait_for_unload();
|
||||
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
|
||||
index 09c08b5..78b8be8 100644
|
||||
--- a/drivers/hv/connection.c
|
||||
+++ b/drivers/hv/connection.c
|
||||
@@ -233,7 +233,7 @@ void vmbus_disconnect(void)
|
||||
/*
|
||||
* First send the unload request to the host.
|
||||
*/
|
||||
- vmbus_initiate_unload();
|
||||
+ vmbus_initiate_unload(false);
|
||||
|
||||
if (vmbus_connection.work_queue) {
|
||||
drain_workqueue(vmbus_connection.work_queue);
|
||||
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
|
||||
index b925fa3..10efab0 100644
|
||||
--- a/drivers/hv/hyperv_vmbus.h
|
||||
+++ b/drivers/hv/hyperv_vmbus.h
|
||||
@@ -751,7 +751,7 @@ void hv_vss_onchannelcallback(void *);
|
||||
int hv_fcopy_init(struct hv_util_service *);
|
||||
void hv_fcopy_deinit(void);
|
||||
void hv_fcopy_onchannelcallback(void *);
|
||||
-void vmbus_initiate_unload(void);
|
||||
+void vmbus_initiate_unload(bool crash);
|
||||
|
||||
static inline void hv_poll_channel(struct vmbus_channel *channel,
|
||||
void (*cb)(void *))
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index d76a65f..45ea71e 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -1263,7 +1263,7 @@ static void hv_kexec_handler(void)
|
||||
int cpu;
|
||||
|
||||
hv_synic_clockevents_cleanup();
|
||||
- vmbus_initiate_unload();
|
||||
+ vmbus_initiate_unload(false);
|
||||
for_each_online_cpu(cpu)
|
||||
smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
|
||||
hv_cleanup();
|
||||
@@ -1271,7 +1271,7 @@ static void hv_kexec_handler(void)
|
||||
|
||||
static void hv_crash_handler(struct pt_regs *regs)
|
||||
{
|
||||
- vmbus_initiate_unload();
|
||||
+ vmbus_initiate_unload(true);
|
||||
/*
|
||||
* In crash handler we can't schedule synic cleanup for all CPUs,
|
||||
* doing the cleanup for current CPU only. This should be sufficient
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -0,0 +1,39 @@
|
||||
From 57ebe7b218a4293879c6cfcfc809bd28d1c86d0b Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Fri, 26 Feb 2016 15:13:18 -0800
|
||||
Subject: [PATCH 33/40] Drivers: hv: vmbus: avoid unneeded compiler
|
||||
optimizations in vmbus_wait_for_unload()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Message header is modified by the hypervisor and we read it in a loop,
|
||||
we need to prevent compilers from optimizing accesses. There are no such
|
||||
optimizations at this moment, this is just a future proof.
|
||||
|
||||
Suggested-by: Radim Krcmar <rkrcmar@redhat.com>
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Reviewed-by: Radim Kr.má<rkrcmar@redhat.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
(cherry picked from commit d452ab7b4c65dfcaee88a0d6866eeeb98a3d1884)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index f70e352..c892db5 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -605,7 +605,7 @@ static void vmbus_wait_for_unload(void)
|
||||
bool unloaded = false;
|
||||
|
||||
while (1) {
|
||||
- if (msg->header.message_type == HVMSG_NONE) {
|
||||
+ if (READ_ONCE(msg->header.message_type) == HVMSG_NONE) {
|
||||
mdelay(10);
|
||||
continue;
|
||||
}
|
||||
--
|
||||
2.8.2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 7f7ff16a50fdab9cf540ba469dd4fd9dc1c36ce8 Mon Sep 17 00:00:00 2001
|
||||
From 309de4588761836db8325d18c96048c1d57976b0 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Herbert <tom@herbertland.com>
|
||||
Date: Mon, 7 Mar 2016 14:11:06 -0800
|
||||
Subject: [PATCH 22/28] kcm: Kernel Connection Multiplexor module
|
||||
Subject: [PATCH 34/40] kcm: Kernel Connection Multiplexor module
|
||||
|
||||
This module implements the Kernel Connection Multiplexor.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 0f2c256a5c2d11572adb078202575c85472c23dd Mon Sep 17 00:00:00 2001
|
||||
From 1b288c812adaffa34be2dc691e559a2c1ba343fa 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/28] net: add the AF_KCM entries to family name tables
|
||||
Subject: [PATCH 35/40] 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).
|
@@ -1,7 +1,7 @@
|
||||
From ff301a551f581af1f7a5b44e531f24f6706ff8a1 Mon Sep 17 00:00:00 2001
|
||||
From 2bc2ef5b66204e811990746ae362acd16519b35d Mon Sep 17 00:00:00 2001
|
||||
From: Courtney Cavin <courtney.cavin@sonymobile.com>
|
||||
Date: Wed, 27 Apr 2016 12:13:03 -0700
|
||||
Subject: [PATCH 24/28] net: Add Qualcomm IPC router
|
||||
Subject: [PATCH 36/40] net: Add Qualcomm IPC router
|
||||
|
||||
Add an implementation of Qualcomm's IPC router protocol, used to
|
||||
communicate with service providing remote processors.
|
@@ -1,7 +1,7 @@
|
||||
From f94eeafa1082af0972a429ca973da5230e21c5c9 Mon Sep 17 00:00:00 2001
|
||||
From e40aa678ad8d502eb916a28f5f3c35c162dcf4d2 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 11 May 2016 10:52:37 -0700
|
||||
Subject: [PATCH 25/28] hv_sock: introduce Hyper-V Sockets
|
||||
Date: Sun, 15 May 2016 09:53:11 -0700
|
||||
Subject: [PATCH 37/40] hv_sock: introduce Hyper-V Sockets
|
||||
|
||||
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
|
||||
mechanism between the host and the guest. It's somewhat like TCP over
|
||||
@@ -22,7 +22,7 @@ Cc: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Cc: Haiyang Zhang <haiyangz@microsoft.com>
|
||||
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Cc: Cathy Avery <cavery@redhat.com>
|
||||
Origin: http://patchwork.ozlabs.org/patch/621190/
|
||||
Origin: https://patchwork.ozlabs.org/patch/622404/
|
||||
---
|
||||
MAINTAINERS | 2 +
|
||||
include/linux/hyperv.h | 14 +
|
||||
@@ -33,8 +33,8 @@ Origin: http://patchwork.ozlabs.org/patch/621190/
|
||||
net/Makefile | 1 +
|
||||
net/hv_sock/Kconfig | 10 +
|
||||
net/hv_sock/Makefile | 3 +
|
||||
net/hv_sock/af_hvsock.c | 1484 +++++++++++++++++++++++++++++++++++++++++++
|
||||
10 files changed, 1621 insertions(+), 1 deletion(-)
|
||||
net/hv_sock/af_hvsock.c | 1520 +++++++++++++++++++++++++++++++++++++++++++
|
||||
10 files changed, 1657 insertions(+), 1 deletion(-)
|
||||
create mode 100644 include/net/af_hvsock.h
|
||||
create mode 100644 net/hv_sock/Kconfig
|
||||
create mode 100644 net/hv_sock/Makefile
|
||||
@@ -55,10 +55,10 @@ index 9a70d2d..1021706 100644
|
||||
F: Documentation/ABI/stable/sysfs-bus-vmbus
|
||||
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index af7ee0a..9864a30 100644
|
||||
index 6c9695e..187d4bd 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1314,4 +1314,18 @@ extern __u32 vmbus_proto_version;
|
||||
@@ -1349,4 +1349,18 @@ 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);
|
||||
@@ -102,7 +102,7 @@ index dbd81e7..6634c47 100644
|
||||
/* Maximum queue length specifiable by listen. */
|
||||
diff --git a/include/net/af_hvsock.h b/include/net/af_hvsock.h
|
||||
new file mode 100644
|
||||
index 0000000..e002397
|
||||
index 0000000..7c8c41e
|
||||
--- /dev/null
|
||||
+++ b/include/net/af_hvsock.h
|
||||
@@ -0,0 +1,78 @@
|
||||
@@ -113,7 +113,7 @@ index 0000000..e002397
|
||||
+#include <linux/hyperv.h>
|
||||
+#include <net/sock.h>
|
||||
+
|
||||
+/* Note: 3-page is the minimal recv ringbuffer size:
|
||||
+/* Note: 3-page is the minimal recv ringbuffer size by default:
|
||||
+ *
|
||||
+ * the 1st page is used as the shared read/write index etc, rather than data:
|
||||
+ * see hv_ringbuffer_init();
|
||||
@@ -123,18 +123,18 @@ index 0000000..e002397
|
||||
+ * need at least 2 extra pages for ringbuffer data.
|
||||
+ */
|
||||
+#define HVSOCK_RCV_BUF_SZ PAGE_SIZE
|
||||
+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_RCV (3 * PAGE_SIZE)
|
||||
+#define DEF_RINGBUFFER_PAGES_HVSOCK_RCV 3
|
||||
+
|
||||
+/* As to send, here let's make sure the hvsock_send_buf struct can be held in 1
|
||||
+ * page, and since we want to use 2 pages for the send ringbuffer size (this is
|
||||
+ * the minimal size because the 1st page of the two is used as the shared
|
||||
+ * read/write index etc, rather than data), we only have 1 page for ringbuffer
|
||||
+ * data, this means: the max payload length for hvsock data is
|
||||
+ * PAGE_SIZE - HVSOCK_PKT_LEN(0). Finally, let's reduce the length by 8-bytes
|
||||
+ * the minimal size by default, because the 1st page of the two is used as the
|
||||
+ * shared read/write index etc, rather than data), we only have 1 page for
|
||||
+ * ringbuffer data, this means: the max payload length for hvsock data is
|
||||
+ * PAGE_SIZE - HVSOCK_PKT_LEN(0). And, let's reduce the length by 8-bytes
|
||||
+ * because the ringbuffer can't be 100% full: see hv_ringbuffer_write().
|
||||
+ */
|
||||
+#define HVSOCK_SND_BUF_SZ (PAGE_SIZE - HVSOCK_PKT_LEN(0) - 8)
|
||||
+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_SND (2 * PAGE_SIZE)
|
||||
+#define DEF_RINGBUFFER_PAGES_HVSOCK_SND 2
|
||||
+
|
||||
+/* We only send data when the available space is "big enough". This artificial
|
||||
+ * value must be less than HVSOCK_SND_BUF_SZ.
|
||||
@@ -276,10 +276,10 @@ index 0000000..716c012
|
||||
+hv_sock-y += af_hvsock.o
|
||||
diff --git a/net/hv_sock/af_hvsock.c b/net/hv_sock/af_hvsock.c
|
||||
new file mode 100644
|
||||
index 0000000..013d684
|
||||
index 0000000..b91bd60
|
||||
--- /dev/null
|
||||
+++ b/net/hv_sock/af_hvsock.c
|
||||
@@ -0,0 +1,1484 @@
|
||||
@@ -0,0 +1,1520 @@
|
||||
+/*
|
||||
+ * Hyper-V Sockets -- a socket-based communication channel between the
|
||||
+ * Hyper-V host and the virtual machines running on it.
|
||||
@@ -317,6 +317,21 @@ index 0000000..013d684
|
||||
+#include <linux/module.h>
|
||||
+#include <net/af_hvsock.h>
|
||||
+
|
||||
+static uint send_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_SND;
|
||||
+static uint recv_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_RCV;
|
||||
+static uint max_socket_number = 1024;
|
||||
+
|
||||
+static atomic_t total_num_hvsock = ATOMIC_INIT(0);
|
||||
+
|
||||
+module_param(send_ring_page, uint, 0444);
|
||||
+MODULE_PARM_DESC(send_ring_page, "Send ring buffer size (# of pages)");
|
||||
+
|
||||
+module_param(recv_ring_page, uint, 0444);
|
||||
+MODULE_PARM_DESC(recv_ring_page, "Receive ring buffer size (# of pages)");
|
||||
+
|
||||
+module_param(max_socket_number, uint, 0644);
|
||||
+MODULE_PARM_DESC(max_socket_number, "The max number of created sockets");
|
||||
+
|
||||
+static struct proto hvsock_proto = {
|
||||
+ .name = "HV_SOCK",
|
||||
+ .owner = THIS_MODULE,
|
||||
@@ -525,6 +540,7 @@ index 0000000..013d684
|
||||
+
|
||||
+ kfree(hvsk->send);
|
||||
+ kfree(hvsk->recv);
|
||||
+ atomic_dec(&total_num_hvsock);
|
||||
+
|
||||
+ if (!channel)
|
||||
+ return;
|
||||
@@ -581,43 +597,48 @@ index 0000000..013d684
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct sock *__hvsock_create(struct net *net, struct socket *sock,
|
||||
+ gfp_t priority, unsigned short type)
|
||||
+static int hvsock_create(struct net *net, struct socket *sock,
|
||||
+ gfp_t priority, unsigned short type,
|
||||
+ struct sock **sk)
|
||||
+{
|
||||
+ struct hvsock_send_buf *send = NULL;
|
||||
+ struct hvsock_recv_buf *recv = NULL;
|
||||
+
|
||||
+ struct hvsock_sock *hvsk;
|
||||
+ struct sock *sk;
|
||||
+ int ret = -EMFILE;
|
||||
+ int num_hvsock;
|
||||
+
|
||||
+ send = kmalloc(sizeof(struct hvsock_send_buf), GFP_KERNEL);
|
||||
+ recv = kmalloc(sizeof(struct hvsock_recv_buf), GFP_KERNEL);
|
||||
+ num_hvsock = atomic_inc_return(&total_num_hvsock);
|
||||
+ if (num_hvsock > max_socket_number)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = -ENOMEM;
|
||||
+ send = kmalloc(sizeof(*send), GFP_KERNEL);
|
||||
+ recv = kmalloc(sizeof(*recv), GFP_KERNEL);
|
||||
+ if (!send || !recv)
|
||||
+ goto err;
|
||||
+
|
||||
+ sk = sk_alloc(net, AF_HYPERV, priority, &hvsock_proto, 0);
|
||||
+ if (!sk)
|
||||
+ *sk = sk_alloc(net, AF_HYPERV, priority, &hvsock_proto, 0);
|
||||
+ if (!*sk)
|
||||
+ goto err;
|
||||
+
|
||||
+ sock_init_data(sock, sk);
|
||||
+ sock_init_data(sock, *sk);
|
||||
+
|
||||
+ /* sk->sk_type is normally set in sock_init_data, but only if sock is
|
||||
+ * non-NULL. We make sure that our sockets always have a type by
|
||||
+ /* (*sk)->sk_type is normally set in sock_init_data, but only if sock
|
||||
+ * is non-NULL. We make sure that our sockets always have a type by
|
||||
+ * setting it here if needed.
|
||||
+ */
|
||||
+ if (!sock)
|
||||
+ sk->sk_type = type;
|
||||
+ (*sk)->sk_type = type;
|
||||
+
|
||||
+
|
||||
+ sk->sk_destruct = hvsock_sk_destruct;
|
||||
+ (*sk)->sk_destruct = hvsock_sk_destruct;
|
||||
+
|
||||
+ /* Looks stream-based socket doesn't need this. */
|
||||
+ sk->sk_backlog_rcv = NULL;
|
||||
+ (*sk)->sk_backlog_rcv = NULL;
|
||||
+
|
||||
+ sk->sk_state = 0;
|
||||
+ sock_reset_flag(sk, SOCK_DONE);
|
||||
+ (*sk)->sk_state = 0;
|
||||
+ sock_reset_flag(*sk, SOCK_DONE);
|
||||
+
|
||||
+ hvsk = sk_to_hvsock(sk);
|
||||
+ hvsk = sk_to_hvsock(*sk);
|
||||
+
|
||||
+ hvsk->send = send;
|
||||
+ hvsk->recv = recv;
|
||||
@@ -636,11 +657,13 @@ index 0000000..013d684
|
||||
+ hvsk->recv->data_len = 0;
|
||||
+ hvsk->recv->data_offset = 0;
|
||||
+
|
||||
+ return sk;
|
||||
+ return 0;
|
||||
+err:
|
||||
+ atomic_dec(&total_num_hvsock);
|
||||
+ kfree(send);
|
||||
+ kfree(recv);
|
||||
+ return NULL;
|
||||
+ *sk = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_bind(struct socket *sock, struct sockaddr *addr,
|
||||
@@ -699,40 +722,6 @@ index 0000000..013d684
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_shutdown(struct socket *sock, int mode)
|
||||
+{
|
||||
+ struct sock *sk;
|
||||
+
|
||||
+ if (mode < SHUT_RD || mode > SHUT_RDWR)
|
||||
+ return -EINVAL;
|
||||
+ /* This maps:
|
||||
+ * SHUT_RD (0) -> RCV_SHUTDOWN (1)
|
||||
+ * SHUT_WR (1) -> SEND_SHUTDOWN (2)
|
||||
+ * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
|
||||
+ */
|
||||
+ ++mode;
|
||||
+
|
||||
+ if (sock->state == SS_UNCONNECTED)
|
||||
+ return -ENOTCONN;
|
||||
+
|
||||
+ sock->state = SS_DISCONNECTING;
|
||||
+
|
||||
+ sk = sock->sk;
|
||||
+
|
||||
+ lock_sock(sk);
|
||||
+
|
||||
+ sk->sk_shutdown |= mode;
|
||||
+ sk->sk_state_change(sk);
|
||||
+
|
||||
+ /* TODO: how to send a FIN if we haven't done that? */
|
||||
+ if (mode & SEND_SHUTDOWN)
|
||||
+ ;
|
||||
+
|
||||
+ release_sock(sk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void get_ringbuffer_rw_status(struct vmbus_channel *channel,
|
||||
+ bool *can_read, bool *can_write)
|
||||
+{
|
||||
@@ -742,7 +731,7 @@ index 0000000..013d684
|
||||
+ hv_get_ringbuffer_availbytes(&channel->inbound,
|
||||
+ &avl_read_bytes,
|
||||
+ &dummy);
|
||||
+ /* 0-size payload meaans FIN */
|
||||
+ /* 0-size payload means FIN */
|
||||
+ *can_read = avl_read_bytes >= HVSOCK_PKT_LEN(0);
|
||||
+ }
|
||||
+
|
||||
@@ -765,14 +754,86 @@ index 0000000..013d684
|
||||
+ &dummy,
|
||||
+ &avl_write_bytes);
|
||||
+
|
||||
+ if (avl_write_bytes < HVSOCK_PKT_LEN(1))
|
||||
+ if (avl_write_bytes < HVSOCK_PKT_LEN(1) + HVSOCK_PKT_LEN(0))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* The ringbuffer can't be 100% full */
|
||||
+ ret = avl_write_bytes - HVSOCK_PKT_LEN(1);
|
||||
+ /* The ringbuffer mustn't be 100% full, and we should reserve a
|
||||
+ * zero-length-payload packet for the FIN: see hv_ringbuffer_write()
|
||||
+ * and hvsock_shutdown().
|
||||
+ */
|
||||
+ ret = avl_write_bytes - HVSOCK_PKT_LEN(1) - HVSOCK_PKT_LEN(0);
|
||||
+
|
||||
+ return round_down(ret, 8);
|
||||
+}
|
||||
+
|
||||
+static int hvsock_send_data(struct vmbus_channel *channel,
|
||||
+ struct hvsock_sock *hvsk,
|
||||
+ size_t to_write)
|
||||
+{
|
||||
+ hvsk->send->hdr.pkt_type = 1;
|
||||
+ hvsk->send->hdr.data_size = to_write;
|
||||
+ return vmbus_sendpacket(channel, &hvsk->send->hdr,
|
||||
+ sizeof(hvsk->send->hdr) + to_write,
|
||||
+ 0, VM_PKT_DATA_INBAND, 0);
|
||||
+}
|
||||
+
|
||||
+static int hvsock_recv_data(struct vmbus_channel *channel,
|
||||
+ struct hvsock_sock *hvsk,
|
||||
+ size_t *payload_len)
|
||||
+{
|
||||
+ u32 buffer_actual_len;
|
||||
+ u64 dummy_req_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = vmbus_recvpacket(channel, &hvsk->recv->hdr,
|
||||
+ sizeof(hvsk->recv->hdr) +
|
||||
+ sizeof(hvsk->recv->buf),
|
||||
+ &buffer_actual_len, &dummy_req_id);
|
||||
+ if (ret != 0 || buffer_actual_len <= sizeof(hvsk->recv->hdr))
|
||||
+ *payload_len = 0;
|
||||
+ else
|
||||
+ *payload_len = hvsk->recv->hdr.data_size;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_shutdown(struct socket *sock, int mode)
|
||||
+{
|
||||
+ struct hvsock_sock *hvsk;
|
||||
+ struct sock *sk;
|
||||
+
|
||||
+ if (mode < SHUT_RD || mode > SHUT_RDWR)
|
||||
+ return -EINVAL;
|
||||
+ /* This maps:
|
||||
+ * SHUT_RD (0) -> RCV_SHUTDOWN (1)
|
||||
+ * SHUT_WR (1) -> SEND_SHUTDOWN (2)
|
||||
+ * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
|
||||
+ */
|
||||
+ ++mode;
|
||||
+
|
||||
+ if (sock->state != SS_CONNECTED)
|
||||
+ return -ENOTCONN;
|
||||
+
|
||||
+ sock->state = SS_DISCONNECTING;
|
||||
+
|
||||
+ sk = sock->sk;
|
||||
+
|
||||
+ lock_sock(sk);
|
||||
+
|
||||
+ sk->sk_shutdown |= mode;
|
||||
+ sk->sk_state_change(sk);
|
||||
+
|
||||
+ if (mode & SEND_SHUTDOWN) {
|
||||
+ hvsk = sk_to_hvsock(sk);
|
||||
+ /* It can't fail: see get_ringbuffer_writable_bytes(). */
|
||||
+ (void)hvsock_send_data(hvsk->channel, hvsk, 0);
|
||||
+ }
|
||||
+
|
||||
+ release_sock(sk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned int hvsock_poll(struct file *file, struct socket *sock,
|
||||
+ poll_table *wait)
|
||||
+{
|
||||
@@ -898,7 +959,6 @@ index 0000000..013d684
|
||||
+ if (!sk)
|
||||
+ goto out;
|
||||
+
|
||||
+ sk->sk_socket->state = SS_UNCONNECTED;
|
||||
+ sk->sk_state = SS_UNCONNECTED;
|
||||
+ sock_set_flag(sk, SOCK_DONE);
|
||||
+
|
||||
@@ -932,7 +992,7 @@ index 0000000..013d684
|
||||
+ sk = hvsock_find_bound_socket(&hv_addr);
|
||||
+
|
||||
+ if (!sk || (conn_from_host && sk->sk_state != SS_LISTEN) ||
|
||||
+ (!conn_from_host && sk->sk_state != SS_CONNECTING)) {
|
||||
+ (!conn_from_host && sk->sk_state != SS_CONNECTING)) {
|
||||
+ ret = -ENXIO;
|
||||
+ goto out;
|
||||
+ }
|
||||
@@ -943,12 +1003,11 @@ index 0000000..013d684
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ new_sk = __hvsock_create(sock_net(sk), NULL, GFP_KERNEL,
|
||||
+ sk->sk_type);
|
||||
+ if (!new_sk) {
|
||||
+ ret = -ENOMEM;
|
||||
+ ret = hvsock_create(sock_net(sk), NULL, GFP_KERNEL,
|
||||
+ sk->sk_type, &new_sk);
|
||||
+ if (ret != 0)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ new_sk->sk_state = SS_CONNECTING;
|
||||
+ new_hvsk = sk_to_hvsock(new_sk);
|
||||
+ new_hvsk->channel = channel;
|
||||
@@ -960,9 +1019,8 @@ index 0000000..013d684
|
||||
+ }
|
||||
+
|
||||
+ set_channel_read_state(channel, false);
|
||||
+ vmbus_set_chn_rescind_callback(channel, hvsock_close_connection);
|
||||
+ ret = vmbus_open(channel, VMBUS_RINGBUFFER_SIZE_HVSOCK_SND,
|
||||
+ VMBUS_RINGBUFFER_SIZE_HVSOCK_RCV, NULL, 0,
|
||||
+ ret = vmbus_open(channel, send_ring_page * PAGE_SIZE,
|
||||
+ recv_ring_page * PAGE_SIZE, NULL, 0,
|
||||
+ hvsock_on_channel_cb, conn_from_host ? new_sk : sk);
|
||||
+ if (ret != 0) {
|
||||
+ if (conn_from_host) {
|
||||
@@ -974,6 +1032,7 @@ index 0000000..013d684
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ vmbus_set_chn_rescind_callback(channel, hvsock_close_connection);
|
||||
+ set_channel_pending_send_size(channel,
|
||||
+ HVSOCK_PKT_LEN(HVSOCK_SND_THRESHOLD));
|
||||
+
|
||||
@@ -1264,17 +1323,6 @@ index 0000000..013d684
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_send_data(struct vmbus_channel *channel,
|
||||
+ struct hvsock_sock *hvsk,
|
||||
+ size_t to_write)
|
||||
+{
|
||||
+ hvsk->send->hdr.pkt_type = 1;
|
||||
+ hvsk->send->hdr.data_size = to_write;
|
||||
+ return vmbus_sendpacket(channel, &hvsk->send->hdr,
|
||||
+ sizeof(hvsk->send->hdr) + to_write,
|
||||
+ 0, VM_PKT_DATA_INBAND, 0);
|
||||
+}
|
||||
+
|
||||
+static
|
||||
+int hvsock_sendmsg_wait(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
+{
|
||||
@@ -1432,26 +1480,6 @@ index 0000000..013d684
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_recv_data(struct vmbus_channel *channel,
|
||||
+ struct hvsock_sock *hvsk,
|
||||
+ size_t *payload_len)
|
||||
+{
|
||||
+ u32 buffer_actual_len;
|
||||
+ u64 dummy_req_id;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = vmbus_recvpacket(channel, &hvsk->recv->hdr,
|
||||
+ sizeof(hvsk->recv->hdr) +
|
||||
+ sizeof(hvsk->recv->buf),
|
||||
+ &buffer_actual_len, &dummy_req_id);
|
||||
+ if (ret != 0 || buffer_actual_len <= sizeof(hvsk->recv->hdr))
|
||||
+ *payload_len = 0;
|
||||
+ else
|
||||
+ *payload_len = hvsk->recv->hdr.data_size;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hvsock_recvmsg_wait(struct sock *sk, struct msghdr *msg,
|
||||
+ size_t len, int flags)
|
||||
+{
|
||||
@@ -1651,9 +1679,11 @@ index 0000000..013d684
|
||||
+ .sendpage = sock_no_sendpage,
|
||||
+};
|
||||
+
|
||||
+static int hvsock_create(struct net *net, struct socket *sock,
|
||||
+ int protocol, int kern)
|
||||
+static int hvsock_create_sock(struct net *net, struct socket *sock,
|
||||
+ int protocol, int kern)
|
||||
+{
|
||||
+ struct sock *sk;
|
||||
+
|
||||
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN))
|
||||
+ return -EPERM;
|
||||
+
|
||||
@@ -1670,12 +1700,12 @@ index 0000000..013d684
|
||||
+
|
||||
+ sock->state = SS_UNCONNECTED;
|
||||
+
|
||||
+ return __hvsock_create(net, sock, GFP_KERNEL, 0) ? 0 : -ENOMEM;
|
||||
+ return hvsock_create(net, sock, GFP_KERNEL, 0, &sk);
|
||||
+}
|
||||
+
|
||||
+static const struct net_proto_family hvsock_family_ops = {
|
||||
+ .family = AF_HYPERV,
|
||||
+ .create = hvsock_create,
|
||||
+ .create = hvsock_create_sock,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
@@ -1719,6 +1749,12 @@ index 0000000..013d684
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (send_ring_page < DEF_RINGBUFFER_PAGES_HVSOCK_SND)
|
||||
+ send_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_SND;
|
||||
+
|
||||
+ if (recv_ring_page < DEF_RINGBUFFER_PAGES_HVSOCK_RCV)
|
||||
+ recv_ring_page = DEF_RINGBUFFER_PAGES_HVSOCK_RCV;
|
||||
+
|
||||
+ /* Hyper-V Sockets requires at least VMBus 4.0 */
|
||||
+ if ((vmbus_proto_version >> 16) < 4) {
|
||||
+ pr_err("failed to load: VMBus 4 or later is required\n");
|
@@ -1,7 +1,7 @@
|
||||
From 2cffe53eda5ea0b90968867317149b57eb6d5b13 Mon Sep 17 00:00:00 2001
|
||||
From 7034fda17f5619f598de93fecdfd0af6a96b18f4 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 21 Mar 2016 02:53:08 -0700
|
||||
Subject: [PATCH 26/28] net: add the AF_HYPERV entries to family name tables
|
||||
Subject: [PATCH 38/40] net: add the AF_HYPERV entries to family name tables
|
||||
|
||||
This is for the hv_sock driver, which introduces AF_HYPERV(42).
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 6d6ad94bf42ceff0785f28382ba2c4a2cc6725d3 Mon Sep 17 00:00:00 2001
|
||||
From 0eba2b0c75b7dddedeedd6c827d71d0f23ae00ac Mon Sep 17 00:00:00 2001
|
||||
From: Ian Campbell <ian.campbell@docker.com>
|
||||
Date: Wed, 4 May 2016 14:21:53 +0100
|
||||
Subject: [PATCH 27/28] VSOCK: do not disconnect socket when peer has shutdown
|
||||
Subject: [PATCH 39/40] VSOCK: do not disconnect socket when peer has shutdown
|
||||
SEND only
|
||||
|
||||
The peer may be expecting a reply having sent a request and then done a
|
@@ -0,0 +1,150 @@
|
||||
From 87cb6b00e44a0d496c623ea19801e2a9415a9759 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Mon, 16 May 2016 22:26:05 +0800
|
||||
Subject: [PATCH 40/40] Drivers: hv: vmbus: fix the race when querying &
|
||||
updating the percpu list
|
||||
|
||||
There is a rare race when we remove an entry from the global list
|
||||
hv_context.percpu_list[cpu] in hv_process_channel_removal() ->
|
||||
percpu_channel_deq() -> list_del(): at this time, if vmbus_on_event() ->
|
||||
process_chn_event() -> pcpu_relid2channel() is trying to query the list,
|
||||
we can get the general protection fault:
|
||||
|
||||
general protection fault: 0000 [#1] SMP
|
||||
...
|
||||
RIP: 0010:[<ffffffff81461b6b>] [<ffffffff81461b6b>] vmbus_on_event+0xc4/0x149
|
||||
|
||||
Similarly, we also have the issue in the code path: vmbus_process_offer() ->
|
||||
percpu_channel_enq().
|
||||
|
||||
We can resolve the issue by disabling the tasklet when updating the list.
|
||||
|
||||
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Origin: https://github.com/dcui/linux/commit/cef5caca69a9104988a0e1c5185f919f7adbf1d2.patch
|
||||
---
|
||||
drivers/hv/channel.c | 3 +++
|
||||
drivers/hv/channel_mgmt.c | 20 +++++++++-----------
|
||||
include/linux/hyperv.h | 3 +++
|
||||
3 files changed, 15 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 57a1b65..f66fb3c 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -546,8 +546,11 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
put_cpu();
|
||||
smp_call_function_single(channel->target_cpu, reset_channel_cb,
|
||||
channel, true);
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ percpu_channel_deq, channel, true);
|
||||
} else {
|
||||
reset_channel_cb(channel);
|
||||
+ percpu_channel_deq(channel);
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index c892db5..ac48fe9 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mm.h>
|
||||
@@ -277,7 +278,7 @@ static void free_channel(struct vmbus_channel *channel)
|
||||
kfree(channel);
|
||||
}
|
||||
|
||||
-static void percpu_channel_enq(void *arg)
|
||||
+void percpu_channel_enq(void *arg)
|
||||
{
|
||||
struct vmbus_channel *channel = arg;
|
||||
int cpu = smp_processor_id();
|
||||
@@ -285,7 +286,7 @@ static void percpu_channel_enq(void *arg)
|
||||
list_add_tail(&channel->percpu_list, &hv_context.percpu_list[cpu]);
|
||||
}
|
||||
|
||||
-static void percpu_channel_deq(void *arg)
|
||||
+void percpu_channel_deq(void *arg)
|
||||
{
|
||||
struct vmbus_channel *channel = arg;
|
||||
|
||||
@@ -313,15 +314,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));
|
||||
|
||||
- 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();
|
||||
- }
|
||||
-
|
||||
if (channel->primary_channel == NULL) {
|
||||
list_del(&channel->listentry);
|
||||
|
||||
@@ -363,6 +355,7 @@ void vmbus_free_channels(void)
|
||||
*/
|
||||
static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
{
|
||||
+ struct tasklet_struct *tasklet;
|
||||
struct vmbus_channel *channel;
|
||||
bool fnew = true;
|
||||
unsigned long flags;
|
||||
@@ -409,6 +402,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
|
||||
init_vp_index(newchannel, dev_type);
|
||||
|
||||
+ tasklet = hv_context.event_dpc[newchannel->target_cpu];
|
||||
+ tasklet_disable(tasklet);
|
||||
if (newchannel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
smp_call_function_single(newchannel->target_cpu,
|
||||
@@ -418,6 +413,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
percpu_channel_enq(newchannel);
|
||||
put_cpu();
|
||||
}
|
||||
+ tasklet_enable(tasklet);
|
||||
|
||||
/*
|
||||
* This state is used to indicate a successful open
|
||||
@@ -469,6 +465,7 @@ err_deq_chan:
|
||||
list_del(&newchannel->listentry);
|
||||
mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
+ tasklet_disable(tasklet);
|
||||
if (newchannel->target_cpu != get_cpu()) {
|
||||
put_cpu();
|
||||
smp_call_function_single(newchannel->target_cpu,
|
||||
@@ -477,6 +474,7 @@ err_deq_chan:
|
||||
percpu_channel_deq(newchannel);
|
||||
put_cpu();
|
||||
}
|
||||
+ tasklet_enable(tasklet);
|
||||
|
||||
err_free_chan:
|
||||
free_channel(newchannel);
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 187d4bd..a69364b 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1339,6 +1339,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
|
||||
struct icmsg_negotiate *, u8 *, int,
|
||||
int);
|
||||
|
||||
+void percpu_channel_enq(void *arg);
|
||||
+void percpu_channel_deq(void *arg);
|
||||
+
|
||||
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||
|
||||
/*
|
||||
--
|
||||
2.8.2
|
||||
|
Reference in New Issue
Block a user