mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-22 02:21:34 +00:00
kernel: Remove support for 4.9.x kernels
Signed-off-by: Rolf Neugebauer <rn@rneugeba.io>
This commit is contained in:
parent
f06c39545a
commit
4a06b88d1e
@ -258,7 +258,6 @@ $(eval $(call kernel,4.19.90,4.19.x,$(EXTRA),$(DEBUG)))
|
||||
$(eval $(call kernel,4.19.90,4.19.x,,-dbg))
|
||||
$(eval $(call kernel,4.19.59,4.19.x,-rt,))
|
||||
$(eval $(call kernel,4.14.159,4.14.x,$(EXTRA),$(DEBUG)))
|
||||
$(eval $(call kernel,4.9.206,4.9.x,$(EXTRA),$(DEBUG)))
|
||||
|
||||
else ifeq ($(ARCH),aarch64)
|
||||
$(eval $(call kernel,5.4.4,5.4.x,$(EXTRA),$(DEBUG)))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
||||
From 564a87a65b31d2ca32417d0bd2f47aa6ba3d423a Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Thu, 2 Mar 2017 12:55:49 -0300
|
||||
Subject: [PATCH 01/14] tools build: Add test for sched_getcpu()
|
||||
|
||||
Instead of trying to go on adding more ifdef conditions, do a feature
|
||||
test and define HAVE_SCHED_GETCPU_SUPPORT instead, then use it to
|
||||
provide the prototype. No need to change the stub, as it is already a
|
||||
__weak symbol.
|
||||
|
||||
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Jiri Olsa <jolsa@kernel.org>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Wang Nan <wangnan0@huawei.com>
|
||||
Link: http://lkml.kernel.org/n/tip-yge89er9g90sc0v6k0a0r5tr@git.kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
(cherry picked from commit 120010cb1eea151d38a3e66f5ffc79a0c3110292)
|
||||
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
|
||||
---
|
||||
tools/build/Makefile.feature | 1 +
|
||||
tools/build/feature/Makefile | 6 +++++-
|
||||
tools/build/feature/test-all.c | 5 +++++
|
||||
tools/build/feature/test-sched_getcpu.c | 7 +++++++
|
||||
tools/perf/Makefile.config | 4 ++++
|
||||
tools/perf/util/cloexec.h | 6 ------
|
||||
tools/perf/util/util.h | 4 ++--
|
||||
7 files changed, 24 insertions(+), 9 deletions(-)
|
||||
create mode 100644 tools/build/feature/test-sched_getcpu.c
|
||||
|
||||
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
|
||||
index ae52e029dd22..ea0a46b4f65f 100644
|
||||
--- a/tools/build/Makefile.feature
|
||||
+++ b/tools/build/Makefile.feature
|
||||
@@ -63,6 +63,7 @@ FEATURE_TESTS_BASIC := \
|
||||
lzma \
|
||||
get_cpuid \
|
||||
bpf \
|
||||
+ sched_getcpu \
|
||||
sdt
|
||||
|
||||
# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
|
||||
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
|
||||
index ac9c477a2a48..5d5f093b85a1 100644
|
||||
--- a/tools/build/feature/Makefile
|
||||
+++ b/tools/build/feature/Makefile
|
||||
@@ -47,7 +47,8 @@ FILES= \
|
||||
test-bpf.bin \
|
||||
test-get_cpuid.bin \
|
||||
test-sdt.bin \
|
||||
- test-cxx.bin
|
||||
+ test-cxx.bin \
|
||||
+ test-sched_getcpu.bin
|
||||
|
||||
FILES := $(addprefix $(OUTPUT),$(FILES))
|
||||
|
||||
@@ -89,6 +90,9 @@ $(OUTPUT)test-libelf.bin:
|
||||
$(OUTPUT)test-glibc.bin:
|
||||
$(BUILD)
|
||||
|
||||
+$(OUTPUT)test-sched_getcpu.bin:
|
||||
+ $(BUILD)
|
||||
+
|
||||
DWARFLIBS := -ldw
|
||||
ifeq ($(findstring -static,${LDFLAGS}),-static)
|
||||
DWARFLIBS += -lelf -lebl -lz -llzma -lbz2
|
||||
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
|
||||
index 699e43627397..cc6c7c01f4ca 100644
|
||||
--- a/tools/build/feature/test-all.c
|
||||
+++ b/tools/build/feature/test-all.c
|
||||
@@ -117,6 +117,10 @@
|
||||
# include "test-pthread-attr-setaffinity-np.c"
|
||||
#undef main
|
||||
|
||||
+#define main main_test_sched_getcpu
|
||||
+# include "test-sched_getcpu.c"
|
||||
+#undef main
|
||||
+
|
||||
# if 0
|
||||
/*
|
||||
* Disable libbabeltrace check for test-all, because the requested
|
||||
@@ -182,6 +186,7 @@ int main(int argc, char *argv[])
|
||||
main_test_get_cpuid();
|
||||
main_test_bpf();
|
||||
main_test_libcrypto();
|
||||
+ main_test_sched_getcpu();
|
||||
main_test_sdt();
|
||||
|
||||
return 0;
|
||||
diff --git a/tools/build/feature/test-sched_getcpu.c b/tools/build/feature/test-sched_getcpu.c
|
||||
new file mode 100644
|
||||
index 000000000000..c4a148dd7104
|
||||
--- /dev/null
|
||||
+++ b/tools/build/feature/test-sched_getcpu.c
|
||||
@@ -0,0 +1,7 @@
|
||||
+#define _GNU_SOURCE
|
||||
+#include <sched.h>
|
||||
+
|
||||
+int main(void)
|
||||
+{
|
||||
+ return sched_getcpu();
|
||||
+}
|
||||
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
|
||||
index ff375310efe4..07c12686bcd1 100644
|
||||
--- a/tools/perf/Makefile.config
|
||||
+++ b/tools/perf/Makefile.config
|
||||
@@ -296,6 +296,10 @@ ifdef NO_DWARF
|
||||
NO_LIBDW_DWARF_UNWIND := 1
|
||||
endif
|
||||
|
||||
+ifeq ($(feature-sched_getcpu), 1)
|
||||
+ CFLAGS += -DHAVE_SCHED_GETCPU_SUPPORT
|
||||
+endif
|
||||
+
|
||||
ifndef NO_LIBELF
|
||||
CFLAGS += -DHAVE_LIBELF_SUPPORT
|
||||
EXTLIBS += -lelf
|
||||
diff --git a/tools/perf/util/cloexec.h b/tools/perf/util/cloexec.h
|
||||
index d0d465953d36..94a5a7d829d5 100644
|
||||
--- a/tools/perf/util/cloexec.h
|
||||
+++ b/tools/perf/util/cloexec.h
|
||||
@@ -3,10 +3,4 @@
|
||||
|
||||
unsigned long perf_event_open_cloexec_flag(void);
|
||||
|
||||
-#ifdef __GLIBC_PREREQ
|
||||
-#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
|
||||
-int sched_getcpu(void) __THROW;
|
||||
-#endif
|
||||
-#endif
|
||||
-
|
||||
#endif /* __PERF_CLOEXEC_H */
|
||||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
|
||||
index 8b39e8086c2d..d0c7526db145 100644
|
||||
--- a/tools/perf/util/util.h
|
||||
+++ b/tools/perf/util/util.h
|
||||
@@ -353,8 +353,8 @@ void print_binary(unsigned char *data, size_t len,
|
||||
size_t bytes_per_line, print_binary_t printer,
|
||||
void *extra);
|
||||
|
||||
-#if !defined(__GLIBC__) && !defined(__ANDROID__)
|
||||
-extern int sched_getcpu(void);
|
||||
+#ifndef HAVE_SCHED_GETCPU_SUPPORT
|
||||
+int sched_getcpu(void);
|
||||
#endif
|
||||
|
||||
int is_printable_array(char *p, unsigned int len);
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,70 +0,0 @@
|
||||
From 3c894cd46a6b7bd5f98e5743715c8bfeb5169992 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
Date: Thu, 13 Oct 2016 17:12:35 -0300
|
||||
Subject: [PATCH 02/14] perf jit: Avoid returning garbage for a ret variable
|
||||
|
||||
When the loop body isn't executed at all, then the 'ret' local variable,
|
||||
that is uninitialized will be used as the return value.
|
||||
|
||||
This triggers this error on Alpine Linux:
|
||||
|
||||
CC /tmp/build/perf/util/demangle-java.o
|
||||
CC /tmp/build/perf/util/demangle-rust.o
|
||||
CC /tmp/build/perf/util/jitdump.o
|
||||
CC /tmp/build/perf/util/genelf.o
|
||||
util/jitdump.c: In function 'jit_process':
|
||||
util/jitdump.c:622:3: error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized]
|
||||
fprintf(stderr, "injected: %s (%d)\n", path, ret);
|
||||
^
|
||||
util/jitdump.c:584:6: note: 'ret' was declared here
|
||||
int ret;
|
||||
^
|
||||
FLEX /tmp/build/perf/util/parse-events-flex.c
|
||||
|
||||
/ $ gcc -v
|
||||
Using built-in specs.
|
||||
COLLECT_GCC=gcc
|
||||
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-alpine-linux-musl/5.3.0/lto-wrapper
|
||||
Target: x86_64-alpine-linux-musl
|
||||
Configured with: /home/buildozer/aports/main/gcc/src/gcc-5.3.0/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info
|
||||
+--build=x86_64-alpine-linux-musl --host=x86_64-alpine-linux-musl --target=x86_64-alpine-linux-musl --with-pkgversion='Alpine 5.3.0' --enable-checking=release
|
||||
+--disable-fixed-point --disable-libstdcxx-pch --disable-multilib --disable-nls --disable-werror --disable-symvers --enable-__cxa_atexit --enable-esp
|
||||
+--enable-cloog-backend --enable-languages=c,c++,objc,java,fortran,ada --disable-libssp --disable-libmudflap --disable-libsanitizer --enable-shared
|
||||
+--enable-threads --enable-tls --with-system-zlib
|
||||
Thread model: posix
|
||||
gcc version 5.3.0 (Alpine 5.3.0)
|
||||
|
||||
But this so far got under the radar, not causing any build problem, till the
|
||||
"perf jit: enable jitdump support without dwarf" gets applied, when the above
|
||||
problem takes place, some combination of inlining or whatever, the problem
|
||||
is real, so fix it by initializing the variable to zero.
|
||||
|
||||
Cc: Anton Blanchard <anton@ozlabs.org>
|
||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
||||
Cc: Maciej Debski <maciejd@google.com>
|
||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Stephane Eranian <eranian@google.com>
|
||||
Link: https://lkml.kernel.org/r/20161013200437.GA12815@kernel.org
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
(cherry picked from commit ef2c3e76d98dfb69a46d870b47656e8e5bac6e2b)
|
||||
---
|
||||
tools/perf/util/jitdump.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
|
||||
index 7e2e8aa95467..e85918002f13 100644
|
||||
--- a/tools/perf/util/jitdump.c
|
||||
+++ b/tools/perf/util/jitdump.c
|
||||
@@ -581,7 +581,7 @@ static int
|
||||
jit_process_dump(struct jit_buf_desc *jd)
|
||||
{
|
||||
union jr_entry *jr;
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
|
||||
while ((jr = jit_get_next_entry(jd))) {
|
||||
switch(jr->prefix.id) {
|
||||
--
|
||||
2.24.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
||||
From 88a3e7768563e2cc69cac3989baf3e3dc8179f0a Mon Sep 17 00:00:00 2001
|
||||
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
|
||||
Date: Mon, 23 May 2016 18:55:45 +0100
|
||||
Subject: [PATCH 04/14] vmbus: Don't spam the logs with unknown GUIDs
|
||||
|
||||
With Hyper-V sockets device types are introduced on the fly. The pr_info()
|
||||
then prints a message on every connection, which is way too verbose. Since
|
||||
there doesn't seem to be an easy way to check for registered services,
|
||||
disable the pr_info() completely.
|
||||
|
||||
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 9360cdce740e..d838074e9add 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -192,7 +192,6 @@ static u16 hv_get_dev_type(const struct vmbus_channel *channel)
|
||||
if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
|
||||
return i;
|
||||
}
|
||||
- pr_info("Unknown GUID: %pUl\n", guid);
|
||||
return i;
|
||||
}
|
||||
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,48 +0,0 @@
|
||||
From eeb0dec2777fb87ff9d1c4f8401d876866edaea7 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Ng <alexng@messages.microsoft.com>
|
||||
Date: Sun, 6 Nov 2016 13:14:07 -0800
|
||||
Subject: [PATCH 05/14] Drivers: hv: utils: Fix the mapping between host
|
||||
version and protocol to use
|
||||
|
||||
We should intentionally declare the protocols to use for every known host
|
||||
and default to using the latest protocol if the host is unknown or new.
|
||||
|
||||
Signed-off-by: Alex Ng <alexng@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
(cherry picked from commit 3da0401b4d0e17aea7526db0235d98fa535d903e)
|
||||
---
|
||||
drivers/hv/hv_util.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
|
||||
index bcd06306f3e8..e7707747f56d 100644
|
||||
--- a/drivers/hv/hv_util.c
|
||||
+++ b/drivers/hv/hv_util.c
|
||||
@@ -389,16 +389,19 @@ static int util_probe(struct hv_device *dev,
|
||||
ts_srv_version = TS_VERSION_1;
|
||||
hb_srv_version = HB_VERSION_1;
|
||||
break;
|
||||
- case(VERSION_WIN10):
|
||||
+ case VERSION_WIN7:
|
||||
+ case VERSION_WIN8:
|
||||
+ case VERSION_WIN8_1:
|
||||
util_fw_version = UTIL_FW_VERSION;
|
||||
sd_srv_version = SD_VERSION;
|
||||
- ts_srv_version = TS_VERSION;
|
||||
+ ts_srv_version = TS_VERSION_3;
|
||||
hb_srv_version = HB_VERSION;
|
||||
break;
|
||||
+ case VERSION_WIN10:
|
||||
default:
|
||||
util_fw_version = UTIL_FW_VERSION;
|
||||
sd_srv_version = SD_VERSION;
|
||||
- ts_srv_version = TS_VERSION_3;
|
||||
+ ts_srv_version = TS_VERSION;
|
||||
hb_srv_version = HB_VERSION;
|
||||
}
|
||||
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,105 +0,0 @@
|
||||
From a784af34e3903106e3097e7cb43c53f5e26b8e58 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Ng <alexng@messages.microsoft.com>
|
||||
Date: Sun, 6 Nov 2016 13:14:10 -0800
|
||||
Subject: [PATCH 06/14] Drivers: hv: vss: Improve log messages.
|
||||
|
||||
Adding log messages to help troubleshoot error cases and transaction
|
||||
handling.
|
||||
|
||||
Signed-off-by: Alex Ng <alexng@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
(cherry picked from commit 23d2cc0c29eb0e7c6fe4cac88098306c31c40208)
|
||||
---
|
||||
drivers/hv/hv_snapshot.c | 25 +++++++++++++++++++------
|
||||
1 file changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
|
||||
index a6707133c297..5c95ba1e2ecf 100644
|
||||
--- a/drivers/hv/hv_snapshot.c
|
||||
+++ b/drivers/hv/hv_snapshot.c
|
||||
@@ -120,7 +120,7 @@ static int vss_handle_handshake(struct hv_vss_msg *vss_msg)
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
- pr_debug("VSS: userspace daemon ver. %d connected\n", dm_reg_value);
|
||||
+ pr_info("VSS: userspace daemon ver. %d connected\n", dm_reg_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,8 +128,10 @@ static int vss_on_msg(void *msg, int len)
|
||||
{
|
||||
struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;
|
||||
|
||||
- if (len != sizeof(*vss_msg))
|
||||
+ if (len != sizeof(*vss_msg)) {
|
||||
+ pr_debug("VSS: Message size does not match length\n");
|
||||
return -EINVAL;
|
||||
+ }
|
||||
|
||||
if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER ||
|
||||
vss_msg->vss_hdr.operation == VSS_OP_REGISTER1) {
|
||||
@@ -137,8 +139,11 @@ static int vss_on_msg(void *msg, int len)
|
||||
* Don't process registration messages if we're in the middle
|
||||
* of a transaction processing.
|
||||
*/
|
||||
- if (vss_transaction.state > HVUTIL_READY)
|
||||
+ if (vss_transaction.state > HVUTIL_READY) {
|
||||
+ pr_debug("VSS: Got unexpected registration request\n");
|
||||
return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
return vss_handle_handshake(vss_msg);
|
||||
} else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) {
|
||||
vss_transaction.state = HVUTIL_USERSPACE_RECV;
|
||||
@@ -155,7 +160,7 @@ static int vss_on_msg(void *msg, int len)
|
||||
}
|
||||
} else {
|
||||
/* This is a spurious call! */
|
||||
- pr_warn("VSS: Transaction not active\n");
|
||||
+ pr_debug("VSS: Transaction not active\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
@@ -168,8 +173,10 @@ static void vss_send_op(void)
|
||||
struct hv_vss_msg *vss_msg;
|
||||
|
||||
/* The transaction state is wrong. */
|
||||
- if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
|
||||
+ if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED) {
|
||||
+ pr_debug("VSS: Unexpected attempt to send to daemon\n");
|
||||
return;
|
||||
+ }
|
||||
|
||||
vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
|
||||
if (!vss_msg)
|
||||
@@ -210,9 +217,13 @@ static void vss_handle_request(struct work_struct *dummy)
|
||||
case VSS_OP_HOT_BACKUP:
|
||||
if (vss_transaction.state < HVUTIL_READY) {
|
||||
/* Userspace is not registered yet */
|
||||
+ pr_debug("VSS: Not ready for request.\n");
|
||||
vss_respond_to_host(HV_E_FAIL);
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ pr_debug("VSS: Received request for op code: %d\n",
|
||||
+ vss_transaction.msg->vss_hdr.operation);
|
||||
vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
|
||||
vss_send_op();
|
||||
return;
|
||||
@@ -353,8 +364,10 @@ hv_vss_init(struct hv_util_service *srv)
|
||||
|
||||
hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
|
||||
vss_on_msg, vss_on_reset);
|
||||
- if (!hvt)
|
||||
+ if (!hvt) {
|
||||
+ pr_warn("VSS: Failed to initialize transport\n");
|
||||
return -EFAULT;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 8f30ce837fd4cc521dfc071ceba5bd0030645f3d Mon Sep 17 00:00:00 2001
|
||||
From: Alex Ng <alexng@messages.microsoft.com>
|
||||
Date: Sun, 6 Nov 2016 13:14:11 -0800
|
||||
Subject: [PATCH 07/14] Drivers: hv: vss: Operation timeouts should match host
|
||||
expectation
|
||||
|
||||
Increase the timeout of backup operations. When system is under I/O load,
|
||||
it needs more time to freeze. These timeout values should also match the
|
||||
host timeout values more closely.
|
||||
|
||||
Signed-off-by: Alex Ng <alexng@microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
(cherry picked from commit b357fd3908c1191f2f56e38aa77f2aecdae18bc8)
|
||||
---
|
||||
drivers/hv/hv_snapshot.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
|
||||
index 5c95ba1e2ecf..eee238cc60bd 100644
|
||||
--- a/drivers/hv/hv_snapshot.c
|
||||
+++ b/drivers/hv/hv_snapshot.c
|
||||
@@ -31,7 +31,10 @@
|
||||
#define VSS_MINOR 0
|
||||
#define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR)
|
||||
|
||||
-#define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000))
|
||||
+/*
|
||||
+ * Timeout values are based on expecations from host
|
||||
+ */
|
||||
+#define VSS_FREEZE_TIMEOUT (15 * 60)
|
||||
|
||||
/*
|
||||
* Global state maintained for transaction that is being processed. For a class
|
||||
@@ -186,7 +189,8 @@ static void vss_send_op(void)
|
||||
|
||||
vss_transaction.state = HVUTIL_USERSPACE_REQ;
|
||||
|
||||
- schedule_delayed_work(&vss_timeout_work, VSS_USERSPACE_TIMEOUT);
|
||||
+ schedule_delayed_work(&vss_timeout_work, op == VSS_OP_FREEZE ?
|
||||
+ VSS_FREEZE_TIMEOUT * HZ : HV_UTIL_TIMEOUT * HZ);
|
||||
|
||||
rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
|
||||
if (rc) {
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,492 +0,0 @@
|
||||
From efb4cdb8f07aec5a3f9d8495b896bb48fbba08e1 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Ng <alexng@messages.microsoft.com>
|
||||
Date: Sat, 28 Jan 2017 12:37:17 -0700
|
||||
Subject: [PATCH 08/14] Drivers: hv: vmbus: Use all supported IC versions to
|
||||
negotiate
|
||||
|
||||
Previously, we were assuming that each IC protocol version was tied to a
|
||||
specific host version. For example, some Windows 10 preview hosts only
|
||||
support v3 TimeSync even though driver assumes v4 is supported by all
|
||||
Windows 10 hosts.
|
||||
|
||||
The guest will stop trying to negotiate even though older supported
|
||||
versions may still be offered by the host.
|
||||
|
||||
Make IC version negotiation more robust by going through all versions
|
||||
that are supported by the guest.
|
||||
|
||||
Fixes: 3da0401b4d0e ("Drivers: hv: utils: Fix the mapping between host
|
||||
version and protocol to use")
|
||||
|
||||
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
|
||||
Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
(cherry picked from commit a1656454131880980bc3a5313c8bf66ef5990c91)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 80 ++++++++++++++++++++++-----------
|
||||
drivers/hv/hv_fcopy.c | 20 ++++++---
|
||||
drivers/hv/hv_kvp.c | 41 +++++++----------
|
||||
drivers/hv/hv_snapshot.c | 18 ++++++--
|
||||
drivers/hv/hv_util.c | 94 +++++++++++++++++++++------------------
|
||||
include/linux/hyperv.h | 7 +--
|
||||
6 files changed, 154 insertions(+), 106 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index d838074e9add..095dd37367de 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -202,33 +202,34 @@ static u16 hv_get_dev_type(const struct vmbus_channel *channel)
|
||||
* @buf: Raw buffer channel data
|
||||
*
|
||||
* @icmsghdrp is of type &struct icmsg_hdr.
|
||||
- * @negop is of type &struct icmsg_negotiate.
|
||||
* Set up and fill in default negotiate response message.
|
||||
*
|
||||
- * The fw_version specifies the framework version that
|
||||
- * we can support and srv_version specifies the service
|
||||
- * version we can support.
|
||||
+ * The fw_version and fw_vercnt specifies the framework version that
|
||||
+ * we can support.
|
||||
+ *
|
||||
+ * The srv_version and srv_vercnt specifies the service
|
||||
+ * versions we can support.
|
||||
+ *
|
||||
+ * Versions are given in decreasing order.
|
||||
+ *
|
||||
+ * nego_fw_version and nego_srv_version store the selected protocol versions.
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
- struct icmsg_negotiate *negop, u8 *buf,
|
||||
- int fw_version, int srv_version)
|
||||
+ u8 *buf, const int *fw_version, int fw_vercnt,
|
||||
+ const int *srv_version, int srv_vercnt,
|
||||
+ int *nego_fw_version, int *nego_srv_version)
|
||||
{
|
||||
int icframe_major, icframe_minor;
|
||||
int icmsg_major, icmsg_minor;
|
||||
int fw_major, fw_minor;
|
||||
int srv_major, srv_minor;
|
||||
- int i;
|
||||
+ int i, j;
|
||||
bool found_match = false;
|
||||
+ struct icmsg_negotiate *negop;
|
||||
|
||||
icmsghdrp->icmsgsize = 0x10;
|
||||
- fw_major = (fw_version >> 16);
|
||||
- fw_minor = (fw_version & 0xFFFF);
|
||||
-
|
||||
- srv_major = (srv_version >> 16);
|
||||
- srv_minor = (srv_version & 0xFFFF);
|
||||
-
|
||||
negop = (struct icmsg_negotiate *)&buf[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
sizeof(struct icmsg_hdr)];
|
||||
@@ -244,13 +245,22 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
* support.
|
||||
*/
|
||||
|
||||
- for (i = 0; i < negop->icframe_vercnt; i++) {
|
||||
- if ((negop->icversion_data[i].major == fw_major) &&
|
||||
- (negop->icversion_data[i].minor == fw_minor)) {
|
||||
- icframe_major = negop->icversion_data[i].major;
|
||||
- icframe_minor = negop->icversion_data[i].minor;
|
||||
- found_match = true;
|
||||
+ for (i = 0; i < fw_vercnt; i++) {
|
||||
+ fw_major = (fw_version[i] >> 16);
|
||||
+ fw_minor = (fw_version[i] & 0xFFFF);
|
||||
+
|
||||
+ for (j = 0; j < negop->icframe_vercnt; j++) {
|
||||
+ if ((negop->icversion_data[j].major == fw_major) &&
|
||||
+ (negop->icversion_data[j].minor == fw_minor)) {
|
||||
+ icframe_major = negop->icversion_data[j].major;
|
||||
+ icframe_minor = negop->icversion_data[j].minor;
|
||||
+ found_match = true;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (found_match)
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (!found_match)
|
||||
@@ -258,14 +268,26 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
|
||||
found_match = false;
|
||||
|
||||
- for (i = negop->icframe_vercnt;
|
||||
- (i < negop->icframe_vercnt + negop->icmsg_vercnt); i++) {
|
||||
- if ((negop->icversion_data[i].major == srv_major) &&
|
||||
- (negop->icversion_data[i].minor == srv_minor)) {
|
||||
- icmsg_major = negop->icversion_data[i].major;
|
||||
- icmsg_minor = negop->icversion_data[i].minor;
|
||||
- found_match = true;
|
||||
+ for (i = 0; i < srv_vercnt; i++) {
|
||||
+ srv_major = (srv_version[i] >> 16);
|
||||
+ srv_minor = (srv_version[i] & 0xFFFF);
|
||||
+
|
||||
+ for (j = negop->icframe_vercnt;
|
||||
+ (j < negop->icframe_vercnt + negop->icmsg_vercnt);
|
||||
+ j++) {
|
||||
+
|
||||
+ if ((negop->icversion_data[j].major == srv_major) &&
|
||||
+ (negop->icversion_data[j].minor == srv_minor)) {
|
||||
+
|
||||
+ icmsg_major = negop->icversion_data[j].major;
|
||||
+ icmsg_minor = negop->icversion_data[j].minor;
|
||||
+ found_match = true;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (found_match)
|
||||
+ break;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -282,6 +304,12 @@ bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
negop->icmsg_vercnt = 1;
|
||||
}
|
||||
|
||||
+ if (nego_fw_version)
|
||||
+ *nego_fw_version = (icframe_major << 16) | icframe_minor;
|
||||
+
|
||||
+ if (nego_srv_version)
|
||||
+ *nego_srv_version = (icmsg_major << 16) | icmsg_minor;
|
||||
+
|
||||
negop->icversion_data[0].major = icframe_major;
|
||||
negop->icversion_data[0].minor = icframe_minor;
|
||||
negop->icversion_data[1].major = icmsg_major;
|
||||
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
|
||||
index 44420073edda..f1e0d0358206 100644
|
||||
--- a/drivers/hv/hv_fcopy.c
|
||||
+++ b/drivers/hv/hv_fcopy.c
|
||||
@@ -31,6 +31,16 @@
|
||||
#define WIN8_SRV_MINOR 1
|
||||
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
|
||||
|
||||
+#define FCOPY_VER_COUNT 1
|
||||
+static const int fcopy_versions[] = {
|
||||
+ WIN8_SRV_VERSION
|
||||
+};
|
||||
+
|
||||
+#define FW_VER_COUNT 1
|
||||
+static const int fw_versions[] = {
|
||||
+ UTIL_FW_VERSION
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Global state maintained for transaction that is being processed.
|
||||
* For a class of integration services, including the "file copy service",
|
||||
@@ -231,8 +241,6 @@ void hv_fcopy_onchannelcallback(void *context)
|
||||
u64 requestid;
|
||||
struct hv_fcopy_hdr *fcopy_msg;
|
||||
struct icmsg_hdr *icmsghdr;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
- int util_fw_version;
|
||||
int fcopy_srv_version;
|
||||
|
||||
if (fcopy_transaction.state > HVUTIL_READY)
|
||||
@@ -246,10 +254,10 @@ void hv_fcopy_onchannelcallback(void *context)
|
||||
icmsghdr = (struct icmsg_hdr *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- util_fw_version = UTIL_FW_VERSION;
|
||||
- fcopy_srv_version = WIN8_SRV_VERSION;
|
||||
- vmbus_prep_negotiate_resp(icmsghdr, negop, recv_buffer,
|
||||
- util_fw_version, fcopy_srv_version);
|
||||
+ vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
|
||||
+ fw_versions, FW_VER_COUNT,
|
||||
+ fcopy_versions, FCOPY_VER_COUNT,
|
||||
+ NULL, &fcopy_srv_version);
|
||||
} else {
|
||||
fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
|
||||
index 2fd0f119a67b..820d4cd71fa9 100644
|
||||
--- a/drivers/hv/hv_kvp.c
|
||||
+++ b/drivers/hv/hv_kvp.c
|
||||
@@ -46,6 +46,19 @@
|
||||
#define WIN8_SRV_MINOR 0
|
||||
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
|
||||
|
||||
+#define KVP_VER_COUNT 3
|
||||
+static const int kvp_versions[] = {
|
||||
+ WIN8_SRV_VERSION,
|
||||
+ WIN7_SRV_VERSION,
|
||||
+ WS2008_SRV_VERSION
|
||||
+};
|
||||
+
|
||||
+#define FW_VER_COUNT 2
|
||||
+static const int fw_versions[] = {
|
||||
+ UTIL_FW_VERSION,
|
||||
+ UTIL_WS2K8_FW_VERSION
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Global state maintained for transaction that is being processed. For a class
|
||||
* of integration services, including the "KVP service", the specified protocol
|
||||
@@ -609,8 +622,6 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
struct hv_kvp_msg *kvp_msg;
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
- int util_fw_version;
|
||||
int kvp_srv_version;
|
||||
static enum {NEGO_NOT_STARTED,
|
||||
NEGO_IN_PROGRESS,
|
||||
@@ -640,28 +651,10 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- /*
|
||||
- * Based on the host, select appropriate
|
||||
- * framework and service versions we will
|
||||
- * negotiate.
|
||||
- */
|
||||
- switch (vmbus_proto_version) {
|
||||
- case (VERSION_WS2008):
|
||||
- util_fw_version = UTIL_WS2K8_FW_VERSION;
|
||||
- kvp_srv_version = WS2008_SRV_VERSION;
|
||||
- break;
|
||||
- case (VERSION_WIN7):
|
||||
- util_fw_version = UTIL_FW_VERSION;
|
||||
- kvp_srv_version = WIN7_SRV_VERSION;
|
||||
- break;
|
||||
- default:
|
||||
- util_fw_version = UTIL_FW_VERSION;
|
||||
- kvp_srv_version = WIN8_SRV_VERSION;
|
||||
- }
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
|
||||
- recv_buffer, util_fw_version,
|
||||
- kvp_srv_version);
|
||||
-
|
||||
+ vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
+ recv_buffer, fw_versions, FW_VER_COUNT,
|
||||
+ kvp_versions, KVP_VER_COUNT,
|
||||
+ NULL, &kvp_srv_version);
|
||||
} else {
|
||||
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
|
||||
index eee238cc60bd..8e62bf7f6265 100644
|
||||
--- a/drivers/hv/hv_snapshot.c
|
||||
+++ b/drivers/hv/hv_snapshot.c
|
||||
@@ -31,6 +31,16 @@
|
||||
#define VSS_MINOR 0
|
||||
#define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR)
|
||||
|
||||
+#define VSS_VER_COUNT 1
|
||||
+static const int vss_versions[] = {
|
||||
+ VSS_VERSION
|
||||
+};
|
||||
+
|
||||
+#define FW_VER_COUNT 1
|
||||
+static const int fw_versions[] = {
|
||||
+ UTIL_FW_VERSION
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Timeout values are based on expecations from host
|
||||
*/
|
||||
@@ -296,7 +306,6 @@ void hv_vss_onchannelcallback(void *context)
|
||||
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
if (vss_transaction.state > HVUTIL_READY)
|
||||
return;
|
||||
@@ -309,9 +318,10 @@ void hv_vss_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
|
||||
- recv_buffer, UTIL_FW_VERSION,
|
||||
- VSS_VERSION);
|
||||
+ vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
+ recv_buffer, fw_versions, FW_VER_COUNT,
|
||||
+ vss_versions, VSS_VER_COUNT,
|
||||
+ NULL, NULL);
|
||||
} else {
|
||||
vss_msg = (struct hv_vss_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
|
||||
index e7707747f56d..f3797c07be10 100644
|
||||
--- a/drivers/hv/hv_util.c
|
||||
+++ b/drivers/hv/hv_util.c
|
||||
@@ -57,7 +57,31 @@
|
||||
static int sd_srv_version;
|
||||
static int ts_srv_version;
|
||||
static int hb_srv_version;
|
||||
-static int util_fw_version;
|
||||
+
|
||||
+#define SD_VER_COUNT 2
|
||||
+static const int sd_versions[] = {
|
||||
+ SD_VERSION,
|
||||
+ SD_VERSION_1
|
||||
+};
|
||||
+
|
||||
+#define TS_VER_COUNT 3
|
||||
+static const int ts_versions[] = {
|
||||
+ TS_VERSION,
|
||||
+ TS_VERSION_3,
|
||||
+ TS_VERSION_1
|
||||
+};
|
||||
+
|
||||
+#define HB_VER_COUNT 2
|
||||
+static const int hb_versions[] = {
|
||||
+ HB_VERSION,
|
||||
+ HB_VERSION_1
|
||||
+};
|
||||
+
|
||||
+#define FW_VER_COUNT 2
|
||||
+static const int fw_versions[] = {
|
||||
+ UTIL_FW_VERSION,
|
||||
+ UTIL_WS2K8_FW_VERSION
|
||||
+};
|
||||
|
||||
static void shutdown_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_shutdown = {
|
||||
@@ -118,7 +142,6 @@ static void shutdown_onchannelcallback(void *context)
|
||||
struct shutdown_msg_data *shutdown_msg;
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
vmbus_recvpacket(channel, shut_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@@ -128,9 +151,14 @@ static void shutdown_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
|
||||
- shut_txf_buf, util_fw_version,
|
||||
- sd_srv_version);
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdrp, shut_txf_buf,
|
||||
+ fw_versions, FW_VER_COUNT,
|
||||
+ sd_versions, SD_VER_COUNT,
|
||||
+ NULL, &sd_srv_version)) {
|
||||
+ pr_info("Shutdown IC version %d.%d\n",
|
||||
+ sd_srv_version >> 16,
|
||||
+ sd_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
shutdown_msg =
|
||||
(struct shutdown_msg_data *)&shut_txf_buf[
|
||||
@@ -253,7 +281,6 @@ static void timesync_onchannelcallback(void *context)
|
||||
struct ictimesync_data *timedatap;
|
||||
struct ictimesync_ref_data *refdata;
|
||||
u8 *time_txf_buf = util_timesynch.recv_buffer;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
vmbus_recvpacket(channel, time_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@@ -263,12 +290,14 @@ static void timesync_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
|
||||
- time_txf_buf,
|
||||
- util_fw_version,
|
||||
- ts_srv_version);
|
||||
- pr_info("Using TimeSync version %d.%d\n",
|
||||
- ts_srv_version >> 16, ts_srv_version & 0xFFFF);
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdrp, time_txf_buf,
|
||||
+ fw_versions, FW_VER_COUNT,
|
||||
+ ts_versions, TS_VER_COUNT,
|
||||
+ NULL, &ts_srv_version)) {
|
||||
+ pr_info("TimeSync version %d.%d\n",
|
||||
+ ts_srv_version >> 16,
|
||||
+ ts_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
if (ts_srv_version > TS_VERSION_3) {
|
||||
refdata = (struct ictimesync_ref_data *)
|
||||
@@ -312,7 +341,6 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct heartbeat_msg_data *heartbeat_msg;
|
||||
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
while (1) {
|
||||
|
||||
@@ -326,9 +354,16 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
|
||||
- hbeat_txf_buf, util_fw_version,
|
||||
- hb_srv_version);
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
+ hbeat_txf_buf,
|
||||
+ fw_versions, FW_VER_COUNT,
|
||||
+ hb_versions, HB_VER_COUNT,
|
||||
+ NULL, &hb_srv_version)) {
|
||||
+
|
||||
+ pr_info("Heartbeat version %d.%d\n",
|
||||
+ hb_srv_version >> 16,
|
||||
+ hb_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
heartbeat_msg =
|
||||
(struct heartbeat_msg_data *)&hbeat_txf_buf[
|
||||
@@ -378,33 +413,6 @@ static int util_probe(struct hv_device *dev,
|
||||
|
||||
hv_set_drvdata(dev, srv);
|
||||
|
||||
- /*
|
||||
- * Based on the host; initialize the framework and
|
||||
- * service version numbers we will negotiate.
|
||||
- */
|
||||
- switch (vmbus_proto_version) {
|
||||
- case (VERSION_WS2008):
|
||||
- util_fw_version = UTIL_WS2K8_FW_VERSION;
|
||||
- sd_srv_version = SD_VERSION_1;
|
||||
- ts_srv_version = TS_VERSION_1;
|
||||
- hb_srv_version = HB_VERSION_1;
|
||||
- break;
|
||||
- case VERSION_WIN7:
|
||||
- case VERSION_WIN8:
|
||||
- case VERSION_WIN8_1:
|
||||
- util_fw_version = UTIL_FW_VERSION;
|
||||
- sd_srv_version = SD_VERSION;
|
||||
- ts_srv_version = TS_VERSION_3;
|
||||
- hb_srv_version = HB_VERSION;
|
||||
- break;
|
||||
- case VERSION_WIN10:
|
||||
- default:
|
||||
- util_fw_version = UTIL_FW_VERSION;
|
||||
- sd_srv_version = SD_VERSION;
|
||||
- ts_srv_version = TS_VERSION;
|
||||
- hb_srv_version = HB_VERSION;
|
||||
- }
|
||||
-
|
||||
ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
|
||||
srv->util_cb, dev->channel);
|
||||
if (ret)
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index c9af8369b4f7..7df9eb8f0cf7 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1453,9 +1453,10 @@ struct hyperv_service_callback {
|
||||
};
|
||||
|
||||
#define MAX_SRV_VER 0x7ffffff
|
||||
-extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
|
||||
- struct icmsg_negotiate *, u8 *, int,
|
||||
- int);
|
||||
+extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
|
||||
+ const int *fw_version, int fw_vercnt,
|
||||
+ const int *srv_version, int srv_vercnt,
|
||||
+ int *nego_fw_version, int *nego_srv_version);
|
||||
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel);
|
||||
void hv_event_tasklet_enable(struct vmbus_channel *channel);
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,118 +0,0 @@
|
||||
From 4ececf204f51b6789d273f56ef4011272eb6286a Mon Sep 17 00:00:00 2001
|
||||
From: Alex Ng <alexng@messages.microsoft.com>
|
||||
Date: Sat, 28 Jan 2017 12:37:18 -0700
|
||||
Subject: [PATCH 09/14] Drivers: hv: Log the negotiated IC versions.
|
||||
|
||||
Log the negotiated IC versions.
|
||||
|
||||
Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
(cherry picked from commit 1274a690f6b2bd2b37447c47e3062afa8aa43f93)
|
||||
---
|
||||
drivers/hv/hv_fcopy.c | 9 +++++++--
|
||||
drivers/hv/hv_kvp.c | 8 ++++++--
|
||||
drivers/hv/hv_snapshot.c | 11 ++++++++---
|
||||
drivers/hv/hv_util.c | 4 ++--
|
||||
4 files changed, 23 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
|
||||
index f1e0d0358206..e0ce0753c568 100644
|
||||
--- a/drivers/hv/hv_fcopy.c
|
||||
+++ b/drivers/hv/hv_fcopy.c
|
||||
@@ -254,10 +254,15 @@ void hv_fcopy_onchannelcallback(void *context)
|
||||
icmsghdr = (struct icmsg_hdr *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdr, recv_buffer,
|
||||
fw_versions, FW_VER_COUNT,
|
||||
fcopy_versions, FCOPY_VER_COUNT,
|
||||
- NULL, &fcopy_srv_version);
|
||||
+ NULL, &fcopy_srv_version)) {
|
||||
+
|
||||
+ pr_info("FCopy IC version %d.%d\n",
|
||||
+ fcopy_srv_version >> 16,
|
||||
+ fcopy_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
|
||||
index 820d4cd71fa9..18c4deb39f41 100644
|
||||
--- a/drivers/hv/hv_kvp.c
|
||||
+++ b/drivers/hv/hv_kvp.c
|
||||
@@ -651,10 +651,14 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
recv_buffer, fw_versions, FW_VER_COUNT,
|
||||
kvp_versions, KVP_VER_COUNT,
|
||||
- NULL, &kvp_srv_version);
|
||||
+ NULL, &kvp_srv_version)) {
|
||||
+ pr_info("KVP IC version %d.%d\n",
|
||||
+ kvp_srv_version >> 16,
|
||||
+ kvp_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
|
||||
index 8e62bf7f6265..e659d1b94a57 100644
|
||||
--- a/drivers/hv/hv_snapshot.c
|
||||
+++ b/drivers/hv/hv_snapshot.c
|
||||
@@ -303,7 +303,7 @@ void hv_vss_onchannelcallback(void *context)
|
||||
u32 recvlen;
|
||||
u64 requestid;
|
||||
struct hv_vss_msg *vss_msg;
|
||||
-
|
||||
+ int vss_srv_version;
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
|
||||
@@ -318,10 +318,15 @@ void hv_vss_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
- vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
+ if (vmbus_prep_negotiate_resp(icmsghdrp,
|
||||
recv_buffer, fw_versions, FW_VER_COUNT,
|
||||
vss_versions, VSS_VER_COUNT,
|
||||
- NULL, NULL);
|
||||
+ NULL, &vss_srv_version)) {
|
||||
+
|
||||
+ pr_info("VSS IC version %d.%d\n",
|
||||
+ vss_srv_version >> 16,
|
||||
+ vss_srv_version & 0xFFFF);
|
||||
+ }
|
||||
} else {
|
||||
vss_msg = (struct hv_vss_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
|
||||
index f3797c07be10..89440c2eb346 100644
|
||||
--- a/drivers/hv/hv_util.c
|
||||
+++ b/drivers/hv/hv_util.c
|
||||
@@ -294,7 +294,7 @@ static void timesync_onchannelcallback(void *context)
|
||||
fw_versions, FW_VER_COUNT,
|
||||
ts_versions, TS_VER_COUNT,
|
||||
NULL, &ts_srv_version)) {
|
||||
- pr_info("TimeSync version %d.%d\n",
|
||||
+ pr_info("TimeSync IC version %d.%d\n",
|
||||
ts_srv_version >> 16,
|
||||
ts_srv_version & 0xFFFF);
|
||||
}
|
||||
@@ -360,7 +360,7 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
hb_versions, HB_VER_COUNT,
|
||||
NULL, &hb_srv_version)) {
|
||||
|
||||
- pr_info("Heartbeat version %d.%d\n",
|
||||
+ pr_info("Heartbeat IC version %d.%d\n",
|
||||
hb_srv_version >> 16,
|
||||
hb_srv_version & 0xFFFF);
|
||||
}
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 9437b5fd5eb5570a82f7c79672007240ba866966 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Sun, 26 Mar 2017 16:42:20 +0800
|
||||
Subject: [PATCH 10/14] vmbus: fix missed ring events on boot
|
||||
|
||||
During initialization, the channel initialization code schedules the
|
||||
tasklet to scan the VMBUS receive event page (i.e. simulates an
|
||||
interrupt). The problem was that it invokes the tasklet on a different
|
||||
CPU from where it normally runs and therefore if an event is present,
|
||||
it will clear the bit but not find the associated channel.
|
||||
|
||||
This can lead to missed events, typically stuck tasks, during bootup
|
||||
when sub channels are being initialized. Typically seen as stuck
|
||||
boot with 8 or more CPU's.
|
||||
|
||||
This patch is not necessary for upstream (4.11 and later) since
|
||||
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
|
||||
This changed vmbus code to get rid of common tasklet which
|
||||
caused the problem.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 638fea33aee8 ("Drivers: hv: vmbus: fix the race when querying & updating the percpu list")
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit 5cf3a72a111cecc7da759542c56560ce509159d7)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 095dd37367de..effac8042dc6 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -388,8 +388,17 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel)
|
||||
tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||
tasklet_enable(tasklet);
|
||||
|
||||
- /* In case there is any pending event */
|
||||
- tasklet_schedule(tasklet);
|
||||
+ /*
|
||||
+ * In case there is any pending event schedule a rescan
|
||||
+ * but must be on the correct CPU for the channel.
|
||||
+ */
|
||||
+ if (channel->target_cpu == get_cpu())
|
||||
+ tasklet_schedule(tasklet);
|
||||
+ else
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ (smp_call_func_t)tasklet_schedule,
|
||||
+ tasklet, false);
|
||||
+ put_cpu();
|
||||
}
|
||||
|
||||
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 59bdf5a956bb431016fb00b135952d62ab8017af Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 29 Mar 2017 18:37:10 +0800
|
||||
Subject: [PATCH 11/14] vmbus: remove "goto error_clean_msglist" in
|
||||
vmbus_open()
|
||||
|
||||
This is just a cleanup patch to simplify the code a little.
|
||||
No semantic change.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit 2c89f21cbdfd39299482cd6068094097a45f13b3)
|
||||
---
|
||||
drivers/hv/channel.c | 18 +++++++-----------
|
||||
1 file changed, 7 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 784c45484825..fb94b96e8469 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -184,17 +184,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel), true);
|
||||
|
||||
- if (ret != 0) {
|
||||
- err = ret;
|
||||
- goto error_clean_msglist;
|
||||
- }
|
||||
-
|
||||
- wait_for_completion(&open_info->waitevent);
|
||||
+ if (ret == 0)
|
||||
+ wait_for_completion(&open_info->waitevent);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
+ if (ret != 0) {
|
||||
+ err = ret;
|
||||
+ goto error_free_gpadl;
|
||||
+ }
|
||||
+
|
||||
if (newchannel->rescind) {
|
||||
err = -ENODEV;
|
||||
goto error_free_gpadl;
|
||||
@@ -209,11 +210,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
kfree(open_info);
|
||||
return 0;
|
||||
|
||||
-error_clean_msglist:
|
||||
- spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
- list_del(&open_info->msglistentry);
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
-
|
||||
error_free_gpadl:
|
||||
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||
kfree(open_info);
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,177 +0,0 @@
|
||||
From b42442dd3866916eaa11904b9d92b35bec5231c7 Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Fri, 24 Mar 2017 20:53:18 +0800
|
||||
Subject: [PATCH 12/14] vmbus: dynamically enqueue/dequeue the channel on
|
||||
vmbus_open/close
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit bee4910daa4aed57ce60d2e2350e3cc120c383ca)
|
||||
---
|
||||
drivers/hv/channel.c | 16 +++++++++--
|
||||
drivers/hv/channel_mgmt.c | 58 ++++++++++++++++-----------------------
|
||||
include/linux/hyperv.h | 3 ++
|
||||
3 files changed, 40 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index fb94b96e8469..22e62fe70de3 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -181,6 +181,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
&vmbus_connection.chn_msg_list);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
+ hv_event_tasklet_disable(newchannel);
|
||||
+ hv_percpu_channel_enq(newchannel);
|
||||
+ hv_event_tasklet_enable(newchannel);
|
||||
+
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel), true);
|
||||
|
||||
@@ -193,23 +197,27 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
|
||||
if (ret != 0) {
|
||||
err = ret;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
if (newchannel->rescind) {
|
||||
err = -ENODEV;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
if (open_info->response.open_result.status) {
|
||||
err = -EAGAIN;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
newchannel->state = CHANNEL_OPENED_STATE;
|
||||
kfree(open_info);
|
||||
return 0;
|
||||
|
||||
+error_deq_channel:
|
||||
+ hv_event_tasklet_disable(newchannel);
|
||||
+ hv_percpu_channel_deq(newchannel);
|
||||
+ hv_event_tasklet_enable(newchannel);
|
||||
error_free_gpadl:
|
||||
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||
kfree(open_info);
|
||||
@@ -563,6 +571,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ hv_percpu_channel_deq(channel);
|
||||
+
|
||||
channel->state = CHANNEL_OPEN_STATE;
|
||||
channel->sc_creation_callback = NULL;
|
||||
/* Stop callback and cancel the timer asap */
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index effac8042dc6..5470eeaf3f45 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -375,6 +375,30 @@ static void vmbus_release_relid(u32 relid)
|
||||
true);
|
||||
}
|
||||
|
||||
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
|
||||
+{
|
||||
+ if (channel->target_cpu != get_cpu())
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ percpu_channel_enq,
|
||||
+ channel, true);
|
||||
+ else
|
||||
+ percpu_channel_enq(channel);
|
||||
+ put_cpu();
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
|
||||
+{
|
||||
+ if (channel->target_cpu != get_cpu())
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ percpu_channel_deq,
|
||||
+ channel, true);
|
||||
+ else
|
||||
+ percpu_channel_deq(channel);
|
||||
+ put_cpu();
|
||||
+
|
||||
+}
|
||||
+
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel)
|
||||
{
|
||||
struct tasklet_struct *tasklet;
|
||||
@@ -409,17 +433,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
BUG_ON(!channel->rescind);
|
||||
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||
|
||||
- hv_event_tasklet_disable(channel);
|
||||
- if (channel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(channel->target_cpu,
|
||||
- percpu_channel_deq, channel, true);
|
||||
- } else {
|
||||
- percpu_channel_deq(channel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(channel);
|
||||
-
|
||||
if (channel->primary_channel == NULL) {
|
||||
list_del(&channel->listentry);
|
||||
|
||||
@@ -512,18 +525,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
|
||||
init_vp_index(newchannel, dev_type);
|
||||
|
||||
- hv_event_tasklet_disable(newchannel);
|
||||
- if (newchannel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(newchannel->target_cpu,
|
||||
- percpu_channel_enq,
|
||||
- newchannel, true);
|
||||
- } else {
|
||||
- percpu_channel_enq(newchannel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(newchannel);
|
||||
-
|
||||
/*
|
||||
* This state is used to indicate a successful open
|
||||
* so that when we do close the channel normally, we
|
||||
@@ -572,17 +573,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
list_del(&newchannel->listentry);
|
||||
mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
- hv_event_tasklet_disable(newchannel);
|
||||
- if (newchannel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(newchannel->target_cpu,
|
||||
- percpu_channel_deq, newchannel, true);
|
||||
- } else {
|
||||
- percpu_channel_deq(newchannel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(newchannel);
|
||||
-
|
||||
vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||
|
||||
err_free_chan:
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 7df9eb8f0cf7..a87757cf277b 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1461,6 +1461,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel);
|
||||
void hv_event_tasklet_enable(struct vmbus_channel *channel);
|
||||
|
||||
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
|
||||
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
|
||||
+
|
||||
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||
|
||||
void vmbus_setevent(struct vmbus_channel *channel);
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,142 +0,0 @@
|
||||
From 6dbc83e7d8729d2af84a769107e1c02963407fc9 Mon Sep 17 00:00:00 2001
|
||||
From: Ido Schimmel <idosch@mellanox.com>
|
||||
Date: Mon, 10 Apr 2017 14:59:27 +0300
|
||||
Subject: [PATCH 13/14] bridge: implement missing ndo_uninit()
|
||||
|
||||
While the bridge driver implements an ndo_init(), it was missing a
|
||||
symmetric ndo_uninit(), causing the different de-initialization
|
||||
operations to be scattered around its dellink() and destructor().
|
||||
|
||||
Implement a symmetric ndo_uninit() and remove the overlapping operations
|
||||
from its dellink() and destructor().
|
||||
|
||||
This is a prerequisite for the next patch, as it allows us to have a
|
||||
proper cleanup upon changelink() failure during the bridge's newlink().
|
||||
|
||||
Fixes: b6677449dff6 ("bridge: netlink: call br_changelink() during br_dev_newlink()")
|
||||
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
(cherry picked from commit b6fe0440c63716e09cfc0d1484e3898a0f29d1d1)
|
||||
---
|
||||
net/bridge/br_device.c | 20 +++++++++++---------
|
||||
net/bridge/br_if.c | 1 -
|
||||
net/bridge/br_multicast.c | 7 +++++--
|
||||
net/bridge/br_private.h | 5 +++++
|
||||
4 files changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
|
||||
index 5f5e28f210e0..15be72678bc8 100644
|
||||
--- a/net/bridge/br_device.c
|
||||
+++ b/net/bridge/br_device.c
|
||||
@@ -122,6 +122,15 @@ static int br_dev_init(struct net_device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
+static void br_dev_uninit(struct net_device *dev)
|
||||
+{
|
||||
+ struct net_bridge *br = netdev_priv(dev);
|
||||
+
|
||||
+ br_multicast_uninit_stats(br);
|
||||
+ br_vlan_flush(br);
|
||||
+ free_percpu(br->stats);
|
||||
+}
|
||||
+
|
||||
static int br_dev_open(struct net_device *dev)
|
||||
{
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
@@ -337,6 +346,7 @@ static const struct net_device_ops br_netdev_ops = {
|
||||
.ndo_open = br_dev_open,
|
||||
.ndo_stop = br_dev_stop,
|
||||
.ndo_init = br_dev_init,
|
||||
+ .ndo_uninit = br_dev_uninit,
|
||||
.ndo_start_xmit = br_dev_xmit,
|
||||
.ndo_get_stats64 = br_get_stats64,
|
||||
.ndo_set_mac_address = br_set_mac_address,
|
||||
@@ -363,14 +373,6 @@ static const struct net_device_ops br_netdev_ops = {
|
||||
.ndo_features_check = passthru_features_check,
|
||||
};
|
||||
|
||||
-static void br_dev_free(struct net_device *dev)
|
||||
-{
|
||||
- struct net_bridge *br = netdev_priv(dev);
|
||||
-
|
||||
- free_percpu(br->stats);
|
||||
- free_netdev(dev);
|
||||
-}
|
||||
-
|
||||
static struct device_type br_type = {
|
||||
.name = "bridge",
|
||||
};
|
||||
@@ -383,7 +385,7 @@ void br_dev_setup(struct net_device *dev)
|
||||
ether_setup(dev);
|
||||
|
||||
dev->netdev_ops = &br_netdev_ops;
|
||||
- dev->destructor = br_dev_free;
|
||||
+ dev->destructor = free_netdev;
|
||||
dev->ethtool_ops = &br_ethtool_ops;
|
||||
SET_NETDEV_DEVTYPE(dev, &br_type);
|
||||
dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
|
||||
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
|
||||
index 925818a05398..191b1f23c160 100644
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -311,7 +311,6 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
|
||||
|
||||
br_fdb_delete_by_port(br, NULL, 0, 1);
|
||||
|
||||
- br_vlan_flush(br);
|
||||
br_multicast_dev_del(br);
|
||||
del_timer_sync(&br->gc_timer);
|
||||
|
||||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
|
||||
index 80c81c7e3cf9..8b3a5dfa4e7f 100644
|
||||
--- a/net/bridge/br_multicast.c
|
||||
+++ b/net/bridge/br_multicast.c
|
||||
@@ -1905,8 +1905,6 @@ void br_multicast_dev_del(struct net_bridge *br)
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&br->multicast_lock);
|
||||
-
|
||||
- free_percpu(br->mcast_stats);
|
||||
}
|
||||
|
||||
int br_multicast_set_router(struct net_bridge *br, unsigned long val)
|
||||
@@ -2363,6 +2361,11 @@ int br_multicast_init_stats(struct net_bridge *br)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void br_multicast_uninit_stats(struct net_bridge *br)
|
||||
+{
|
||||
+ free_percpu(br->mcast_stats);
|
||||
+}
|
||||
+
|
||||
static void mcast_stats_add_dir(u64 *dst, u64 *src)
|
||||
{
|
||||
dst[BR_MCAST_DIR_RX] += src[BR_MCAST_DIR_RX];
|
||||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
|
||||
index 1b63177e0ccd..417edbe7b8b2 100644
|
||||
--- a/net/bridge/br_private.h
|
||||
+++ b/net/bridge/br_private.h
|
||||
@@ -601,6 +601,7 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
|
||||
void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p,
|
||||
const struct sk_buff *skb, u8 type, u8 dir);
|
||||
int br_multicast_init_stats(struct net_bridge *br);
|
||||
+void br_multicast_uninit_stats(struct net_bridge *br);
|
||||
void br_multicast_get_stats(const struct net_bridge *br,
|
||||
const struct net_bridge_port *p,
|
||||
struct br_mcast_stats *dest);
|
||||
@@ -741,6 +742,10 @@ static inline int br_multicast_init_stats(struct net_bridge *br)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline void br_multicast_uninit_stats(struct net_bridge *br)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
static inline int br_multicast_igmp_type(const struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,109 +0,0 @@
|
||||
From 41661998f27ab61e9b5a134375ecb8c007c57c11 Mon Sep 17 00:00:00 2001
|
||||
From: Xin Long <lucien.xin@gmail.com>
|
||||
Date: Tue, 25 Apr 2017 22:58:37 +0800
|
||||
Subject: [PATCH 14/14] bridge: move bridge multicast cleanup to ndo_uninit
|
||||
|
||||
During removing a bridge device, if the bridge is still up, a new mdb entry
|
||||
still can be added in br_multicast_add_group() after all mdb entries are
|
||||
removed in br_multicast_dev_del(). Like the path:
|
||||
|
||||
mld_ifc_timer_expire ->
|
||||
mld_sendpack -> ...
|
||||
br_multicast_rcv ->
|
||||
br_multicast_add_group
|
||||
|
||||
The new mp's timer will be set up. If the timer expires after the bridge
|
||||
is freed, it may cause use-after-free panic in br_multicast_group_expired.
|
||||
|
||||
BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
|
||||
IP: [<ffffffffa07ed2c8>] br_multicast_group_expired+0x28/0xb0 [bridge]
|
||||
Call Trace:
|
||||
<IRQ>
|
||||
[<ffffffff81094536>] call_timer_fn+0x36/0x110
|
||||
[<ffffffffa07ed2a0>] ? br_mdb_free+0x30/0x30 [bridge]
|
||||
[<ffffffff81096967>] run_timer_softirq+0x237/0x340
|
||||
[<ffffffff8108dcbf>] __do_softirq+0xef/0x280
|
||||
[<ffffffff8169889c>] call_softirq+0x1c/0x30
|
||||
[<ffffffff8102c275>] do_softirq+0x65/0xa0
|
||||
[<ffffffff8108e055>] irq_exit+0x115/0x120
|
||||
[<ffffffff81699515>] smp_apic_timer_interrupt+0x45/0x60
|
||||
[<ffffffff81697a5d>] apic_timer_interrupt+0x6d/0x80
|
||||
|
||||
Nikolay also found it would cause a memory leak - the mdb hash is
|
||||
reallocated and not freed due to the mdb rehash.
|
||||
|
||||
unreferenced object 0xffff8800540ba800 (size 2048):
|
||||
backtrace:
|
||||
[<ffffffff816e2287>] kmemleak_alloc+0x67/0xc0
|
||||
[<ffffffff81260bea>] __kmalloc+0x1ba/0x3e0
|
||||
[<ffffffffa05c60ee>] br_mdb_rehash+0x5e/0x340 [bridge]
|
||||
[<ffffffffa05c74af>] br_multicast_new_group+0x43f/0x6e0 [bridge]
|
||||
[<ffffffffa05c7aa3>] br_multicast_add_group+0x203/0x260 [bridge]
|
||||
[<ffffffffa05ca4b5>] br_multicast_rcv+0x945/0x11d0 [bridge]
|
||||
[<ffffffffa05b6b10>] br_dev_xmit+0x180/0x470 [bridge]
|
||||
[<ffffffff815c781b>] dev_hard_start_xmit+0xbb/0x3d0
|
||||
[<ffffffff815c8743>] __dev_queue_xmit+0xb13/0xc10
|
||||
[<ffffffff815c8850>] dev_queue_xmit+0x10/0x20
|
||||
[<ffffffffa02f8d7a>] ip6_finish_output2+0x5ca/0xac0 [ipv6]
|
||||
[<ffffffffa02fbfc6>] ip6_finish_output+0x126/0x2c0 [ipv6]
|
||||
[<ffffffffa02fc245>] ip6_output+0xe5/0x390 [ipv6]
|
||||
[<ffffffffa032b92c>] NF_HOOK.constprop.44+0x6c/0x240 [ipv6]
|
||||
[<ffffffffa032bd16>] mld_sendpack+0x216/0x3e0 [ipv6]
|
||||
[<ffffffffa032d5eb>] mld_ifc_timer_expire+0x18b/0x2b0 [ipv6]
|
||||
|
||||
This could happen when ip link remove a bridge or destroy a netns with a
|
||||
bridge device inside.
|
||||
|
||||
With Nikolay's suggestion, this patch is to clean up bridge multicast in
|
||||
ndo_uninit after bridge dev is shutdown, instead of br_dev_delete, so
|
||||
that netif_running check in br_multicast_add_group can avoid this issue.
|
||||
|
||||
v1->v2:
|
||||
- fix this issue by moving br_multicast_dev_del to ndo_uninit, instead
|
||||
of calling dev_close in br_dev_delete.
|
||||
|
||||
(NOTE: Depends upon b6fe0440c637 ("bridge: implement missing ndo_uninit()"))
|
||||
|
||||
(NOTE: Manually fixed cherry-pick conflict as the code in the vicinity had
|
||||
changed. The logic of this fix should be preserved)
|
||||
|
||||
Fixes: e10177abf842 ("bridge: multicast: fix handling of temp and perm entries")
|
||||
Reported-by: Jianwen Ji <jiji@redhat.com>
|
||||
Signed-off-by: Xin Long <lucien.xin@gmail.com>
|
||||
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
|
||||
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Rolf Neugebauer <rn@rneugeba.io>
|
||||
(cherry picked from commit b1b9d366028ff580e6dd80b48a69c473361456f1)
|
||||
---
|
||||
net/bridge/br_device.c | 1 +
|
||||
net/bridge/br_if.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
|
||||
index 15be72678bc8..a0a7bb6a991f 100644
|
||||
--- a/net/bridge/br_device.c
|
||||
+++ b/net/bridge/br_device.c
|
||||
@@ -126,6 +126,7 @@ static void br_dev_uninit(struct net_device *dev)
|
||||
{
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
|
||||
+ br_multicast_dev_del(br);
|
||||
br_multicast_uninit_stats(br);
|
||||
br_vlan_flush(br);
|
||||
free_percpu(br->stats);
|
||||
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
|
||||
index 191b1f23c160..93d08d1b039e 100644
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -311,7 +311,6 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
|
||||
|
||||
br_fdb_delete_by_port(br, NULL, 0, 1);
|
||||
|
||||
- br_multicast_dev_del(br);
|
||||
del_timer_sync(&br->gc_timer);
|
||||
|
||||
br_sysfs_delbr(br->dev);
|
||||
--
|
||||
2.24.0
|
||||
|
@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SUMMARY: Sanity check on the kernel config file
|
||||
# LABELS:
|
||||
# REPEAT:
|
||||
|
||||
set -e
|
||||
|
||||
# Source libraries. Uncomment if needed/defined
|
||||
#. "${RT_LIB}"
|
||||
. "${RT_PROJECT_ROOT}/_lib/lib.sh"
|
||||
|
||||
NAME=kconfig
|
||||
|
||||
clean_up() {
|
||||
rm -rf ${NAME}-*
|
||||
}
|
||||
trap clean_up EXIT
|
||||
|
||||
# Test code goes here
|
||||
linuxkit build -format kernel+initrd -name "${NAME}" test.yml
|
||||
RESULT="$(linuxkit run ${NAME})"
|
||||
echo "${RESULT}" | grep -q "suite PASSED"
|
||||
|
||||
exit 0
|
@ -1,15 +0,0 @@
|
||||
kernel:
|
||||
image: linuxkit/kernel:4.9.206
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:a4fcf333298f644dfac6adf680b83140927aa85e
|
||||
- linuxkit/runc:69b4a35eaa22eba4990ee52cccc8f48f6c08ed03
|
||||
onboot:
|
||||
- name: check-kernel-config
|
||||
image: linuxkit/test-kernel-config:94fdeb494e09200fc05b6da39822aabfaca234e4
|
||||
- name: poweroff
|
||||
image: linuxkit/poweroff:b498d30dd9660090565537fceb9e757618737a85
|
||||
command: ["/bin/sh", "/poweroff.sh", "3"]
|
||||
trust:
|
||||
org:
|
||||
- linuxkit
|
@ -1,23 +0,0 @@
|
||||
# This Dockerfile extracts the kernel headers from the kernel image
|
||||
# and then compiles a simple hello world kernel module against them.
|
||||
# In the last stage, it creates a package, which can be used for
|
||||
# testing.
|
||||
|
||||
FROM linuxkit/kernel:4.9.206 AS ksrc
|
||||
|
||||
# Extract headers and compile module
|
||||
FROM linuxkit/alpine:3fdc49366257e53276c6f363956a4353f95d9a81 AS build
|
||||
RUN apk add build-base elfutils-dev
|
||||
|
||||
COPY --from=ksrc /kernel-dev.tar /
|
||||
RUN tar xf kernel-dev.tar
|
||||
|
||||
WORKDIR /kmod
|
||||
COPY ./src/* ./
|
||||
RUN make all
|
||||
|
||||
# Package
|
||||
FROM alpine:3.9
|
||||
COPY --from=build /kmod/hello_world.ko /
|
||||
COPY check.sh /check.sh
|
||||
ENTRYPOINT ["/bin/sh", "/check.sh"]
|
@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
function failed {
|
||||
printf "Kernel module test suite FAILED\n"
|
||||
/sbin/poweroff -f
|
||||
}
|
||||
|
||||
uname -a
|
||||
modinfo hello_world.ko || failed
|
||||
insmod hello_world.ko || failed
|
||||
[ -n "$(dmesg | grep -o 'Hello LinuxKit')" ] || failed
|
||||
rmmod hello_world || failed
|
||||
|
||||
printf "Kernel module test suite PASSED\n"
|
||||
|
||||
/sbin/poweroff -f
|
@ -1,6 +0,0 @@
|
||||
obj-m += hello_world.o
|
||||
KVER=$(shell basename /usr/src/linux-headers-*)
|
||||
all:
|
||||
make -C /usr/src/$(KVER) M=$(PWD) modules
|
||||
clean:
|
||||
make -C /usr/src/$(KVER) M=$(PWD) clean
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* A simple Hello World kernel module
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
int init_hello(void)
|
||||
{
|
||||
printk(KERN_INFO "Hello LinuxKit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exit_hello(void)
|
||||
{
|
||||
printk(KERN_INFO "Goodbye LinuxKit.\n");
|
||||
}
|
||||
|
||||
module_init(init_hello);
|
||||
module_exit(exit_hello);
|
||||
MODULE_AUTHOR("Rolf Neugebauer <rolf.neugebauer@docker.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("A simple Hello World kernel module for testing");
|
@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SUMMARY: Test build and insertion of kernel modules
|
||||
# LABELS:
|
||||
# REPEAT:
|
||||
|
||||
set -e
|
||||
|
||||
# Source libraries. Uncomment if needed/defined
|
||||
#. "${RT_LIB}"
|
||||
. "${RT_PROJECT_ROOT}/_lib/lib.sh"
|
||||
|
||||
NAME=kmod
|
||||
IMAGE_NAME=kmod-test
|
||||
|
||||
clean_up() {
|
||||
docker rmi ${IMAGE_NAME} || true
|
||||
rm -rf ${NAME}-*
|
||||
}
|
||||
trap clean_up EXIT
|
||||
|
||||
# Make sure we have the latest kernel image
|
||||
docker pull linuxkit/kernel:4.9.206
|
||||
# Build a package
|
||||
docker build -t ${IMAGE_NAME} .
|
||||
|
||||
# Build and run a LinuxKit image with kernel module (and test script)
|
||||
linuxkit build -format kernel+initrd -name "${NAME}" test.yml
|
||||
RESULT="$(linuxkit run ${NAME})"
|
||||
echo "${RESULT}" | grep -q "Hello LinuxKit"
|
||||
|
||||
exit 0
|
@ -1,20 +0,0 @@
|
||||
kernel:
|
||||
image: linuxkit/kernel:4.9.206
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:a4fcf333298f644dfac6adf680b83140927aa85e
|
||||
- linuxkit/runc:69b4a35eaa22eba4990ee52cccc8f48f6c08ed03
|
||||
onboot:
|
||||
- name: check
|
||||
image: kmod-test
|
||||
binds:
|
||||
- /dev:/dev
|
||||
- /lib/modules:/lib/modules
|
||||
capabilities:
|
||||
- all
|
||||
- name: poweroff
|
||||
image: linuxkit/poweroff:b498d30dd9660090565537fceb9e757618737a85
|
||||
command: ["/bin/sh", "/poweroff.sh", "3"]
|
||||
trust:
|
||||
org:
|
||||
- linuxkit
|
Loading…
Reference in New Issue
Block a user