mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 17:26:28 +00:00
projects: add kernel-config project
This is just a direct import of the current kernel/ directory, with a slight splitting up of the dockerfiles to build a kernel-source and kernel image. Signed-off-by: Tycho Andersen <tycho@docker.com>
This commit is contained in:
parent
a4c95be30a
commit
1e0021d969
@ -21,6 +21,7 @@ If you want to create a project, please submit a pull request to create a new di
|
||||
- [Clear Containers](clear-containers/) Clear Containers image
|
||||
- [Logging](logging/) Experimental logging tools
|
||||
- [etcd cluster](etcd/) etcd cluster demo from DockerCon'17
|
||||
- [kernel-config](kernel-config/) an experiment on how to manage kernel config
|
||||
|
||||
## Current projects not yet documented
|
||||
- VMWare support (VMWare)
|
||||
|
59
projects/kernel-config/Dockerfile.build
Normal file
59
projects/kernel-config/Dockerfile.build
Normal file
@ -0,0 +1,59 @@
|
||||
ARG source=nosuchimage
|
||||
FROM ${source}
|
||||
|
||||
ARG KERNEL_VERSION
|
||||
ARG KERNEL_SERIES
|
||||
ARG DEBUG
|
||||
|
||||
COPY kernel_config-${KERNEL_SERIES} /linux/arch/x86/configs/x86_64_defconfig
|
||||
COPY kernel_config.debug /linux/debug_config
|
||||
|
||||
RUN if [ -n "${DEBUG}" ]; then \
|
||||
sed -i 's/CONFIG_PANIC_ON_OOPS=y/# CONFIG_PANIC_ON_OOPS is not set/' /linux/arch/x86/configs/x86_64_defconfig; \
|
||||
cat /linux/debug_config >> /linux/arch/x86/configs/x86_64_defconfig; \
|
||||
fi
|
||||
|
||||
RUN mkdir /out
|
||||
|
||||
# Kernel
|
||||
RUN make defconfig && \
|
||||
make oldconfig && \
|
||||
make -j "$(getconf _NPROCESSORS_ONLN)" KCFLAGS="-fno-pie" && \
|
||||
cp arch/x86_64/boot/bzImage /out/kernel && \
|
||||
cp System.map /out
|
||||
|
||||
# Modules
|
||||
RUN make INSTALL_MOD_PATH=/tmp/kernel-modules modules_install && \
|
||||
( DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdepth 1)) && \
|
||||
cd /tmp/kernel-modules/lib/modules/$DVER && \
|
||||
rm build source && \
|
||||
ln -s /usr/src/linux-headers-$DVER build ) && \
|
||||
( cd /tmp/kernel-modules && tar cf /out/kernel.tar lib )
|
||||
|
||||
# Headers (userspace API)
|
||||
RUN mkdir -p /tmp/kernel-headers/usr && \
|
||||
make INSTALL_HDR_PATH=/tmp/kernel-headers/usr headers_install && \
|
||||
( cd /tmp/kernel-headers && tar cf /out/kernel-headers.tar usr )
|
||||
|
||||
# Headers (kernel development)
|
||||
RUN DVER=$(basename $(find /tmp/kernel-modules/lib/modules/ -mindepth 1 -maxdepth 1)) && \
|
||||
dir=/tmp/usr/src/linux-headers-$DVER && \
|
||||
mkdir -p $dir && \
|
||||
cp /linux/.config $dir && \
|
||||
cp /linux/Module.symvers $dir && \
|
||||
find . -path './include/*' -prune -o \
|
||||
-path './arch/*/include' -prune -o \
|
||||
-path './scripts/*' -prune -o \
|
||||
-type f \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
|
||||
-name '*.lds' -o -name '*.pl' -o -name '*.sh' \) | \
|
||||
tar cf - -T - | (cd $dir; tar xf -) && \
|
||||
( cd /tmp && tar cf /out/kernel-dev.tar usr/src )
|
||||
|
||||
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info
|
||||
|
||||
|
||||
FROM linuxkit/toybox-media:eee3dd4d72cd784801e95b1781e6c4f9d8a5e5eb@sha256:7f940e687164ee2676e11c61705c79f7dd2d144ee87ad17a494848a7045f5f53
|
||||
ENTRYPOINT []
|
||||
CMD []
|
||||
WORKDIR /
|
||||
COPY --from=kernel-build /out/* /
|
18
projects/kernel-config/Dockerfile.source
Normal file
18
projects/kernel-config/Dockerfile.source
Normal file
@ -0,0 +1,18 @@
|
||||
FROM linuxkit/kernel-compile:1b396c221af673757703258159ddc8539843b02b@sha256:6b32d205bfc6407568324337b707d195d027328dbfec554428ea93e7b0a8299b AS kernel-build
|
||||
|
||||
ARG KERNEL_VERSION
|
||||
ARG KERNEL_SERIES
|
||||
|
||||
ENV KERNEL_SOURCE=https://www.kernel.org/pub/linux/kernel/v4.x/linux-${KERNEL_VERSION}.tar.xz
|
||||
|
||||
RUN curl -fsSL -o linux-${KERNEL_VERSION}.tar.xz ${KERNEL_SOURCE}
|
||||
|
||||
RUN cat linux-${KERNEL_VERSION}.tar.xz | tar --absolute-names -xJ && mv /linux-${KERNEL_VERSION} /linux
|
||||
|
||||
# Apply local patches
|
||||
COPY patches-${KERNEL_SERIES} /patches
|
||||
WORKDIR /linux
|
||||
RUN set -e && for patch in /patches/*.patch; do \
|
||||
echo "Applying $patch"; \
|
||||
patch -p1 < "$patch"; \
|
||||
done
|
78
projects/kernel-config/Makefile
Normal file
78
projects/kernel-config/Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
# This builds the supported LinuxKit kernels. Kernels are wrapped up
|
||||
# in a minimal toybox container, which contains the bzImage, a tar
|
||||
# ball with modules and the kernel source.
|
||||
#
|
||||
# Each kernel is pushed to hub twice, once as
|
||||
# linuxkit/kernel:<kernel>.<major>.<minor>-<hash> and once as
|
||||
# inuxkit/kernel:<kernel>.<major>.x. The <hash> is the git tree hash
|
||||
# of the current directory. The build will only rebuild the kernel
|
||||
# image if the git tree hash changed.
|
||||
|
||||
# Git tree hash of this directory. Override to force build
|
||||
HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}')
|
||||
# Name on Hub
|
||||
IMAGE:=kernel
|
||||
|
||||
.PHONY: check tag push sign
|
||||
# Targets:
|
||||
# build: builds all kernels
|
||||
# push: pushes all tagged kernel images to hub
|
||||
# sign: sign and push all kernel images to hub
|
||||
build:
|
||||
push:
|
||||
sign:
|
||||
|
||||
# A template for defining kernel build
|
||||
# Arguments:
|
||||
# $1: Full kernel version, e.g., 4.9.22
|
||||
# $2: Kernel "series", e.g., 4.9.x
|
||||
# $3: Build a debug kernel (used as suffix for image)
|
||||
# This defines targets like:
|
||||
# build_4.9.x, push_4.9.x and sign_4.9.x and adds them as dependencies
|
||||
# to the global targets
|
||||
# Set $3 to "_dbg", to build debug kernels. This defines targets like
|
||||
# build_4.9.x_dbg and adds "_dbg" to the hub image name.
|
||||
define kernel
|
||||
.PHONY: source_$(2)$(3)
|
||||
source_$(2)$(3):
|
||||
docker image inspect linuxkit/$(IMAGE)-source:$(1)-$(HASH) >/dev/null || \
|
||||
docker build -f Dockerfile.source \
|
||||
--build-arg KERNEL_VERSION=$(1) \
|
||||
--build-arg KERNEL_SERIES=$(2) \
|
||||
--no-cache -t linuxkit/$(IMAGE)-source:$(1)-$(HASH) .
|
||||
|
||||
build_$(2)$(3): Dockerfile.build Makefile $(wildcard patches-$(2)/*) kernel_config-$(2) kernel_config.debug source_$(2)$(3)
|
||||
docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
|
||||
docker build -f Dockerfile.build \
|
||||
--build-arg KERNEL_VERSION=$(1) \
|
||||
--build-arg KERNEL_SERIES=$(2) \
|
||||
--build-arg DEBUG=$(3) \
|
||||
--build-arg source=linuxkit/$(IMAGE)-source:$(1)$(3)-$(HASH) \
|
||||
--no-cache -t linuxkit/$(IMAGE):$(1)$(3)-$(HASH) .
|
||||
|
||||
push_$(2)$(3): build_$(2)$(3)
|
||||
docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
|
||||
(docker push linuxkit/$(IMAGE):$(1)$(3)-$(HASH) && \
|
||||
docker tag linuxkit/$(IMAGE):$(1)$(3)-$(HASH) linuxkit/$(IMAGE):$(2)$(3) && \
|
||||
docker push linuxkit/$(IMAGE):$(2)$(3))
|
||||
|
||||
sign_$(2)$(3): build_$(2)$(3)
|
||||
DOCKER_CONTENT_TRUST=1 docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
|
||||
(DOCKER_CONTENT_TRUST=1 docker push linuxkit/$(IMAGE):$(1)$(3)-$(HASH) && \
|
||||
docker tag linuxkit/$(IMAGE):$(1)$(3)-$(HASH) linuxkit/$(IMAGE):$(2)$(3) && \
|
||||
DOCKER_CONTENT_TRUST=1 docker push linuxkit/$(IMAGE):$(2)$(3))
|
||||
|
||||
build: build_$(2)$(3)
|
||||
push: push_$(2)$(3)
|
||||
sign: sign_$(2)$(3)
|
||||
endef
|
||||
|
||||
#
|
||||
# Build Targets
|
||||
# Debug targets only for latest stable and LTS stable
|
||||
#
|
||||
$(eval $(call kernel,4.10.14,4.10.x))
|
||||
$(eval $(call kernel,4.10.14,4.10.x,_dbg))
|
||||
$(eval $(call kernel,4.9.26,4.9.x))
|
||||
$(eval $(call kernel,4.9.26,4.9.x,_dbg))
|
||||
$(eval $(call kernel,4.4.66,4.4.x))
|
3742
projects/kernel-config/kernel_config-4.10.x
Normal file
3742
projects/kernel-config/kernel_config-4.10.x
Normal file
File diff suppressed because it is too large
Load Diff
3503
projects/kernel-config/kernel_config-4.4.x
Normal file
3503
projects/kernel-config/kernel_config-4.4.x
Normal file
File diff suppressed because it is too large
Load Diff
3697
projects/kernel-config/kernel_config-4.9.x
Normal file
3697
projects/kernel-config/kernel_config-4.9.x
Normal file
File diff suppressed because it is too large
Load Diff
26
projects/kernel-config/kernel_config.debug
Normal file
26
projects/kernel-config/kernel_config.debug
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
## LinuxKit DEBUG OPTIONS ##
|
||||
|
||||
CONFIG_LOCKDEP=y
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_DEBUG_TIMEKEEPING=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_DEBUG_MUTEXES=y
|
||||
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
|
||||
CONFIG_DEBUG_LOCK_ALLOC=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
CONFIG_LOCK_STAT=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
CONFIG_PROVE_RCU=y
|
||||
CONFIG_RCU_TRACE=y
|
||||
CONFIG_KGDB=y
|
||||
CONFIG_KGDB_SERIAL_CONSOLE=y
|
||||
CONFIG_KGDBOC=y
|
||||
CONFIG_DEBUG_RODATA_TEST=y
|
||||
CONFIG_DEBUG_WX=y
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,492 @@
|
||||
From 6d21f35a580779c88a2f251395097b082574f4cc 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 2/7] 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 a58cd102af1b..feca5d2e7b25 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -203,33 +203,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)];
|
||||
@@ -245,13 +246,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)
|
||||
@@ -259,14 +269,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -283,6 +305,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 e47d8c9db03a..0a315e6aa589 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",
|
||||
@@ -228,8 +238,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)
|
||||
@@ -243,10 +251,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 3abfc5983c97..2cc670442f6c 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
|
||||
@@ -610,8 +623,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 4e543dbb731a..d14f10b924a0 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
|
||||
*/
|
||||
@@ -297,7 +307,6 @@ void hv_vss_onchannelcallback(void *context)
|
||||
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
- struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
if (vss_transaction.state > HVUTIL_READY)
|
||||
return;
|
||||
@@ -310,9 +319,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 ca26335de49a..41e5ed87f833 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1459,9 +1459,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.11.0
|
||||
|
@ -0,0 +1,118 @@
|
||||
From fbdcc24ca6ecc490da8254110a85aa33325137b9 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 3/7] 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 0a315e6aa589..9aee6014339d 100644
|
||||
--- a/drivers/hv/hv_fcopy.c
|
||||
+++ b/drivers/hv/hv_fcopy.c
|
||||
@@ -251,10 +251,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 2cc670442f6c..de263712e247 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 d14f10b924a0..bcc03f0748d6 100644
|
||||
--- a/drivers/hv/hv_snapshot.c
|
||||
+++ b/drivers/hv/hv_snapshot.c
|
||||
@@ -304,7 +304,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;
|
||||
|
||||
@@ -319,10 +319,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.11.0
|
||||
|
@ -0,0 +1,56 @@
|
||||
From 64b212adc820690cb54855b79e30e23329aecc5a Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Sun, 26 Mar 2017 16:42:20 +0800
|
||||
Subject: [PATCH 4/7] vmbus: fix missed ring events on boot
|
||||
|
||||
During initialization, the channel initialization code schedules the
|
||||
tasklet to scan the VMBUS receive event page (i.e. simulates an
|
||||
interrupt). The problem was that it invokes the tasklet on a different
|
||||
CPU from where it normally runs and therefore if an event is present,
|
||||
it will clear the bit but not find the associated channel.
|
||||
|
||||
This can lead to missed events, typically stuck tasks, during bootup
|
||||
when sub channels are being initialized. Typically seen as stuck
|
||||
boot with 8 or more CPU's.
|
||||
|
||||
This patch is not necessary for upstream (4.11 and later) since
|
||||
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
|
||||
This changed vmbus code to get rid of common tasklet which
|
||||
caused the problem.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 638fea33aee8 ("Drivers: hv: vmbus: fix the race when querying & updating the percpu list")
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit 5cf3a72a111cecc7da759542c56560ce509159d7)
|
||||
---
|
||||
drivers/hv/channel_mgmt.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index feca5d2e7b25..3fda63bf60ab 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -389,8 +389,17 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel)
|
||||
tasklet = hv_context.event_dpc[channel->target_cpu];
|
||||
tasklet_enable(tasklet);
|
||||
|
||||
- /* In case there is any pending event */
|
||||
- tasklet_schedule(tasklet);
|
||||
+ /*
|
||||
+ * In case there is any pending event schedule a rescan
|
||||
+ * but must be on the correct CPU for the channel.
|
||||
+ */
|
||||
+ if (channel->target_cpu == get_cpu())
|
||||
+ tasklet_schedule(tasklet);
|
||||
+ else
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ (smp_call_func_t)tasklet_schedule,
|
||||
+ tasklet, false);
|
||||
+ put_cpu();
|
||||
}
|
||||
|
||||
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
--
|
||||
2.11.0
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 0c089ad42dfc3a845ce6a21a1f78dd1704cbbaed Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Wed, 29 Mar 2017 18:37:10 +0800
|
||||
Subject: [PATCH 5/7] vmbus: remove "goto error_clean_msglist" in vmbus_open()
|
||||
|
||||
This is just a cleanup patch to simplify the code a little.
|
||||
No semantic change.
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit 2c89f21cbdfd39299482cd6068094097a45f13b3)
|
||||
---
|
||||
drivers/hv/channel.c | 18 +++++++-----------
|
||||
1 file changed, 7 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 1606e7f08f4b..1caed01954f6 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -184,17 +184,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel), true);
|
||||
|
||||
- if (ret != 0) {
|
||||
- err = ret;
|
||||
- goto error_clean_msglist;
|
||||
- }
|
||||
-
|
||||
- wait_for_completion(&open_info->waitevent);
|
||||
+ if (ret == 0)
|
||||
+ wait_for_completion(&open_info->waitevent);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
+ if (ret != 0) {
|
||||
+ err = ret;
|
||||
+ goto error_free_gpadl;
|
||||
+ }
|
||||
+
|
||||
if (newchannel->rescind) {
|
||||
err = -ENODEV;
|
||||
goto error_free_gpadl;
|
||||
@@ -209,11 +210,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
kfree(open_info);
|
||||
return 0;
|
||||
|
||||
-error_clean_msglist:
|
||||
- spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
- list_del(&open_info->msglistentry);
|
||||
- spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
-
|
||||
error_free_gpadl:
|
||||
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||
kfree(open_info);
|
||||
--
|
||||
2.11.0
|
||||
|
@ -0,0 +1,177 @@
|
||||
From 67f5a959cea3dea2f5773cf7b690337dde421f9b Mon Sep 17 00:00:00 2001
|
||||
From: Dexuan Cui <decui@microsoft.com>
|
||||
Date: Fri, 24 Mar 2017 20:53:18 +0800
|
||||
Subject: [PATCH 6/7] vmbus: dynamically enqueue/dequeue the channel on
|
||||
vmbus_open/close
|
||||
|
||||
Signed-off-by: Dexuan Cui <decui@microsoft.com>
|
||||
Origin: git@github.com:dcui/linux.git
|
||||
(cherry picked from commit bee4910daa4aed57ce60d2e2350e3cc120c383ca)
|
||||
---
|
||||
drivers/hv/channel.c | 16 ++++++++++---
|
||||
drivers/hv/channel_mgmt.c | 58 ++++++++++++++++++++---------------------------
|
||||
include/linux/hyperv.h | 3 +++
|
||||
3 files changed, 40 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
|
||||
index 1caed01954f6..5bbcc964dbf7 100644
|
||||
--- a/drivers/hv/channel.c
|
||||
+++ b/drivers/hv/channel.c
|
||||
@@ -181,6 +181,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
&vmbus_connection.chn_msg_list);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
+ hv_event_tasklet_disable(newchannel);
|
||||
+ hv_percpu_channel_enq(newchannel);
|
||||
+ hv_event_tasklet_enable(newchannel);
|
||||
+
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel), true);
|
||||
|
||||
@@ -193,23 +197,27 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
|
||||
if (ret != 0) {
|
||||
err = ret;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
if (newchannel->rescind) {
|
||||
err = -ENODEV;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
if (open_info->response.open_result.status) {
|
||||
err = -EAGAIN;
|
||||
- goto error_free_gpadl;
|
||||
+ goto error_deq_channel;
|
||||
}
|
||||
|
||||
newchannel->state = CHANNEL_OPENED_STATE;
|
||||
kfree(open_info);
|
||||
return 0;
|
||||
|
||||
+error_deq_channel:
|
||||
+ hv_event_tasklet_disable(newchannel);
|
||||
+ hv_percpu_channel_deq(newchannel);
|
||||
+ hv_event_tasklet_enable(newchannel);
|
||||
error_free_gpadl:
|
||||
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||
kfree(open_info);
|
||||
@@ -555,6 +563,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ hv_percpu_channel_deq(channel);
|
||||
+
|
||||
channel->state = CHANNEL_OPEN_STATE;
|
||||
channel->sc_creation_callback = NULL;
|
||||
/* Stop callback and cancel the timer asap */
|
||||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
|
||||
index 3fda63bf60ab..e2fbfa290f1c 100644
|
||||
--- a/drivers/hv/channel_mgmt.c
|
||||
+++ b/drivers/hv/channel_mgmt.c
|
||||
@@ -376,6 +376,30 @@ static void vmbus_release_relid(u32 relid)
|
||||
true);
|
||||
}
|
||||
|
||||
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
|
||||
+{
|
||||
+ if (channel->target_cpu != get_cpu())
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ percpu_channel_enq,
|
||||
+ channel, true);
|
||||
+ else
|
||||
+ percpu_channel_enq(channel);
|
||||
+ put_cpu();
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
|
||||
+{
|
||||
+ if (channel->target_cpu != get_cpu())
|
||||
+ smp_call_function_single(channel->target_cpu,
|
||||
+ percpu_channel_deq,
|
||||
+ channel, true);
|
||||
+ else
|
||||
+ percpu_channel_deq(channel);
|
||||
+ put_cpu();
|
||||
+
|
||||
+}
|
||||
+
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel)
|
||||
{
|
||||
struct tasklet_struct *tasklet;
|
||||
@@ -410,17 +434,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
|
||||
BUG_ON(!channel->rescind);
|
||||
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
|
||||
|
||||
- hv_event_tasklet_disable(channel);
|
||||
- if (channel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(channel->target_cpu,
|
||||
- percpu_channel_deq, channel, true);
|
||||
- } else {
|
||||
- percpu_channel_deq(channel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(channel);
|
||||
-
|
||||
if (channel->primary_channel == NULL) {
|
||||
list_del(&channel->listentry);
|
||||
|
||||
@@ -513,18 +526,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
|
||||
init_vp_index(newchannel, dev_type);
|
||||
|
||||
- hv_event_tasklet_disable(newchannel);
|
||||
- if (newchannel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(newchannel->target_cpu,
|
||||
- percpu_channel_enq,
|
||||
- newchannel, true);
|
||||
- } else {
|
||||
- percpu_channel_enq(newchannel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(newchannel);
|
||||
-
|
||||
/*
|
||||
* This state is used to indicate a successful open
|
||||
* so that when we do close the channel normally, we
|
||||
@@ -573,17 +574,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||
list_del(&newchannel->listentry);
|
||||
mutex_unlock(&vmbus_connection.channel_mutex);
|
||||
|
||||
- hv_event_tasklet_disable(newchannel);
|
||||
- if (newchannel->target_cpu != get_cpu()) {
|
||||
- put_cpu();
|
||||
- smp_call_function_single(newchannel->target_cpu,
|
||||
- percpu_channel_deq, newchannel, true);
|
||||
- } else {
|
||||
- percpu_channel_deq(newchannel);
|
||||
- put_cpu();
|
||||
- }
|
||||
- hv_event_tasklet_enable(newchannel);
|
||||
-
|
||||
vmbus_release_relid(newchannel->offermsg.child_relid);
|
||||
|
||||
err_free_chan:
|
||||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
|
||||
index 41e5ed87f833..0792d16f4b3e 100644
|
||||
--- a/include/linux/hyperv.h
|
||||
+++ b/include/linux/hyperv.h
|
||||
@@ -1467,6 +1467,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel);
|
||||
void hv_event_tasklet_enable(struct vmbus_channel *channel);
|
||||
|
||||
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
|
||||
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
|
||||
+
|
||||
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
|
||||
|
||||
void vmbus_setevent(struct vmbus_channel *channel);
|
||||
--
|
||||
2.11.0
|
||||
|
@ -0,0 +1,94 @@
|
||||
From 6064d8207f1a62352f2476d09b8d6c6fba572359 Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Hemminger <stephen@networkplumber.org>
|
||||
Date: Tue, 7 Mar 2017 09:15:53 -0800
|
||||
Subject: [PATCH 7/7] scsi: storvsc: Workaround for virtual DVD SCSI version
|
||||
|
||||
Hyper-V host emulation of SCSI for virtual DVD device reports SCSI
|
||||
version 0 (UNKNOWN) but is still capable of supporting REPORTLUN.
|
||||
|
||||
Without this patch, a GEN2 Linux guest on Hyper-V will not boot 4.11
|
||||
successfully with virtual DVD ROM device. What happens is that the SCSI
|
||||
scan process falls back to doing sequential probing by INQUIRY. But the
|
||||
storvsc driver has a previous workaround that masks/blocks all errors
|
||||
reports from INQUIRY (or MODE_SENSE) commands. This workaround causes
|
||||
the scan to then populate a full set of bogus LUN's on the target and
|
||||
then sends kernel spinning off into a death spiral doing block reads on
|
||||
the non-existent LUNs.
|
||||
|
||||
By setting the correct blacklist flags, the target with the DVD device
|
||||
is scanned with REPORTLUN and that works correctly.
|
||||
|
||||
Patch needs to go in current 4.11, it is safe but not necessary in older
|
||||
kernels.
|
||||
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
||||
(cherry picked from commit f1c635b439a5c01776fe3a25b1e2dc546ea82e6f)
|
||||
---
|
||||
drivers/scsi/storvsc_drv.c | 27 +++++++++++++++++----------
|
||||
1 file changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
|
||||
index 7be04fc0d0e7..6f5d173ea9ff 100644
|
||||
--- a/drivers/scsi/storvsc_drv.c
|
||||
+++ b/drivers/scsi/storvsc_drv.c
|
||||
@@ -400,8 +400,6 @@ MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels")
|
||||
*/
|
||||
static int storvsc_timeout = 180;
|
||||
|
||||
-static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
|
||||
-
|
||||
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
|
||||
static struct scsi_transport_template *fc_transport_template;
|
||||
#endif
|
||||
@@ -1283,6 +1281,22 @@ static int storvsc_do_io(struct hv_device *device,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int storvsc_device_alloc(struct scsi_device *sdevice)
|
||||
+{
|
||||
+ /*
|
||||
+ * Set blist flag to permit the reading of the VPD pages even when
|
||||
+ * the target may claim SPC-2 compliance. MSFT targets currently
|
||||
+ * claim SPC-2 compliance while they implement post SPC-2 features.
|
||||
+ * With this flag we can correctly handle WRITE_SAME_16 issues.
|
||||
+ *
|
||||
+ * Hypervisor reports SCSI_UNKNOWN type for DVD ROM device but
|
||||
+ * still supports REPORT LUN.
|
||||
+ */
|
||||
+ sdevice->sdev_bflags = BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int storvsc_device_configure(struct scsi_device *sdevice)
|
||||
{
|
||||
|
||||
@@ -1298,14 +1312,6 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
|
||||
sdevice->no_write_same = 1;
|
||||
|
||||
/*
|
||||
- * Add blist flags to permit the reading of the VPD pages even when
|
||||
- * the target may claim SPC-2 compliance. MSFT targets currently
|
||||
- * claim SPC-2 compliance while they implement post SPC-2 features.
|
||||
- * With this patch we can correctly handle WRITE_SAME_16 issues.
|
||||
- */
|
||||
- sdevice->sdev_bflags |= msft_blist_flags;
|
||||
-
|
||||
- /*
|
||||
* If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
|
||||
* if the device is a MSFT virtual device. If the host is
|
||||
* WIN10 or newer, allow write_same.
|
||||
@@ -1569,6 +1575,7 @@ static struct scsi_host_template scsi_driver = {
|
||||
.eh_host_reset_handler = storvsc_host_reset_handler,
|
||||
.proc_name = "storvsc_host",
|
||||
.eh_timed_out = storvsc_eh_timed_out,
|
||||
+ .slave_alloc = storvsc_device_alloc,
|
||||
.slave_configure = storvsc_device_configure,
|
||||
.cmd_per_lun = 255,
|
||||
.this_id = -1,
|
||||
--
|
||||
2.11.0
|
||||
|
Loading…
Reference in New Issue
Block a user